aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2010-05-26 17:43:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 12:12:45 -0400
commitc713541125002b8bc9e681af3b09118e771e2d8a (patch)
tree6c85885dc2403b0310ab13e1c21dcb30960ced83
parent04b1c384fbc4e0209e5c1affb67050886376d44b (diff)
coredump: factor out the not-ispipe file checks
do_coredump() does a lot of file checks after it opens the file or calls usermode helper. But all of these checks are only needed in !ispipe case. Move this code into the "else" branch and kill the ugly repetitive ispipe checks. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: David Howells <dhowells@redhat.com> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: Roland McGrath <roland@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/exec.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 63f459cf20df..1d55d7536641 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1837,7 +1837,6 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1837 char corename[CORENAME_MAX_SIZE + 1]; 1837 char corename[CORENAME_MAX_SIZE + 1];
1838 struct mm_struct *mm = current->mm; 1838 struct mm_struct *mm = current->mm;
1839 struct linux_binfmt * binfmt; 1839 struct linux_binfmt * binfmt;
1840 struct inode * inode;
1841 const struct cred *old_cred; 1840 const struct cred *old_cred;
1842 struct cred *cred; 1841 struct cred *cred;
1843 int retval = 0; 1842 int retval = 0;
@@ -1914,9 +1913,6 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1914 ispipe = format_corename(corename, signr); 1913 ispipe = format_corename(corename, signr);
1915 unlock_kernel(); 1914 unlock_kernel();
1916 1915
1917 if ((!ispipe) && (cprm.limit < binfmt->min_coredump))
1918 goto fail_unlock;
1919
1920 if (ispipe) { 1916 if (ispipe) {
1921 if (cprm.limit == 1) { 1917 if (cprm.limit == 1) {
1922 /* 1918 /*
@@ -1969,39 +1965,42 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1969 corename); 1965 corename);
1970 goto fail_dropcount; 1966 goto fail_dropcount;
1971 } 1967 }
1972 } else 1968 } else {
1969 struct inode *inode;
1970
1971 if (cprm.limit < binfmt->min_coredump)
1972 goto fail_unlock;
1973
1973 cprm.file = filp_open(corename, 1974 cprm.file = filp_open(corename,
1974 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 1975 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
1975 0600); 1976 0600);
1976 if (IS_ERR(cprm.file)) 1977 if (IS_ERR(cprm.file))
1977 goto fail_dropcount; 1978 goto fail_unlock;
1978 inode = cprm.file->f_path.dentry->d_inode;
1979 if (inode->i_nlink > 1)
1980 goto close_fail; /* multiple links - don't dump */
1981 if (!ispipe && d_unhashed(cprm.file->f_path.dentry))
1982 goto close_fail;
1983
1984 /* AK: actually i see no reason to not allow this for named pipes etc.,
1985 but keep the previous behaviour for now. */
1986 if (!ispipe && !S_ISREG(inode->i_mode))
1987 goto close_fail;
1988 /*
1989 * Dont allow local users get cute and trick others to coredump
1990 * into their pre-created files:
1991 * Note, this is not relevant for pipes
1992 */
1993 if (!ispipe && (inode->i_uid != current_fsuid()))
1994 goto close_fail;
1995 if (!cprm.file->f_op)
1996 goto close_fail;
1997 if (!cprm.file->f_op->write)
1998 goto close_fail;
1999 if (!ispipe &&
2000 do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0)
2001 goto close_fail;
2002 1979
2003 retval = binfmt->core_dump(&cprm); 1980 inode = cprm.file->f_path.dentry->d_inode;
1981 if (inode->i_nlink > 1)
1982 goto close_fail;
1983 if (d_unhashed(cprm.file->f_path.dentry))
1984 goto close_fail;
1985 /*
1986 * AK: actually i see no reason to not allow this for named
1987 * pipes etc, but keep the previous behaviour for now.
1988 */
1989 if (!S_ISREG(inode->i_mode))
1990 goto close_fail;
1991 /*
1992 * Dont allow local users get cute and trick others to coredump
1993 * into their pre-created files.
1994 */
1995 if (inode->i_uid != current_fsuid())
1996 goto close_fail;
1997 if (!cprm.file->f_op || !cprm.file->f_op->write)
1998 goto close_fail;
1999 if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
2000 goto close_fail;
2001 }
2004 2002
2003 retval = binfmt->core_dump(&cprm);
2005 if (retval) 2004 if (retval)
2006 current->signal->group_exit_code |= 0x80; 2005 current->signal->group_exit_code |= 0x80;
2007close_fail: 2006close_fail: