|
@@ -32,6 +32,9 @@
|
|
#include <linux/pipe_fs_i.h>
|
|
#include <linux/pipe_fs_i.h>
|
|
#include <linux/oom.h>
|
|
#include <linux/oom.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/compat.h>
|
|
|
|
+#include <linux/sched.h>
|
|
|
|
+#include <linux/fs.h>
|
|
|
|
+#include <linux/path.h>
|
|
#include <linux/timekeeping.h>
|
|
#include <linux/timekeeping.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
@@ -649,6 +652,8 @@ void do_coredump(const siginfo_t *siginfo)
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
struct inode *inode;
|
|
struct inode *inode;
|
|
|
|
+ int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
|
|
|
|
+ O_LARGEFILE | O_EXCL;
|
|
|
|
|
|
if (cprm.limit < binfmt->min_coredump)
|
|
if (cprm.limit < binfmt->min_coredump)
|
|
goto fail_unlock;
|
|
goto fail_unlock;
|
|
@@ -687,10 +692,27 @@ void do_coredump(const siginfo_t *siginfo)
|
|
* what matters is that at least one of the two processes
|
|
* what matters is that at least one of the two processes
|
|
* writes its coredump successfully, not which one.
|
|
* writes its coredump successfully, not which one.
|
|
*/
|
|
*/
|
|
- cprm.file = filp_open(cn.corename,
|
|
|
|
- O_CREAT | 2 | O_NOFOLLOW |
|
|
|
|
- O_LARGEFILE | O_EXCL,
|
|
|
|
- 0600);
|
|
|
|
|
|
+ if (need_suid_safe) {
|
|
|
|
+ /*
|
|
|
|
+ * Using user namespaces, normal user tasks can change
|
|
|
|
+ * their current->fs->root to point to arbitrary
|
|
|
|
+ * directories. Since the intention of the "only dump
|
|
|
|
+ * with a fully qualified path" rule is to control where
|
|
|
|
+ * coredumps may be placed using root privileges,
|
|
|
|
+ * current->fs->root must not be used. Instead, use the
|
|
|
|
+ * root directory of init_task.
|
|
|
|
+ */
|
|
|
|
+ struct path root;
|
|
|
|
+
|
|
|
|
+ task_lock(&init_task);
|
|
|
|
+ get_fs_root(init_task.fs, &root);
|
|
|
|
+ task_unlock(&init_task);
|
|
|
|
+ cprm.file = file_open_root(root.dentry, root.mnt,
|
|
|
|
+ cn.corename, open_flags, 0600);
|
|
|
|
+ path_put(&root);
|
|
|
|
+ } else {
|
|
|
|
+ cprm.file = filp_open(cn.corename, open_flags, 0600);
|
|
|
|
+ }
|
|
if (IS_ERR(cprm.file))
|
|
if (IS_ERR(cprm.file))
|
|
goto fail_unlock;
|
|
goto fail_unlock;
|
|
|
|
|