From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
torvalds@osdl.org, akpm@osdl.org, alan@lxorguk.ukuu.org.uk,
aviro@redhat.com
Subject: [patch 04/12] Fix double decrement of mqueue_mnt->mnt_count in sys_mq_open (CVE-2005-3356)
Date: Fri, 27 Jan 2006 18:20:52 -0800 [thread overview]
Message-ID: <20060128022052.GE17001@kroah.com> (raw)
In-Reply-To: <20060128022023.GA17001@kroah.com>
[-- Attachment #1: fix-double-decrement-of-mqueue_mnt-mnt_count-in-sys_mq_open.patch --]
[-- Type: text/plain, Size: 3950 bytes --]
2.6.15.2 -stable review patch. If anyone has any objections, please let
us know.
------------------
From: Alexander Viro <aviro@redhat.com>
Fixed the refcounting on failure exits in sys_mq_open() and
cleaned the logics up. Rules are actually pretty simple - dentry_open()
expects vfsmount and dentry to be pinned down and it either transfers
them into created struct file or drops them. Old code had been very
confused in that area - if dentry_open() had failed either in do_open()
or do_create(), we ended up dentry and mqueue_mnt dropped twice, once
by dentry_open() cleanup and then by sys_mq_open().
Fix consists of making the rules for do_create() and do_open()
same as for dentry_open() and updating the sys_mq_open() accordingly;
that actually leads to more straightforward code and less work on
normal path.
Signed-off-by: Al Viro <aviro@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
ipc/mqueue.c | 59 +++++++++++++++++++++++++++++++++--------------------------
1 file changed, 33 insertions(+), 26 deletions(-)
--- linux-2.6.15.1.orig/ipc/mqueue.c
+++ linux-2.6.15.1/ipc/mqueue.c
@@ -598,15 +598,16 @@ static int mq_attr_ok(struct mq_attr *at
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
int oflag, mode_t mode, struct mq_attr __user *u_attr)
{
- struct file *filp;
struct mq_attr attr;
int ret;
- if (u_attr != NULL) {
+ if (u_attr) {
+ ret = -EFAULT;
if (copy_from_user(&attr, u_attr, sizeof(attr)))
- return ERR_PTR(-EFAULT);
+ goto out;
+ ret = -EINVAL;
if (!mq_attr_ok(&attr))
- return ERR_PTR(-EINVAL);
+ goto out;
/* store for use during create */
dentry->d_fsdata = &attr;
}
@@ -615,13 +616,14 @@ static struct file *do_create(struct den
ret = vfs_create(dir->d_inode, dentry, mode, NULL);
dentry->d_fsdata = NULL;
if (ret)
- return ERR_PTR(ret);
+ goto out;
- filp = dentry_open(dentry, mqueue_mnt, oflag);
- if (!IS_ERR(filp))
- dget(dentry);
+ return dentry_open(dentry, mqueue_mnt, oflag);
- return filp;
+out:
+ dput(dentry);
+ mntput(mqueue_mnt);
+ return ERR_PTR(ret);
}
/* Opens existing queue */
@@ -629,20 +631,20 @@ static struct file *do_open(struct dentr
{
static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
MAY_READ | MAY_WRITE };
- struct file *filp;
- if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY))
+ if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
+ dput(dentry);
+ mntput(mqueue_mnt);
return ERR_PTR(-EINVAL);
+ }
- if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL))
+ if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) {
+ dput(dentry);
+ mntput(mqueue_mnt);
return ERR_PTR(-EACCES);
+ }
- filp = dentry_open(dentry, mqueue_mnt, oflag);
-
- if (!IS_ERR(filp))
- dget(dentry);
-
- return filp;
+ return dentry_open(dentry, mqueue_mnt, oflag);
}
asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
@@ -670,17 +672,20 @@ asmlinkage long sys_mq_open(const char _
if (oflag & O_CREAT) {
if (dentry->d_inode) { /* entry already exists */
- filp = (oflag & O_EXCL) ? ERR_PTR(-EEXIST) :
- do_open(dentry, oflag);
+ error = -EEXIST;
+ if (oflag & O_EXCL)
+ goto out;
+ filp = do_open(dentry, oflag);
} else {
filp = do_create(mqueue_mnt->mnt_root, dentry,
oflag, mode, u_attr);
}
- } else
- filp = (dentry->d_inode) ? do_open(dentry, oflag) :
- ERR_PTR(-ENOENT);
-
- dput(dentry);
+ } else {
+ error = -ENOENT;
+ if (!dentry->d_inode)
+ goto out;
+ filp = do_open(dentry, oflag);
+ }
if (IS_ERR(filp)) {
error = PTR_ERR(filp);
@@ -691,8 +696,10 @@ asmlinkage long sys_mq_open(const char _
fd_install(fd, filp);
goto out_upsem;
-out_putfd:
+out:
+ dput(dentry);
mntput(mqueue_mnt);
+out_putfd:
put_unused_fd(fd);
out_err:
fd = error;
--
next prev parent reply other threads:[~2006-01-28 2:25 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20060128020629.908825000@press.kroah.org>
2006-01-28 2:20 ` [patch 00/12] 2.6.15.2 -stable review Greg KH
2006-01-28 2:20 ` [patch 01/12] usb-audio: don't use empty packets at start of playback Greg KH
2006-01-28 2:20 ` [patch 02/12] [BLOCK] Kill blk_attempt_remerge() Greg KH
2006-01-28 2:20 ` [patch 03/12] Input: HID - fix an oops in PID initialization code Greg KH
2006-01-28 2:20 ` Greg KH [this message]
2006-01-28 2:20 ` [patch 05/12] Fix oops in ufs_fill_super at mount time Greg KH
2006-01-28 2:21 ` [patch 06/12] elevator=as back-compatibility Greg KH
2006-01-28 19:19 ` Jens Axboe
2006-01-31 7:09 ` [stable] " Greg KH
2006-01-28 2:21 ` [patch 07/12] Fix timekeeping on sparc64 ultra-IIe machines Greg KH
2006-01-28 2:21 ` [patch 08/12] [NET]: Make second arg to skb_reserved() signed Greg KH
2006-01-28 2:21 ` [patch 09/12] Mask off GFP flags before swiotlb_alloc_coherent Greg KH
2006-01-28 2:33 ` Andi Kleen
2006-01-28 3:49 ` Andrew Morton
2006-01-28 6:04 ` Andi Kleen
2006-01-28 2:21 ` [patch 10/12] Someone broke reiserfs v3 mount options and this fixes it Greg KH
2006-01-28 2:21 ` [patch 11/12] Fix i2o_scsi oops on abort Greg KH
2006-01-28 2:21 ` [patch 12/12] Fix mkiss locking bug Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060128022052.GE17001@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=aviro@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rdunlap@xenotime.net \
--cc=stable@kernel.org \
--cc=torvalds@osdl.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.