diff options
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r-- | ipc/mqueue.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 15eabf9d51fd..3853116a2ef8 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -657,24 +657,28 @@ out: | |||
657 | static struct file *do_open(struct ipc_namespace *ipc_ns, | 657 | static struct file *do_open(struct ipc_namespace *ipc_ns, |
658 | struct dentry *dentry, int oflag) | 658 | struct dentry *dentry, int oflag) |
659 | { | 659 | { |
660 | int ret; | ||
660 | const struct cred *cred = current_cred(); | 661 | const struct cred *cred = current_cred(); |
661 | 662 | ||
662 | static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | 663 | static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, |
663 | MAY_READ | MAY_WRITE }; | 664 | MAY_READ | MAY_WRITE }; |
664 | 665 | ||
665 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { | 666 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { |
666 | dput(dentry); | 667 | ret = -EINVAL; |
667 | mntput(ipc_ns->mq_mnt); | 668 | goto err; |
668 | return ERR_PTR(-EINVAL); | ||
669 | } | 669 | } |
670 | 670 | ||
671 | if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { | 671 | if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { |
672 | dput(dentry); | 672 | ret = -EACCES; |
673 | mntput(ipc_ns->mq_mnt); | 673 | goto err; |
674 | return ERR_PTR(-EACCES); | ||
675 | } | 674 | } |
676 | 675 | ||
677 | return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); | 676 | return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); |
677 | |||
678 | err: | ||
679 | dput(dentry); | ||
680 | mntput(ipc_ns->mq_mnt); | ||
681 | return ERR_PTR(ret); | ||
678 | } | 682 | } |
679 | 683 | ||
680 | SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, | 684 | SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, |