2020#include <linux/security.h>
2121
2222#include "do_mounts.h"
23+ #include "initramfs_internal.h"
2324
2425static __initdata bool csum_present ;
2526static __initdata u32 io_csum ;
@@ -75,6 +76,7 @@ static __initdata struct hash {
7576 struct hash * next ;
7677 char name [N_ALIGN (PATH_MAX )];
7778} * head [32 ];
79+ static __initdata bool hardlink_seen ;
7880
7981static inline int hash (int major , int minor , int ino )
8082{
@@ -108,19 +110,21 @@ static char __init *find_link(int major, int minor, int ino,
108110 strcpy (q -> name , name );
109111 q -> next = NULL ;
110112 * p = q ;
113+ hardlink_seen = true;
111114 return NULL ;
112115}
113116
114117static void __init free_hash (void )
115118{
116119 struct hash * * p , * q ;
117- for (p = head ; p < head + 32 ; p ++ ) {
120+ for (p = head ; hardlink_seen && p < head + 32 ; p ++ ) {
118121 while (* p ) {
119122 q = * p ;
120123 * p = q -> next ;
121124 kfree (q );
122125 }
123126 }
127+ hardlink_seen = false;
124128}
125129
126130#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
@@ -143,9 +147,8 @@ struct dir_entry {
143147 char name [];
144148};
145149
146- static void __init dir_add (const char * name , time64_t mtime )
150+ static void __init dir_add (const char * name , size_t nlen , time64_t mtime )
147151{
148- size_t nlen = strlen (name ) + 1 ;
149152 struct dir_entry * de ;
150153
151154 de = kmalloc (sizeof (struct dir_entry ) + nlen , GFP_KERNEL );
@@ -169,7 +172,7 @@ static void __init dir_utime(void)
169172#else
170173static void __init do_utime (char * filename , time64_t mtime ) {}
171174static void __init do_utime_path (const struct path * path , time64_t mtime ) {}
172- static void __init dir_add (const char * name , time64_t mtime ) {}
175+ static void __init dir_add (const char * name , size_t nlen , time64_t mtime ) {}
173176static void __init dir_utime (void ) {}
174177#endif
175178
@@ -188,14 +191,11 @@ static __initdata u32 hdr_csum;
188191static void __init parse_header (char * s )
189192{
190193 unsigned long parsed [13 ];
191- char buf [9 ];
192194 int i ;
193195
194- buf [8 ] = '\0' ;
195- for (i = 0 , s += 6 ; i < 13 ; i ++ , s += 8 ) {
196- memcpy (buf , s , 8 );
197- parsed [i ] = simple_strtoul (buf , NULL , 16 );
198- }
196+ for (i = 0 , s += 6 ; i < 13 ; i ++ , s += 8 )
197+ parsed [i ] = simple_strntoul (s , NULL , 16 , 8 );
198+
199199 ino = parsed [0 ];
200200 mode = parsed [1 ];
201201 uid = parsed [2 ];
@@ -256,7 +256,7 @@ static __initdata char *header_buf, *symlink_buf, *name_buf;
256256
257257static int __init do_start (void )
258258{
259- read_into (header_buf , 110 , GotHeader );
259+ read_into (header_buf , CPIO_HDRLEN , GotHeader );
260260 return 0 ;
261261}
262262
@@ -396,7 +396,7 @@ static int __init do_name(void)
396396 init_mkdir (collected , mode );
397397 init_chown (collected , uid , gid , 0 );
398398 init_chmod (collected , mode );
399- dir_add (collected , mtime );
399+ dir_add (collected , name_len , mtime );
400400 } else if (S_ISBLK (mode ) || S_ISCHR (mode ) ||
401401 S_ISFIFO (mode ) || S_ISSOCK (mode )) {
402402 if (maybe_link () == 0 ) {
@@ -497,20 +497,33 @@ static unsigned long my_inptr __initdata; /* index of next byte to be processed
497497
498498#include <linux/decompress/generic.h>
499499
500- static char * __init unpack_to_rootfs (char * buf , unsigned long len )
500+ /**
501+ * unpack_to_rootfs - decompress and extract an initramfs archive
502+ * @buf: input initramfs archive to extract
503+ * @len: length of initramfs data to process
504+ *
505+ * Returns: NULL for success or an error message string
506+ *
507+ * This symbol shouldn't be used externally. It's available for unit tests.
508+ */
509+ char * __init unpack_to_rootfs (char * buf , unsigned long len )
501510{
502511 long written ;
503512 decompress_fn decompress ;
504513 const char * compress_name ;
505- static __initdata char msg_buf [64 ];
514+ struct {
515+ char header [CPIO_HDRLEN ];
516+ char symlink [PATH_MAX + N_ALIGN (PATH_MAX ) + 1 ];
517+ char name [N_ALIGN (PATH_MAX )];
518+ } * bufs = kmalloc (sizeof (* bufs ), GFP_KERNEL );
506519
507- header_buf = kmalloc (110 , GFP_KERNEL );
508- symlink_buf = kmalloc (PATH_MAX + N_ALIGN (PATH_MAX ) + 1 , GFP_KERNEL );
509- name_buf = kmalloc (N_ALIGN (PATH_MAX ), GFP_KERNEL );
510-
511- if (!header_buf || !symlink_buf || !name_buf )
520+ if (!bufs )
512521 panic_show_mem ("can't allocate buffers" );
513522
523+ header_buf = bufs -> header ;
524+ symlink_buf = bufs -> symlink ;
525+ name_buf = bufs -> name ;
526+
514527 state = Start ;
515528 this_header = 0 ;
516529 message = NULL ;
@@ -538,12 +551,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len)
538551 if (res )
539552 error ("decompressor failed" );
540553 } else if (compress_name ) {
541- if (!message ) {
542- snprintf (msg_buf , sizeof msg_buf ,
543- "compression method %s not configured" ,
544- compress_name );
545- message = msg_buf ;
546- }
554+ pr_err ("compression method %s not configured\n" ,
555+ compress_name );
556+ error ("decompressor failed" );
547557 } else
548558 error ("invalid magic at start of compressed archive" );
549559 if (state != Reset )
@@ -553,9 +563,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len)
553563 len -= my_inptr ;
554564 }
555565 dir_utime ();
556- kfree ( name_buf );
557- kfree ( symlink_buf );
558- kfree (header_buf );
566+ /* free any hardlink state collected without optional TRAILER!!! */
567+ free_hash ( );
568+ kfree (bufs );
559569 return message ;
560570}
561571
0 commit comments