20
20
#include <linux/security.h>
21
21
22
22
#include "do_mounts.h"
23
+ #include "initramfs_internal.h"
23
24
24
25
static __initdata bool csum_present ;
25
26
static __initdata u32 io_csum ;
@@ -75,6 +76,7 @@ static __initdata struct hash {
75
76
struct hash * next ;
76
77
char name [N_ALIGN (PATH_MAX )];
77
78
} * head [32 ];
79
+ static __initdata bool hardlink_seen ;
78
80
79
81
static inline int hash (int major , int minor , int ino )
80
82
{
@@ -108,19 +110,21 @@ static char __init *find_link(int major, int minor, int ino,
108
110
strcpy (q -> name , name );
109
111
q -> next = NULL ;
110
112
* p = q ;
113
+ hardlink_seen = true;
111
114
return NULL ;
112
115
}
113
116
114
117
static void __init free_hash (void )
115
118
{
116
119
struct hash * * p , * q ;
117
- for (p = head ; p < head + 32 ; p ++ ) {
120
+ for (p = head ; hardlink_seen && p < head + 32 ; p ++ ) {
118
121
while (* p ) {
119
122
q = * p ;
120
123
* p = q -> next ;
121
124
kfree (q );
122
125
}
123
126
}
127
+ hardlink_seen = false;
124
128
}
125
129
126
130
#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
@@ -143,9 +147,8 @@ struct dir_entry {
143
147
char name [];
144
148
};
145
149
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 )
147
151
{
148
- size_t nlen = strlen (name ) + 1 ;
149
152
struct dir_entry * de ;
150
153
151
154
de = kmalloc (sizeof (struct dir_entry ) + nlen , GFP_KERNEL );
@@ -169,7 +172,7 @@ static void __init dir_utime(void)
169
172
#else
170
173
static void __init do_utime (char * filename , time64_t mtime ) {}
171
174
static 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 ) {}
173
176
static void __init dir_utime (void ) {}
174
177
#endif
175
178
@@ -188,14 +191,11 @@ static __initdata u32 hdr_csum;
188
191
static void __init parse_header (char * s )
189
192
{
190
193
unsigned long parsed [13 ];
191
- char buf [9 ];
192
194
int i ;
193
195
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
+
199
199
ino = parsed [0 ];
200
200
mode = parsed [1 ];
201
201
uid = parsed [2 ];
@@ -256,7 +256,7 @@ static __initdata char *header_buf, *symlink_buf, *name_buf;
256
256
257
257
static int __init do_start (void )
258
258
{
259
- read_into (header_buf , 110 , GotHeader );
259
+ read_into (header_buf , CPIO_HDRLEN , GotHeader );
260
260
return 0 ;
261
261
}
262
262
@@ -396,7 +396,7 @@ static int __init do_name(void)
396
396
init_mkdir (collected , mode );
397
397
init_chown (collected , uid , gid , 0 );
398
398
init_chmod (collected , mode );
399
- dir_add (collected , mtime );
399
+ dir_add (collected , name_len , mtime );
400
400
} else if (S_ISBLK (mode ) || S_ISCHR (mode ) ||
401
401
S_ISFIFO (mode ) || S_ISSOCK (mode )) {
402
402
if (maybe_link () == 0 ) {
@@ -497,20 +497,33 @@ static unsigned long my_inptr __initdata; /* index of next byte to be processed
497
497
498
498
#include <linux/decompress/generic.h>
499
499
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 )
501
510
{
502
511
long written ;
503
512
decompress_fn decompress ;
504
513
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 );
506
519
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 )
512
521
panic_show_mem ("can't allocate buffers" );
513
522
523
+ header_buf = bufs -> header ;
524
+ symlink_buf = bufs -> symlink ;
525
+ name_buf = bufs -> name ;
526
+
514
527
state = Start ;
515
528
this_header = 0 ;
516
529
message = NULL ;
@@ -538,12 +551,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len)
538
551
if (res )
539
552
error ("decompressor failed" );
540
553
} 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" );
547
557
} else
548
558
error ("invalid magic at start of compressed archive" );
549
559
if (state != Reset )
@@ -553,9 +563,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len)
553
563
len -= my_inptr ;
554
564
}
555
565
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 );
559
569
return message ;
560
570
}
561
571
0 commit comments