1 /* 2 * Many of the syscalls used in this file expect some of the arguments 3 * to be __user pointers not __kernel pointers. To limit the sparse 4 * noise, turn off sparse checking for this file. 5 */ 6 #ifdef __CHECKER__ 7 #undef __CHECKER__ 8 #warning "Sparse checking disabled for this file" 9 #endif 10 11 #include <linux/init.h> 12 #include <linux/fs.h> 13 #include <linux/slab.h> 14 #include <linux/types.h> 15 #include <linux/fcntl.h> 16 #include <linux/delay.h> 17 #include <linux/string.h> 18 #include <linux/dirent.h> 19 #include <linux/syscalls.h> 20 #include <linux/utime.h> 21 22 static __initdata char *message; 23 static void __init error(char *x) 24 { 25 if (!message) 26 message = x; 27 } 28 29 /* link hash */ 30 31 #define N_ALIGN(len) ((((len) + 1) & ~3) + 2) 32 33 static __initdata struct hash { 34 int ino, minor, major; 35 umode_t mode; 36 struct hash *next; 37 char name[N_ALIGN(PATH_MAX)]; 38 } *head[32]; 39 40 static inline int hash(int major, int minor, int ino) 41 { 42 unsigned long tmp = ino + minor + (major << 3); 43 tmp += tmp >> 5; 44 return tmp & 31; 45 } 46 47 static char __init *find_link(int major, int minor, int ino, 48 umode_t mode, char *name) 49 { 50 struct hash **p, *q; 51 for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) { 52 if ((*p)->ino != ino) 53 continue; 54 if ((*p)->minor != minor) 55 continue; 56 if ((*p)->major != major) 57 continue; 58 if (((*p)->mode ^ mode) & S_IFMT) 59 continue; 60 return (*p)->name; 61 } 62 q = kmalloc(sizeof(struct hash), GFP_KERNEL); 63 if (!q) 64 panic("can't allocate link hash entry"); 65 q->major = major; 66 q->minor = minor; 67 q->ino = ino; 68 q->mode = mode; 69 strcpy(q->name, name); 70 q->next = NULL; 71 *p = q; 72 return NULL; 73 } 74 75 static void __init free_hash(void) 76 { 77 struct hash **p, *q; 78 for (p = head; p < head + 32; p++) { 79 while (*p) { 80 q = *p; 81 *p = q->next; 82 kfree(q); 83 } 84 } 85 } 86 87 static long __init do_utime(char *filename, time_t mtime) 88 { 89 struct timespec t[2]; 90 91 t[0].tv_sec = mtime; 92 t[0].tv_nsec = 0; 93 t[1].tv_sec = mtime; 94 t[1].tv_nsec = 0; 95 96 return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW); 97 } 98 99 static __initdata LIST_HEAD(dir_list); 100 struct dir_entry { 101 struct list_head list; 102 char *name; 103 time_t mtime; 104 }; 105 106 static void __init dir_add(const char *name, time_t mtime) 107 { 108 struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL); 109 if (!de) 110 panic("can't allocate dir_entry buffer"); 111 INIT_LIST_HEAD(&de->list); 112 de->name = kstrdup(name, GFP_KERNEL); 113 de->mtime = mtime; 114 list_add(&de->list, &dir_list); 115 } 116 117 static void __init dir_utime(void) 118 { 119 struct dir_entry *de, *tmp; 120 list_for_each_entry_safe(de, tmp, &dir_list, list) { 121 list_del(&de->list); 122 do_utime(de->name, de->mtime); 123 kfree(de->name); 124 kfree(de); 125 } 126 } 127 128 static __initdata time_t mtime; 129 130 /* cpio header parsing */ 131 132 static __initdata unsigned long ino, major, minor, nlink; 133 static __initdata umode_t mode; 134 static __initdata unsigned long body_len, name_len; 135 static __initdata uid_t uid; 136 static __initdata gid_t gid; 137 static __initdata unsigned rdev; 138 139 static void __init parse_header(char *s) 140 { 141 unsigned long parsed[12]; 142 char buf[9]; 143 int i; 144 145 buf[8] = '\0'; 146 for (i = 0, s += 6; i < 12; i++, s += 8) { 147 memcpy(buf, s, 8); 148 parsed[i] = simple_strtoul(buf, NULL, 16); 149 } 150 ino = parsed[0]; 151 mode = parsed[1]; 152 uid = parsed[2]; 153 gid = parsed[3]; 154 nlink = parsed[4]; 155 mtime = parsed[5]; 156 body_len = parsed[6]; 157 major = parsed[7]; 158 minor = parsed[8]; 159 rdev = new_encode_dev(MKDEV(parsed[9], parsed[10])); 160 name_len = parsed[11]; 161 } 162 163 /* FSM */ 164 165 static __initdata enum state { 166 Start, 167 Collect, 168 GotHeader, 169 SkipIt, 170 GotName, 171 CopyFile, 172 GotSymlink, 173 Reset 174 } state, next_state; 175 176 static __initdata char *victim; 177 static __initdata unsigned count; 178 static __initdata loff_t this_header, next_header; 179 180 static inline void __init eat(unsigned n) 181 { 182 victim += n; 183 this_header += n; 184 count -= n; 185 } 186 187 static __initdata char *vcollected; 188 static __initdata char *collected; 189 static __initdata int remains; 190 static __initdata char *collect; 191 192 static void __init read_into(char *buf, unsigned size, enum state next) 193 { 194 if (count >= size) { 195 collected = victim; 196 eat(size); 197 state = next; 198 } else { 199 collect = collected = buf; 200 remains = size; 201 next_state = next; 202 state = Collect; 203 } 204 } 205 206 static __initdata char *header_buf, *symlink_buf, *name_buf; 207 208 static int __init do_start(void) 209 { 210 read_into(header_buf, 110, GotHeader); 211 return 0; 212 } 213 214 static int __init do_collect(void) 215 { 216 unsigned n = remains; 217 if (count < n) 218 n = count; 219 memcpy(collect, victim, n); 220 eat(n); 221 collect += n; 222 if ((remains -= n) != 0) 223 return 1; 224 state = next_state; 225 return 0; 226 } 227 228 static int __init do_header(void) 229 { 230 if (memcmp(collected, "070707", 6)==0) { 231 error("incorrect cpio method used: use -H newc option"); 232 return 1; 233 } 234 if (memcmp(collected, "070701", 6)) { 235 error("no cpio magic"); 236 return 1; 237 } 238 parse_header(collected); 239 next_header = this_header + N_ALIGN(name_len) + body_len; 240 next_header = (next_header + 3) & ~3; 241 state = SkipIt; 242 if (name_len <= 0 || name_len > PATH_MAX) 243 return 0; 244 if (S_ISLNK(mode)) { 245 if (body_len > PATH_MAX) 246 return 0; 247 collect = collected = symlink_buf; 248 remains = N_ALIGN(name_len) + body_len; 249 next_state = GotSymlink; 250 state = Collect; 251 return 0; 252 } 253 if (S_ISREG(mode) || !body_len) 254 read_into(name_buf, N_ALIGN(name_len), GotName); 255 return 0; 256 } 257 258 static int __init do_skip(void) 259 { 260 if (this_header + count < next_header) { 261 eat(count); 262 return 1; 263 } else { 264 eat(next_header - this_header); 265 state = next_state; 266 return 0; 267 } 268 } 269 270 static int __init do_reset(void) 271 { 272 while(count && *victim == '\0') 273 eat(1); 274 if (count && (this_header & 3)) 275 error("broken padding"); 276 return 1; 277 } 278 279 static int __init maybe_link(void) 280 { 281 if (nlink >= 2) { 282 char *old = find_link(major, minor, ino, mode, collected); 283 if (old) 284 return (sys_link(old, collected) < 0) ? -1 : 1; 285 } 286 return 0; 287 } 288 289 static void __init clean_path(char *path, umode_t mode) 290 { 291 struct stat st; 292 293 if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) { 294 if (S_ISDIR(st.st_mode)) 295 sys_rmdir(path); 296 else 297 sys_unlink(path); 298 } 299 } 300 301 static __initdata int wfd; 302 303 static int __init do_name(void) 304 { 305 state = SkipIt; 306 next_state = Reset; 307 if (strcmp(collected, "TRAILER!!!") == 0) { 308 free_hash(); 309 return 0; 310 } 311 clean_path(collected, mode); 312 if (S_ISREG(mode)) { 313 int ml = maybe_link(); 314 if (ml >= 0) { 315 int openflags = O_WRONLY|O_CREAT; 316 if (ml != 1) 317 openflags |= O_TRUNC; 318 wfd = sys_open(collected, openflags, mode); 319 320 if (wfd >= 0) { 321 sys_fchown(wfd, uid, gid); 322 sys_fchmod(wfd, mode); 323 if (body_len) 324 sys_ftruncate(wfd, body_len); 325 vcollected = kstrdup(collected, GFP_KERNEL); 326 state = CopyFile; 327 } 328 } 329 } else if (S_ISDIR(mode)) { 330 sys_mkdir(collected, mode); 331 sys_chown(collected, uid, gid); 332 sys_chmod(collected, mode); 333 dir_add(collected, mtime); 334 } else if (S_ISBLK(mode) || S_ISCHR(mode) || 335 S_ISFIFO(mode) || S_ISSOCK(mode)) { 336 if (maybe_link() == 0) { 337 sys_mknod(collected, mode, rdev); 338 sys_chown(collected, uid, gid); 339 sys_chmod(collected, mode); 340 do_utime(collected, mtime); 341 } 342 } 343 return 0; 344 } 345 346 static int __init do_copy(void) 347 { 348 if (count >= body_len) { 349 sys_write(wfd, victim, body_len); 350 sys_close(wfd); 351 do_utime(vcollected, mtime); 352 kfree(vcollected); 353 eat(body_len); 354 state = SkipIt; 355 return 0; 356 } else { 357 sys_write(wfd, victim, count); 358 body_len -= count; 359 eat(count); 360 return 1; 361 } 362 } 363 364 static int __init do_symlink(void) 365 { 366 collected[N_ALIGN(name_len) + body_len] = '\0'; 367 clean_path(collected, 0); 368 sys_symlink(collected + N_ALIGN(name_len), collected); 369 sys_lchown(collected, uid, gid); 370 do_utime(collected, mtime); 371 state = SkipIt; 372 next_state = Reset; 373 return 0; 374 } 375 376 static __initdata int (*actions[])(void) = { 377 [Start] = do_start, 378 [Collect] = do_collect, 379 [GotHeader] = do_header, 380 [SkipIt] = do_skip, 381 [GotName] = do_name, 382 [CopyFile] = do_copy, 383 [GotSymlink] = do_symlink, 384 [Reset] = do_reset, 385 }; 386 387 static int __init write_buffer(char *buf, unsigned len) 388 { 389 count = len; 390 victim = buf; 391 392 while (!actions[state]()) 393 ; 394 return len - count; 395 } 396 397 static int __init flush_buffer(void *bufv, unsigned len) 398 { 399 char *buf = (char *) bufv; 400 int written; 401 int origLen = len; 402 if (message) 403 return -1; 404 while ((written = write_buffer(buf, len)) < len && !message) { 405 char c = buf[written]; 406 if (c == '0') { 407 buf += written; 408 len -= written; 409 state = Start; 410 } else if (c == 0) { 411 buf += written; 412 len -= written; 413 state = Reset; 414 } else 415 error("junk in compressed archive"); 416 } 417 return origLen; 418 } 419 420 static unsigned my_inptr; /* index of next byte to be processed in inbuf */ 421 422 #include <linux/decompress/generic.h> 423 424 static char * __init unpack_to_rootfs(char *buf, unsigned len) 425 { 426 int written, res; 427 decompress_fn decompress; 428 const char *compress_name; 429 static __initdata char msg_buf[64]; 430 431 header_buf = kmalloc(110, GFP_KERNEL); 432 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); 433 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); 434 435 if (!header_buf || !symlink_buf || !name_buf) 436 panic("can't allocate buffers"); 437 438 state = Start; 439 this_header = 0; 440 message = NULL; 441 while (!message && len) { 442 loff_t saved_offset = this_header; 443 if (*buf == '0' && !(this_header & 3)) { 444 state = Start; 445 written = write_buffer(buf, len); 446 buf += written; 447 len -= written; 448 continue; 449 } 450 if (!*buf) { 451 buf++; 452 len--; 453 this_header++; 454 continue; 455 } 456 this_header = 0; 457 decompress = decompress_method(buf, len, &compress_name); 458 if (decompress) { 459 res = decompress(buf, len, NULL, flush_buffer, NULL, 460 &my_inptr, error); 461 if (res) 462 error("decompressor failed"); 463 } else if (compress_name) { 464 if (!message) { 465 snprintf(msg_buf, sizeof msg_buf, 466 "compression method %s not configured", 467 compress_name); 468 message = msg_buf; 469 } 470 } else 471 error("junk in compressed archive"); 472 if (state != Reset) 473 error("junk in compressed archive"); 474 this_header = saved_offset + my_inptr; 475 buf += my_inptr; 476 len -= my_inptr; 477 } 478 dir_utime(); 479 kfree(name_buf); 480 kfree(symlink_buf); 481 kfree(header_buf); 482 return message; 483 } 484 485 static int __initdata do_retain_initrd; 486 487 static int __init retain_initrd_param(char *str) 488 { 489 if (*str) 490 return 0; 491 do_retain_initrd = 1; 492 return 1; 493 } 494 __setup("retain_initrd", retain_initrd_param); 495 496 extern char __initramfs_start[]; 497 extern unsigned long __initramfs_size; 498 #include <linux/initrd.h> 499 #include <linux/kexec.h> 500 501 static void __init free_initrd(void) 502 { 503 #ifdef CONFIG_KEXEC 504 unsigned long crashk_start = (unsigned long)__va(crashk_res.start); 505 unsigned long crashk_end = (unsigned long)__va(crashk_res.end); 506 #endif 507 if (do_retain_initrd) 508 goto skip; 509 510 #ifdef CONFIG_KEXEC 511 /* 512 * If the initrd region is overlapped with crashkernel reserved region, 513 * free only memory that is not part of crashkernel region. 514 */ 515 if (initrd_start < crashk_end && initrd_end > crashk_start) { 516 /* 517 * Initialize initrd memory region since the kexec boot does 518 * not do. 519 */ 520 memset((void *)initrd_start, 0, initrd_end - initrd_start); 521 if (initrd_start < crashk_start) 522 free_initrd_mem(initrd_start, crashk_start); 523 if (initrd_end > crashk_end) 524 free_initrd_mem(crashk_end, initrd_end); 525 } else 526 #endif 527 free_initrd_mem(initrd_start, initrd_end); 528 skip: 529 initrd_start = 0; 530 initrd_end = 0; 531 } 532 533 #ifdef CONFIG_BLK_DEV_RAM 534 #define BUF_SIZE 1024 535 static void __init clean_rootfs(void) 536 { 537 int fd; 538 void *buf; 539 struct linux_dirent64 *dirp; 540 int num; 541 542 fd = sys_open("/", O_RDONLY, 0); 543 WARN_ON(fd < 0); 544 if (fd < 0) 545 return; 546 buf = kzalloc(BUF_SIZE, GFP_KERNEL); 547 WARN_ON(!buf); 548 if (!buf) { 549 sys_close(fd); 550 return; 551 } 552 553 dirp = buf; 554 num = sys_getdents64(fd, dirp, BUF_SIZE); 555 while (num > 0) { 556 while (num > 0) { 557 struct stat st; 558 int ret; 559 560 ret = sys_newlstat(dirp->d_name, &st); 561 WARN_ON_ONCE(ret); 562 if (!ret) { 563 if (S_ISDIR(st.st_mode)) 564 sys_rmdir(dirp->d_name); 565 else 566 sys_unlink(dirp->d_name); 567 } 568 569 num -= dirp->d_reclen; 570 dirp = (void *)dirp + dirp->d_reclen; 571 } 572 dirp = buf; 573 memset(buf, 0, BUF_SIZE); 574 num = sys_getdents64(fd, dirp, BUF_SIZE); 575 } 576 577 sys_close(fd); 578 kfree(buf); 579 } 580 #endif 581 582 static int __init populate_rootfs(void) 583 { 584 char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); 585 if (err) 586 panic(err); /* Failed to decompress INTERNAL initramfs */ 587 if (initrd_start) { 588 #ifdef CONFIG_BLK_DEV_RAM 589 int fd; 590 printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n"); 591 err = unpack_to_rootfs((char *)initrd_start, 592 initrd_end - initrd_start); 593 if (!err) { 594 free_initrd(); 595 return 0; 596 } else { 597 clean_rootfs(); 598 unpack_to_rootfs(__initramfs_start, __initramfs_size); 599 } 600 printk(KERN_INFO "rootfs image is not initramfs (%s)" 601 "; looks like an initrd\n", err); 602 fd = sys_open("/initrd.image", 603 O_WRONLY|O_CREAT, 0700); 604 if (fd >= 0) { 605 sys_write(fd, (char *)initrd_start, 606 initrd_end - initrd_start); 607 sys_close(fd); 608 free_initrd(); 609 } 610 #else 611 printk(KERN_INFO "Unpacking initramfs...\n"); 612 err = unpack_to_rootfs((char *)initrd_start, 613 initrd_end - initrd_start); 614 if (err) 615 printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); 616 free_initrd(); 617 #endif 618 } 619 return 0; 620 } 621 rootfs_initcall(populate_rootfs); 622