Hi Roman, kernel test robot noticed the following build warnings: [auto build test WARNING on 831bcbcead6668ebf20b64fdb27518f1362ace3a] url: https://github.com/intel-lab-lkp/linux/commits/Roman-Kisel/binfmt_elf-coredump-Log-the-reason-of-the-failed-core-dumps/20240618-074419 base: 831bcbcead6668ebf20b64fdb27518f1362ace3a patch link: https://lore.kernel.org/r/20240617234133.1167523-2-romank%40linux.microsoft.com patch subject: [PATCH 1/1] binfmt_elf, coredump: Log the reason of the failed core dumps config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20240618/202406181954.9Z65WD4Z-lkp@xxxxxxxxx/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 78ee473784e5ef6f0b19ce4cb111fb6e4d23c6b2) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240618/202406181954.9Z65WD4Z-lkp@xxxxxxxxx/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@xxxxxxxxx> | Closes: https://lore.kernel.org/oe-kbuild-all/202406181954.9Z65WD4Z-lkp@xxxxxxxxx/ All warnings (new ones prefixed by >>): In file included from fs/coredump.c:6: In file included from include/linux/mm.h:2253: include/linux/vmstat.h:514:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 514 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ >> fs/coredump.c:816:32: warning: format specifies type 'unsigned long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat] 815 | pr_info("Core dump to |%s: vma_count %d, vma_data_size %lu, written %lld bytes, pos %lld\n", | ~~~ | %zu 816 | cn.corename, cprm.vma_count, cprm.vma_data_size, cprm.written, cprm.pos); | ^~~~~~~~~~~~~~~~~~ include/linux/printk.h:537:34: note: expanded from macro 'pr_info' 537 | printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) | ~~~ ^~~~~~~~~~~ include/linux/printk.h:464:60: note: expanded from macro 'printk' 464 | #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__) | ~~~ ^~~~~~~~~~~ include/linux/printk.h:436:19: note: expanded from macro 'printk_index_wrap' 436 | _p_func(_fmt, ##__VA_ARGS__); \ | ~~~~ ^~~~~~~~~~~ 2 warnings generated. vim +816 fs/coredump.c 521 522 int do_coredump(const kernel_siginfo_t *siginfo) 523 { 524 struct core_state core_state; 525 struct core_name cn; 526 struct mm_struct *mm = current->mm; 527 struct linux_binfmt * binfmt; 528 const struct cred *old_cred; 529 struct cred *cred; 530 int retval; 531 int ispipe; 532 size_t *argv = NULL; 533 int argc = 0; 534 /* require nonrelative corefile path and be extra careful */ 535 bool need_suid_safe = false; 536 bool core_dumped = false; 537 static atomic_t core_dump_count = ATOMIC_INIT(0); 538 struct coredump_params cprm = { 539 .siginfo = siginfo, 540 .limit = rlimit(RLIMIT_CORE), 541 /* 542 * We must use the same mm->flags while dumping core to avoid 543 * inconsistency of bit flags, since this flag is not protected 544 * by any locks. 545 */ 546 .mm_flags = mm->flags, 547 .vma_meta = NULL, 548 .cpu = raw_smp_processor_id(), 549 }; 550 551 audit_core_dumps(siginfo->si_signo); 552 553 binfmt = mm->binfmt; 554 if (!binfmt || !binfmt->core_dump) { 555 retval = -ENOEXEC; 556 goto fail; 557 } 558 if (!__get_dumpable(cprm.mm_flags)) { 559 retval = -EACCES; 560 goto fail; 561 } 562 563 cred = prepare_creds(); 564 if (!cred) { 565 retval = -EPERM; 566 goto fail; 567 } 568 /* 569 * We cannot trust fsuid as being the "true" uid of the process 570 * nor do we know its entire history. We only know it was tainted 571 * so we dump it as root in mode 2, and only into a controlled 572 * environment (pipe handler or fully qualified path). 573 */ 574 if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) { 575 /* Setuid core dump mode */ 576 cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ 577 need_suid_safe = true; 578 } 579 580 retval = coredump_wait(siginfo->si_signo, &core_state); 581 if (retval < 0) 582 goto fail_creds; 583 584 old_cred = override_creds(cred); 585 586 ispipe = format_corename(&cn, &cprm, &argv, &argc); 587 588 if (ispipe) { 589 int argi; 590 int dump_count; 591 char **helper_argv; 592 struct subprocess_info *sub_info; 593 594 if (ispipe < 0) { 595 printk(KERN_WARNING "format_corename failed\n"); 596 printk(KERN_WARNING "Aborting core\n"); 597 retval = ispipe; 598 goto fail_unlock; 599 } 600 601 if (cprm.limit == 1) { 602 /* See umh_pipe_setup() which sets RLIMIT_CORE = 1. 603 * 604 * Normally core limits are irrelevant to pipes, since 605 * we're not writing to the file system, but we use 606 * cprm.limit of 1 here as a special value, this is a 607 * consistent way to catch recursive crashes. 608 * We can still crash if the core_pattern binary sets 609 * RLIM_CORE = !1, but it runs as root, and can do 610 * lots of stupid things. 611 * 612 * Note that we use task_tgid_vnr here to grab the pid 613 * of the process group leader. That way we get the 614 * right pid if a thread in a multi-threaded 615 * core_pattern process dies. 616 */ 617 printk(KERN_WARNING 618 "Process %d(%s) has RLIMIT_CORE set to 1\n", 619 task_tgid_vnr(current), current->comm); 620 printk(KERN_WARNING "Aborting core\n"); 621 retval = -EPERM; 622 goto fail_unlock; 623 } 624 cprm.limit = RLIM_INFINITY; 625 626 dump_count = atomic_inc_return(&core_dump_count); 627 if (core_pipe_limit && (core_pipe_limit < dump_count)) { 628 printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", 629 task_tgid_vnr(current), current->comm); 630 printk(KERN_WARNING "Skipping core dump\n"); 631 retval = -E2BIG; 632 goto fail_dropcount; 633 } 634 635 helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv), 636 GFP_KERNEL); 637 if (!helper_argv) { 638 printk(KERN_WARNING "%s failed to allocate memory\n", 639 __func__); 640 retval = -ENOMEM; 641 goto fail_dropcount; 642 } 643 for (argi = 0; argi < argc; argi++) 644 helper_argv[argi] = cn.corename + argv[argi]; 645 helper_argv[argi] = NULL; 646 647 retval = -ENOMEM; 648 sub_info = call_usermodehelper_setup(helper_argv[0], 649 helper_argv, NULL, GFP_KERNEL, 650 umh_pipe_setup, NULL, &cprm); 651 if (sub_info) 652 retval = call_usermodehelper_exec(sub_info, 653 UMH_WAIT_EXEC); 654 655 kfree(helper_argv); 656 if (retval) { 657 printk(KERN_INFO "Core dump to |%s pipe failed\n", 658 cn.corename); 659 goto close_fail; 660 } 661 } else { 662 struct mnt_idmap *idmap; 663 struct inode *inode; 664 int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW | 665 O_LARGEFILE | O_EXCL; 666 667 if (cprm.limit < binfmt->min_coredump) { 668 retval = -E2BIG; 669 goto fail_unlock; 670 } 671 672 if (need_suid_safe && cn.corename[0] != '/') { 673 printk(KERN_WARNING "Pid %d(%s) can only dump core "\ 674 "to fully qualified path!\n", 675 task_tgid_vnr(current), current->comm); 676 printk(KERN_WARNING "Skipping core dump\n"); 677 retval = -EPERM; 678 goto fail_unlock; 679 } 680 681 /* 682 * Unlink the file if it exists unless this is a SUID 683 * binary - in that case, we're running around with root 684 * privs and don't want to unlink another user's coredump. 685 */ 686 if (!need_suid_safe) { 687 /* 688 * If it doesn't exist, that's fine. If there's some 689 * other problem, we'll catch it at the filp_open(). 690 */ 691 do_unlinkat(AT_FDCWD, getname_kernel(cn.corename)); 692 } 693 694 /* 695 * There is a race between unlinking and creating the 696 * file, but if that causes an EEXIST here, that's 697 * fine - another process raced with us while creating 698 * the corefile, and the other process won. To userspace, 699 * what matters is that at least one of the two processes 700 * writes its coredump successfully, not which one. 701 */ 702 if (need_suid_safe) { 703 /* 704 * Using user namespaces, normal user tasks can change 705 * their current->fs->root to point to arbitrary 706 * directories. Since the intention of the "only dump 707 * with a fully qualified path" rule is to control where 708 * coredumps may be placed using root privileges, 709 * current->fs->root must not be used. Instead, use the 710 * root directory of init_task. 711 */ 712 struct path root; 713 714 task_lock(&init_task); 715 get_fs_root(init_task.fs, &root); 716 task_unlock(&init_task); 717 cprm.file = file_open_root(&root, cn.corename, 718 open_flags, 0600); 719 path_put(&root); 720 } else { 721 cprm.file = filp_open(cn.corename, open_flags, 0600); 722 } 723 if (IS_ERR(cprm.file)) { 724 retval = PTR_ERR(cprm.file); 725 goto fail_unlock; 726 } 727 728 inode = file_inode(cprm.file); 729 if (inode->i_nlink > 1) { 730 retval = -EMLINK; 731 goto close_fail; 732 } 733 if (d_unhashed(cprm.file->f_path.dentry)) { 734 retval = -EEXIST; 735 goto close_fail; 736 } 737 /* 738 * AK: actually i see no reason to not allow this for named 739 * pipes etc, but keep the previous behaviour for now. 740 */ 741 if (!S_ISREG(inode->i_mode)) { 742 retval = -EISDIR; 743 goto close_fail; 744 } 745 /* 746 * Don't dump core if the filesystem changed owner or mode 747 * of the file during file creation. This is an issue when 748 * a process dumps core while its cwd is e.g. on a vfat 749 * filesystem. 750 */ 751 idmap = file_mnt_idmap(cprm.file); 752 if (!vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, inode), 753 current_fsuid())) { 754 pr_info_ratelimited("Core dump to %s aborted: cannot preserve file owner\n", 755 cn.corename); 756 retval = -EPERM; 757 goto close_fail; 758 } 759 if ((inode->i_mode & 0677) != 0600) { 760 pr_info_ratelimited("Core dump to %s aborted: cannot preserve file permissions\n", 761 cn.corename); 762 retval = -EPERM; 763 goto close_fail; 764 } 765 if (!(cprm.file->f_mode & FMODE_CAN_WRITE)) { 766 retval = -EACCES; 767 goto close_fail; 768 } 769 retval = do_truncate(idmap, cprm.file->f_path.dentry, 770 0, 0, cprm.file); 771 if (retval) 772 goto close_fail; 773 } 774 775 /* get us an unshared descriptor table; almost always a no-op */ 776 /* The cell spufs coredump code reads the file descriptor tables */ 777 retval = unshare_files(); 778 if (retval) 779 goto close_fail; 780 if (!dump_interrupted()) { 781 /* 782 * umh disabled with CONFIG_STATIC_USERMODEHELPER_PATH="" would 783 * have this set to NULL. 784 */ 785 if (!cprm.file) { 786 pr_info("Core dump to |%s disabled\n", cn.corename); 787 retval = -EPERM; 788 goto close_fail; 789 } 790 if (!dump_vma_snapshot(&cprm)) { 791 pr_err("Can't get VMA snapshot for core dump |%s\n", cn.corename); 792 retval = -EACCES; 793 goto close_fail; 794 } 795 796 file_start_write(cprm.file); 797 core_dumped = binfmt->core_dump(&cprm); 798 /* 799 * Ensures that file size is big enough to contain the current 800 * file postion. This prevents gdb from complaining about 801 * a truncated file if the last "write" to the file was 802 * dump_skip. 803 */ 804 if (cprm.to_skip) { 805 cprm.to_skip--; 806 dump_emit(&cprm, "", 1); 807 } 808 file_end_write(cprm.file); 809 free_vma_snapshot(&cprm); 810 } else { 811 pr_err("Core dump to |%s has been interrupted\n", cn.corename); 812 retval = -EAGAIN; 813 goto fail; 814 } 815 pr_info("Core dump to |%s: vma_count %d, vma_data_size %lu, written %lld bytes, pos %lld\n", > 816 cn.corename, cprm.vma_count, cprm.vma_data_size, cprm.written, cprm.pos); 817 if (ispipe && core_pipe_limit) 818 wait_for_dump_helpers(cprm.file); 819 820 retval = 0; 821 822 close_fail: 823 if (cprm.file) 824 filp_close(cprm.file, NULL); 825 fail_dropcount: 826 if (ispipe) 827 atomic_dec(&core_dump_count); 828 fail_unlock: 829 kfree(argv); 830 kfree(cn.corename); 831 coredump_finish(core_dumped); 832 revert_creds(old_cred); 833 fail_creds: 834 put_cred(cred); 835 fail: 836 return retval; 837 } 838 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki