hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/init/initramfs.c
....@@ -10,15 +10,19 @@
1010 #include <linux/syscalls.h>
1111 #include <linux/utime.h>
1212 #include <linux/file.h>
13
+#include <linux/memblock.h>
14
+#include <linux/namei.h>
1315 #include <linux/initramfs.h>
16
+#include <linux/init_syscalls.h>
1417
15
-static ssize_t __init xwrite(int fd, const char *p, size_t count)
18
+static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
19
+ loff_t *pos)
1620 {
1721 ssize_t out = 0;
1822
1923 /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */
2024 while (count) {
21
- ssize_t rv = ksys_write(fd, p, count);
25
+ ssize_t rv = kernel_write(file, p, count, pos);
2226
2327 if (rv < 0) {
2428 if (rv == -EINTR || rv == -EAGAIN)
....@@ -108,8 +112,7 @@
108112 t[0].tv_nsec = 0;
109113 t[1].tv_sec = mtime;
110114 t[1].tv_nsec = 0;
111
-
112
- return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
115
+ return init_utimes(filename, t);
113116 }
114117
115118 static __initdata LIST_HEAD(dir_list);
....@@ -200,7 +203,6 @@
200203 byte_count -= n;
201204 }
202205
203
-static __initdata char *vcollected;
204206 static __initdata char *collected;
205207 static long remains __initdata;
206208 static __initdata char *collect;
....@@ -296,11 +298,12 @@
296298 {
297299 struct kstat st;
298300
299
- if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
301
+ if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) &&
302
+ (st.mode ^ fmode) & S_IFMT) {
300303 if (S_ISDIR(st.mode))
301
- ksys_rmdir(path);
304
+ init_rmdir(path);
302305 else
303
- ksys_unlink(path);
306
+ init_unlink(path);
304307 }
305308 }
306309
....@@ -310,13 +313,14 @@
310313 char *old = find_link(major, minor, ino, mode, collected);
311314 if (old) {
312315 clean_path(collected, 0);
313
- return (ksys_link(old, collected) < 0) ? -1 : 1;
316
+ return (init_link(old, collected) < 0) ? -1 : 1;
314317 }
315318 }
316319 return 0;
317320 }
318321
319
-static __initdata int wfd;
322
+static __initdata struct file *wfile;
323
+static __initdata loff_t wfile_pos;
320324
321325 static int __init do_name(void)
322326 {
....@@ -333,28 +337,28 @@
333337 int openflags = O_WRONLY|O_CREAT;
334338 if (ml != 1)
335339 openflags |= O_TRUNC;
336
- wfd = ksys_open(collected, openflags, mode);
340
+ wfile = filp_open(collected, openflags, mode);
341
+ if (IS_ERR(wfile))
342
+ return 0;
343
+ wfile_pos = 0;
337344
338
- if (wfd >= 0) {
339
- ksys_fchown(wfd, uid, gid);
340
- ksys_fchmod(wfd, mode);
341
- if (body_len)
342
- ksys_ftruncate(wfd, body_len);
343
- vcollected = kstrdup(collected, GFP_KERNEL);
344
- state = CopyFile;
345
- }
345
+ vfs_fchown(wfile, uid, gid);
346
+ vfs_fchmod(wfile, mode);
347
+ if (body_len)
348
+ vfs_truncate(&wfile->f_path, body_len);
349
+ state = CopyFile;
346350 }
347351 } else if (S_ISDIR(mode)) {
348
- ksys_mkdir(collected, mode);
349
- ksys_chown(collected, uid, gid);
350
- ksys_chmod(collected, mode);
352
+ init_mkdir(collected, mode);
353
+ init_chown(collected, uid, gid, 0);
354
+ init_chmod(collected, mode);
351355 dir_add(collected, mtime);
352356 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
353357 S_ISFIFO(mode) || S_ISSOCK(mode)) {
354358 if (maybe_link() == 0) {
355
- ksys_mknod(collected, mode, rdev);
356
- ksys_chown(collected, uid, gid);
357
- ksys_chmod(collected, mode);
359
+ init_mknod(collected, mode, rdev);
360
+ init_chown(collected, uid, gid, 0);
361
+ init_chmod(collected, mode);
358362 do_utime(collected, mtime);
359363 }
360364 }
....@@ -364,16 +368,20 @@
364368 static int __init do_copy(void)
365369 {
366370 if (byte_count >= body_len) {
367
- if (xwrite(wfd, victim, body_len) != body_len)
371
+ struct timespec64 t[2] = { };
372
+ if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
368373 error("write error");
369
- ksys_close(wfd);
370
- do_utime(vcollected, mtime);
371
- kfree(vcollected);
374
+
375
+ t[0].tv_sec = mtime;
376
+ t[1].tv_sec = mtime;
377
+ vfs_utimes(&wfile->f_path, t);
378
+
379
+ fput(wfile);
372380 eat(body_len);
373381 state = SkipIt;
374382 return 0;
375383 } else {
376
- if (xwrite(wfd, victim, byte_count) != byte_count)
384
+ if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count)
377385 error("write error");
378386 body_len -= byte_count;
379387 eat(byte_count);
....@@ -385,8 +393,8 @@
385393 {
386394 collected[N_ALIGN(name_len) + body_len] = '\0';
387395 clean_path(collected, 0);
388
- ksys_symlink(collected + N_ALIGN(name_len), collected);
389
- ksys_lchown(collected, uid, gid);
396
+ init_symlink(collected + N_ALIGN(name_len), collected);
397
+ init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
390398 do_utime(collected, mtime);
391399 state = SkipIt;
392400 next_state = Reset;
....@@ -432,7 +440,7 @@
432440 len -= written;
433441 state = Reset;
434442 } else
435
- error("junk in compressed archive");
443
+ error("junk within compressed archive");
436444 }
437445 return origLen;
438446 }
....@@ -458,12 +466,6 @@
458466 state = Start;
459467 this_header = 0;
460468 message = NULL;
461
-
462
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_CRYPTO
463
- if (rk_tb_crypto_sha256_wait_compare_done())
464
- panic("Timeout, campare the sha256 digest fail, the ramdisk is untrusted.\n");
465
-#endif
466
-
467469 #if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_ROCKCHIP_HW_DECOMPRESS) && defined(CONFIG_INITRD_ASYNC)
468470 wait_initrd_hw_decom_done();
469471 #endif
....@@ -498,14 +500,9 @@
498500 message = msg_buf;
499501 }
500502 } else
501
- error("junk in compressed archive");
503
+ error("invalid magic at start of compressed archive");
502504 if (state != Reset)
503
- error("junk in compressed archive");
504
- #ifdef CONFIG_ROCKCHIP_ONE_INITRD
505
- else
506
- break;
507
- #endif
508
-
505
+ error("junk at the end of compressed archive");
509506 this_header = saved_offset + my_inptr;
510507 buf += my_inptr;
511508 len -= my_inptr;
....@@ -528,178 +525,122 @@
528525 }
529526 __setup("retain_initrd", retain_initrd_param);
530527
531
-static int __initdata do_dump_initrd;
532
-
533
-static int __init dump_initrd_param(char *str)
528
+#ifdef CONFIG_ARCH_HAS_KEEPINITRD
529
+static int __init keepinitrd_setup(char *__unused)
534530 {
535
- if (*str)
536
- return 0;
537
- do_dump_initrd = 1;
531
+ do_retain_initrd = 1;
538532 return 1;
539533 }
540
-__setup("dump_initrd", dump_initrd_param);
534
+__setup("keepinitrd", keepinitrd_setup);
535
+#endif
541536
542537 extern char __initramfs_start[];
543538 extern unsigned long __initramfs_size;
544539 #include <linux/initrd.h>
545540 #include <linux/kexec.h>
546541
547
-static void __init free_initrd(void)
542
+void __weak __init free_initrd_mem(unsigned long start, unsigned long end)
548543 {
549
-#ifdef CONFIG_KEXEC_CORE
550
- unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
551
- unsigned long crashk_end = (unsigned long)__va(crashk_res.end);
544
+#ifdef CONFIG_ARCH_KEEP_MEMBLOCK
545
+ unsigned long aligned_start = ALIGN_DOWN(start, PAGE_SIZE);
546
+ unsigned long aligned_end = ALIGN(end, PAGE_SIZE);
547
+
548
+ memblock_free(__pa(aligned_start), aligned_end - aligned_start);
552549 #endif
553
- if (do_retain_initrd || !initrd_start)
554
- goto skip;
550
+
551
+ free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
552
+ "initrd");
553
+}
555554
556555 #ifdef CONFIG_KEXEC_CORE
556
+static bool __init kexec_free_initrd(void)
557
+{
558
+ unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
559
+ unsigned long crashk_end = (unsigned long)__va(crashk_res.end);
560
+
557561 /*
558562 * If the initrd region is overlapped with crashkernel reserved region,
559563 * free only memory that is not part of crashkernel region.
560564 */
561
- if (initrd_start < crashk_end && initrd_end > crashk_start) {
562
- /*
563
- * Initialize initrd memory region since the kexec boot does
564
- * not do.
565
- */
566
- memset((void *)initrd_start, 0, initrd_end - initrd_start);
567
- if (initrd_start < crashk_start)
568
- free_initrd_mem(initrd_start, crashk_start);
569
- if (initrd_end > crashk_end)
570
- free_initrd_mem(crashk_end, initrd_end);
571
- } else
572
-#endif
573
- free_initrd_mem(initrd_start, initrd_end);
574
-skip:
575
- initrd_start = 0;
576
- initrd_end = 0;
565
+ if (initrd_start >= crashk_end || initrd_end <= crashk_start)
566
+ return false;
567
+
568
+ /*
569
+ * Initialize initrd memory region since the kexec boot does not do.
570
+ */
571
+ memset((void *)initrd_start, 0, initrd_end - initrd_start);
572
+ if (initrd_start < crashk_start)
573
+ free_initrd_mem(initrd_start, crashk_start);
574
+ if (initrd_end > crashk_end)
575
+ free_initrd_mem(crashk_end, initrd_end);
576
+ return true;
577577 }
578
+#else
579
+static inline bool kexec_free_initrd(void)
580
+{
581
+ return false;
582
+}
583
+#endif /* CONFIG_KEXEC_CORE */
578584
579585 #ifdef CONFIG_BLK_DEV_RAM
580
-#define BUF_SIZE 1024
581
-static void __init clean_rootfs(void)
586
+static void __init populate_initrd_image(char *err)
582587 {
583
- int fd;
584
- void *buf;
585
- struct linux_dirent64 *dirp;
586
- int num;
588
+ ssize_t written;
589
+ struct file *file;
590
+ loff_t pos = 0;
587591
588
- fd = ksys_open("/", O_RDONLY, 0);
589
- WARN_ON(fd < 0);
590
- if (fd < 0)
592
+ unpack_to_rootfs(__initramfs_start, __initramfs_size);
593
+
594
+ printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n",
595
+ err);
596
+ file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700);
597
+ if (IS_ERR(file))
591598 return;
592
- buf = kzalloc(BUF_SIZE, GFP_KERNEL);
593
- WARN_ON(!buf);
594
- if (!buf) {
595
- ksys_close(fd);
596
- return;
597
- }
598599
599
- dirp = buf;
600
- num = ksys_getdents64(fd, dirp, BUF_SIZE);
601
- while (num > 0) {
602
- while (num > 0) {
603
- struct kstat st;
604
- int ret;
605
-
606
- ret = vfs_lstat(dirp->d_name, &st);
607
- WARN_ON_ONCE(ret);
608
- if (!ret) {
609
- if (S_ISDIR(st.mode))
610
- ksys_rmdir(dirp->d_name);
611
- else
612
- ksys_unlink(dirp->d_name);
613
- }
614
-
615
- num -= dirp->d_reclen;
616
- dirp = (void *)dirp + dirp->d_reclen;
617
- }
618
- dirp = buf;
619
- memset(buf, 0, BUF_SIZE);
620
- num = ksys_getdents64(fd, dirp, BUF_SIZE);
621
- }
622
-
623
- ksys_close(fd);
624
- kfree(buf);
600
+ written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start,
601
+ &pos);
602
+ if (written != initrd_end - initrd_start)
603
+ pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
604
+ written, initrd_end - initrd_start);
605
+ fput(file);
625606 }
626
-#endif
627
-
628
-static int __initdata do_skip_initramfs;
629
-
630
-static int __init skip_initramfs_param(char *str)
631
-{
632
- if (*str)
633
- return 0;
634
- do_skip_initramfs = 1;
635
- return 1;
636
-}
637
-__setup("skip_initramfs", skip_initramfs_param);
607
+#endif /* CONFIG_BLK_DEV_RAM */
638608
639609 static int __init populate_rootfs(void)
640610 {
641
- char *err;
642
-
643
- if (do_skip_initramfs) {
644
- if (initrd_start)
645
- free_initrd();
646
- return default_rootfs();
647
- }
648
-
649611 /* Load the built in initramfs */
650
- err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
612
+ char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
651613 if (err)
652614 panic("%s", err); /* Failed to decompress INTERNAL initramfs */
653
- /* If available load the bootloader supplied initrd */
654
- if (initrd_start && !IS_ENABLED(CONFIG_INITRAMFS_FORCE)) {
655
-#ifdef CONFIG_BLK_DEV_RAM
656
- int fd;
615
+
616
+ if (!initrd_start || IS_ENABLED(CONFIG_INITRAMFS_FORCE))
617
+ goto done;
618
+
619
+ if (IS_ENABLED(CONFIG_BLK_DEV_RAM))
657620 printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
658
- err = unpack_to_rootfs((char *)initrd_start,
659
- initrd_end - initrd_start);
660
- if (!err) {
661
- if (do_dump_initrd)
662
- goto dump;
663
-
664
- goto done;
665
- }
666
-
667
- clean_rootfs();
668
- unpack_to_rootfs(__initramfs_start, __initramfs_size);
669
-
670
- printk(KERN_INFO "rootfs image is not initramfs (%s)"
671
- "; looks like an initrd\n", err);
672
- dump:
673
- fd = ksys_open("/initrd.image",
674
- O_WRONLY|O_CREAT, 0700);
675
- if (fd >= 0) {
676
- ssize_t written = xwrite(fd, (char *)initrd_start,
677
- initrd_end - initrd_start);
678
-
679
- if (written != initrd_end - initrd_start)
680
- pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
681
- written, initrd_end - initrd_start);
682
-
683
- ksys_close(fd);
684
- }
685
- done:
686
- /* empty statement */;
687
-#else
621
+ else
688622 printk(KERN_INFO "Unpacking initramfs...\n");
689
- err = unpack_to_rootfs((char *)initrd_start,
690
- initrd_end - initrd_start);
691
- if (err)
692
- printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
623
+
624
+ err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start);
625
+ if (err) {
626
+#ifdef CONFIG_BLK_DEV_RAM
627
+ populate_initrd_image(err);
628
+#else
629
+ printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
693630 #endif
694631 }
695
- free_initrd();
696
- flush_delayed_fput();
697
- /*
698
- * Try loading default modules from initramfs. This gives
699
- * us a chance to load before device_initcalls.
700
- */
701
- load_default_modules();
702632
633
+done:
634
+ /*
635
+ * If the initrd region is overlapped with crashkernel reserved region,
636
+ * free only memory that is not part of crashkernel region.
637
+ */
638
+ if (!do_retain_initrd && initrd_start && !kexec_free_initrd())
639
+ free_initrd_mem(initrd_start, initrd_end);
640
+ initrd_start = 0;
641
+ initrd_end = 0;
642
+
643
+ flush_delayed_fput();
703644 return 0;
704645 }
705646