@@ -865,6 +865,108 @@ static inline void coredump_sock_wait(struct file *file) { }
865865static inline void coredump_sock_shutdown (struct file * file ) { }
866866#endif
867867
868+ /* cprm->mm_flags contains a stable snapshot of dumpability flags. */
869+ static inline bool coredump_force_suid_safe (const struct coredump_params * cprm )
870+ {
871+ /* Require nonrelative corefile path and be extra careful. */
872+ return __get_dumpable (cprm -> mm_flags ) == SUID_DUMP_ROOT ;
873+ }
874+
875+ static bool coredump_file (struct core_name * cn , struct coredump_params * cprm ,
876+ const struct linux_binfmt * binfmt )
877+ {
878+ struct mnt_idmap * idmap ;
879+ struct inode * inode ;
880+ struct file * file __free (fput ) = NULL ;
881+ int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW | O_LARGEFILE | O_EXCL ;
882+
883+ if (cprm -> limit < binfmt -> min_coredump )
884+ return false;
885+
886+ if (coredump_force_suid_safe (cprm ) && cn -> corename [0 ] != '/' ) {
887+ coredump_report_failure ("this process can only dump core to a fully qualified path, skipping core dump" );
888+ return false;
889+ }
890+
891+ /*
892+ * Unlink the file if it exists unless this is a SUID
893+ * binary - in that case, we're running around with root
894+ * privs and don't want to unlink another user's coredump.
895+ */
896+ if (!coredump_force_suid_safe (cprm )) {
897+ /*
898+ * If it doesn't exist, that's fine. If there's some
899+ * other problem, we'll catch it at the filp_open().
900+ */
901+ do_unlinkat (AT_FDCWD , getname_kernel (cn -> corename ));
902+ }
903+
904+ /*
905+ * There is a race between unlinking and creating the
906+ * file, but if that causes an EEXIST here, that's
907+ * fine - another process raced with us while creating
908+ * the corefile, and the other process won. To userspace,
909+ * what matters is that at least one of the two processes
910+ * writes its coredump successfully, not which one.
911+ */
912+ if (coredump_force_suid_safe (cprm )) {
913+ /*
914+ * Using user namespaces, normal user tasks can change
915+ * their current->fs->root to point to arbitrary
916+ * directories. Since the intention of the "only dump
917+ * with a fully qualified path" rule is to control where
918+ * coredumps may be placed using root privileges,
919+ * current->fs->root must not be used. Instead, use the
920+ * root directory of init_task.
921+ */
922+ struct path root ;
923+
924+ task_lock (& init_task );
925+ get_fs_root (init_task .fs , & root );
926+ task_unlock (& init_task );
927+ file = file_open_root (& root , cn -> corename , open_flags , 0600 );
928+ path_put (& root );
929+ } else {
930+ file = filp_open (cn -> corename , open_flags , 0600 );
931+ }
932+ if (IS_ERR (file ))
933+ return false;
934+
935+ inode = file_inode (file );
936+ if (inode -> i_nlink > 1 )
937+ return false;
938+ if (d_unhashed (file -> f_path .dentry ))
939+ return false;
940+ /*
941+ * AK: actually i see no reason to not allow this for named
942+ * pipes etc, but keep the previous behaviour for now.
943+ */
944+ if (!S_ISREG (inode -> i_mode ))
945+ return false;
946+ /*
947+ * Don't dump core if the filesystem changed owner or mode
948+ * of the file during file creation. This is an issue when
949+ * a process dumps core while its cwd is e.g. on a vfat
950+ * filesystem.
951+ */
952+ idmap = file_mnt_idmap (file );
953+ if (!vfsuid_eq_kuid (i_uid_into_vfsuid (idmap , inode ), current_fsuid ())) {
954+ coredump_report_failure ("Core dump to %s aborted: cannot preserve file owner" , cn -> corename );
955+ return false;
956+ }
957+ if ((inode -> i_mode & 0677 ) != 0600 ) {
958+ coredump_report_failure ("Core dump to %s aborted: cannot preserve file permissions" , cn -> corename );
959+ return false;
960+ }
961+ if (!(file -> f_mode & FMODE_CAN_WRITE ))
962+ return false;
963+ if (do_truncate (idmap , file -> f_path .dentry , 0 , 0 , file ))
964+ return false;
965+
966+ cprm -> file = no_free_ptr (file );
967+ return true;
968+ }
969+
868970void vfs_coredump (const kernel_siginfo_t * siginfo )
869971{
870972 struct core_state core_state ;
@@ -876,8 +978,6 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
876978 int retval = 0 ;
877979 size_t * argv = NULL ;
878980 int argc = 0 ;
879- /* require nonrelative corefile path and be extra careful */
880- bool need_suid_safe = false;
881981 bool core_dumped = false;
882982 static atomic_t core_dump_count = ATOMIC_INIT (0 );
883983 struct coredump_params cprm = {
@@ -910,11 +1010,8 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
9101010 * so we dump it as root in mode 2, and only into a controlled
9111011 * environment (pipe handler or fully qualified path).
9121012 */
913- if (__get_dumpable (cprm .mm_flags ) == SUID_DUMP_ROOT ) {
914- /* Setuid core dump mode */
915- cred -> fsuid = GLOBAL_ROOT_UID ; /* Dump root private */
916- need_suid_safe = true;
917- }
1013+ if (coredump_force_suid_safe (& cprm ))
1014+ cred -> fsuid = GLOBAL_ROOT_UID ;
9181015
9191016 retval = coredump_wait (siginfo -> si_signo , & core_state );
9201017 if (retval < 0 )
@@ -928,102 +1025,10 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
9281025 }
9291026
9301027 switch (cn .core_type ) {
931- case COREDUMP_FILE : {
932- struct mnt_idmap * idmap ;
933- struct inode * inode ;
934- int open_flags = O_CREAT | O_WRONLY | O_NOFOLLOW |
935- O_LARGEFILE | O_EXCL ;
936-
937- if (cprm .limit < binfmt -> min_coredump )
938- goto fail_unlock ;
939-
940- if (need_suid_safe && cn .corename [0 ] != '/' ) {
941- coredump_report_failure (
942- "this process can only dump core to a fully qualified path, skipping core dump" );
943- goto fail_unlock ;
944- }
945-
946- /*
947- * Unlink the file if it exists unless this is a SUID
948- * binary - in that case, we're running around with root
949- * privs and don't want to unlink another user's coredump.
950- */
951- if (!need_suid_safe ) {
952- /*
953- * If it doesn't exist, that's fine. If there's some
954- * other problem, we'll catch it at the filp_open().
955- */
956- do_unlinkat (AT_FDCWD , getname_kernel (cn .corename ));
957- }
958-
959- /*
960- * There is a race between unlinking and creating the
961- * file, but if that causes an EEXIST here, that's
962- * fine - another process raced with us while creating
963- * the corefile, and the other process won. To userspace,
964- * what matters is that at least one of the two processes
965- * writes its coredump successfully, not which one.
966- */
967- if (need_suid_safe ) {
968- /*
969- * Using user namespaces, normal user tasks can change
970- * their current->fs->root to point to arbitrary
971- * directories. Since the intention of the "only dump
972- * with a fully qualified path" rule is to control where
973- * coredumps may be placed using root privileges,
974- * current->fs->root must not be used. Instead, use the
975- * root directory of init_task.
976- */
977- struct path root ;
978-
979- task_lock (& init_task );
980- get_fs_root (init_task .fs , & root );
981- task_unlock (& init_task );
982- cprm .file = file_open_root (& root , cn .corename ,
983- open_flags , 0600 );
984- path_put (& root );
985- } else {
986- cprm .file = filp_open (cn .corename , open_flags , 0600 );
987- }
988- if (IS_ERR (cprm .file ))
989- goto fail_unlock ;
990-
991- inode = file_inode (cprm .file );
992- if (inode -> i_nlink > 1 )
993- goto close_fail ;
994- if (d_unhashed (cprm .file -> f_path .dentry ))
995- goto close_fail ;
996- /*
997- * AK: actually i see no reason to not allow this for named
998- * pipes etc, but keep the previous behaviour for now.
999- */
1000- if (!S_ISREG (inode -> i_mode ))
1001- goto close_fail ;
1002- /*
1003- * Don't dump core if the filesystem changed owner or mode
1004- * of the file during file creation. This is an issue when
1005- * a process dumps core while its cwd is e.g. on a vfat
1006- * filesystem.
1007- */
1008- idmap = file_mnt_idmap (cprm .file );
1009- if (!vfsuid_eq_kuid (i_uid_into_vfsuid (idmap , inode ),
1010- current_fsuid ())) {
1011- coredump_report_failure ("Core dump to %s aborted: "
1012- "cannot preserve file owner" , cn .corename );
1013- goto close_fail ;
1014- }
1015- if ((inode -> i_mode & 0677 ) != 0600 ) {
1016- coredump_report_failure ("Core dump to %s aborted: "
1017- "cannot preserve file permissions" , cn .corename );
1018- goto close_fail ;
1019- }
1020- if (!(cprm .file -> f_mode & FMODE_CAN_WRITE ))
1021- goto close_fail ;
1022- if (do_truncate (idmap , cprm .file -> f_path .dentry ,
1023- 0 , 0 , cprm .file ))
1028+ case COREDUMP_FILE :
1029+ if (!coredump_file (& cn , & cprm , binfmt ))
10241030 goto close_fail ;
10251031 break ;
1026- }
10271032 case COREDUMP_PIPE : {
10281033 int argi ;
10291034 int dump_count ;
0 commit comments