summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-16 13:30:07 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-10-16 13:36:50 -0400
commit45525b26a46cd593cb72070304c4cd7c8391bd37 (patch)
tree9064f045ef433e4d74d281daa995ee3c082e806e
parentdd8e8c4a2c902d8350b702e7bc7c2799e5e7e331 (diff)
fix a leak in replace_fd() users
replace_fd() began with "eats a reference, tries to insert into descriptor table" semantics; at some point I'd switched it to much saner current behaviour ("try to insert into descriptor table, grabbing a new reference if inserted; caller should do fput() in any case"), but forgot to update the callers. Mea culpa... [Spotted by Pavel Roskin, who has really weird system with pipe-fed coredumps as part of what he considers a normal boot ;-)] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/coredump.c5
-rw-r--r--security/selinux/hooks.c18
2 files changed, 10 insertions, 13 deletions
diff --git a/fs/coredump.c b/fs/coredump.c
index fd37facac8dc..ce47379bfa61 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -450,11 +450,12 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
cp->file = files[1];
- replace_fd(0, files[0], 0);
+ err = replace_fd(0, files[0], 0);
+ fput(files[0]);
/* and disallow core files too */
current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
- return 0;
+ return err;
}
void do_coredump(siginfo_t *siginfo, struct pt_regs *regs)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 24ab4148547c..61a53367d029 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2132,18 +2132,14 @@ static inline void flush_unauthorized_files(const struct cred *cred,
return;
devnull = dentry_open(&selinux_null, O_RDWR, cred);
- if (!IS_ERR(devnull)) {
- /* replace all the matching ones with this */
- do {
- replace_fd(n - 1, get_file(devnull), 0);
- } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
+ if (IS_ERR(devnull))
+ devnull = NULL;
+ /* replace all the matching ones with this */
+ do {
+ replace_fd(n - 1, devnull, 0);
+ } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
+ if (devnull)
fput(devnull);
- } else {
- /* just close all the matching ones */
- do {
- replace_fd(n - 1, NULL, 0);
- } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
- }
}
/*