diff options
author | Oleg Nesterov <oleg@redhat.com> | 2010-05-26 17:43:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 12:12:45 -0400 |
commit | c713541125002b8bc9e681af3b09118e771e2d8a (patch) | |
tree | 6c85885dc2403b0310ab13e1c21dcb30960ced83 | |
parent | 04b1c384fbc4e0209e5c1affb67050886376d44b (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.c | 63 |
1 files changed, 31 insertions, 32 deletions
@@ -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; |
2007 | close_fail: | 2006 | close_fail: |