aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/mqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r--ipc/mqueue.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 3853116a2ef8..547d9c8631f5 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -184,7 +184,7 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
184{ 184{
185 struct inode *inode; 185 struct inode *inode;
186 struct ipc_namespace *ns = data; 186 struct ipc_namespace *ns = data;
187 int error = 0; 187 int error;
188 188
189 sb->s_blocksize = PAGE_CACHE_SIZE; 189 sb->s_blocksize = PAGE_CACHE_SIZE;
190 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 190 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -202,7 +202,9 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
202 if (!sb->s_root) { 202 if (!sb->s_root) {
203 iput(inode); 203 iput(inode);
204 error = -ENOMEM; 204 error = -ENOMEM;
205 goto out;
205 } 206 }
207 error = 0;
206 208
207out: 209out:
208 return error; 210 return error;
@@ -621,9 +623,10 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
621 int ret; 623 int ret;
622 624
623 if (attr) { 625 if (attr) {
624 ret = -EINVAL; 626 if (!mq_attr_ok(ipc_ns, attr)) {
625 if (!mq_attr_ok(ipc_ns, attr)) 627 ret = -EINVAL;
626 goto out; 628 goto out;
629 }
627 /* store for use during create */ 630 /* store for use during create */
628 dentry->d_fsdata = attr; 631 dentry->d_fsdata = attr;
629 } 632 }
@@ -714,9 +717,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
714 if (oflag & O_CREAT) { 717 if (oflag & O_CREAT) {
715 if (dentry->d_inode) { /* entry already exists */ 718 if (dentry->d_inode) { /* entry already exists */
716 audit_inode(name, dentry); 719 audit_inode(name, dentry);
717 error = -EEXIST; 720 if (oflag & O_EXCL) {
718 if (oflag & O_EXCL) 721 error = -EEXIST;
719 goto out; 722 goto out;
723 }
720 filp = do_open(ipc_ns, dentry, oflag); 724 filp = do_open(ipc_ns, dentry, oflag);
721 } else { 725 } else {
722 filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root, 726 filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
@@ -724,9 +728,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
724 u_attr ? &attr : NULL); 728 u_attr ? &attr : NULL);
725 } 729 }
726 } else { 730 } else {
727 error = -ENOENT; 731 if (!dentry->d_inode) {
728 if (!dentry->d_inode) 732 error = -ENOENT;
729 goto out; 733 goto out;
734 }
730 audit_inode(name, dentry); 735 audit_inode(name, dentry);
731 filp = do_open(ipc_ns, dentry, oflag); 736 filp = do_open(ipc_ns, dentry, oflag);
732 } 737 }
@@ -873,19 +878,24 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
873 audit_mq_sendrecv(mqdes, msg_len, msg_prio, p); 878 audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
874 timeout = prepare_timeout(p); 879 timeout = prepare_timeout(p);
875 880
876 ret = -EBADF;
877 filp = fget(mqdes); 881 filp = fget(mqdes);
878 if (unlikely(!filp)) 882 if (unlikely(!filp)) {
883 ret = -EBADF;
879 goto out; 884 goto out;
885 }
880 886
881 inode = filp->f_path.dentry->d_inode; 887 inode = filp->f_path.dentry->d_inode;
882 if (unlikely(filp->f_op != &mqueue_file_operations)) 888 if (unlikely(filp->f_op != &mqueue_file_operations)) {
889 ret = -EBADF;
883 goto out_fput; 890 goto out_fput;
891 }
884 info = MQUEUE_I(inode); 892 info = MQUEUE_I(inode);
885 audit_inode(NULL, filp->f_path.dentry); 893 audit_inode(NULL, filp->f_path.dentry);
886 894
887 if (unlikely(!(filp->f_mode & FMODE_WRITE))) 895 if (unlikely(!(filp->f_mode & FMODE_WRITE))) {
896 ret = -EBADF;
888 goto out_fput; 897 goto out_fput;
898 }
889 899
890 if (unlikely(msg_len > info->attr.mq_msgsize)) { 900 if (unlikely(msg_len > info->attr.mq_msgsize)) {
891 ret = -EMSGSIZE; 901 ret = -EMSGSIZE;
@@ -962,19 +972,24 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
962 audit_mq_sendrecv(mqdes, msg_len, 0, p); 972 audit_mq_sendrecv(mqdes, msg_len, 0, p);
963 timeout = prepare_timeout(p); 973 timeout = prepare_timeout(p);
964 974
965 ret = -EBADF;
966 filp = fget(mqdes); 975 filp = fget(mqdes);
967 if (unlikely(!filp)) 976 if (unlikely(!filp)) {
977 ret = -EBADF;
968 goto out; 978 goto out;
979 }
969 980
970 inode = filp->f_path.dentry->d_inode; 981 inode = filp->f_path.dentry->d_inode;
971 if (unlikely(filp->f_op != &mqueue_file_operations)) 982 if (unlikely(filp->f_op != &mqueue_file_operations)) {
983 ret = -EBADF;
972 goto out_fput; 984 goto out_fput;
985 }
973 info = MQUEUE_I(inode); 986 info = MQUEUE_I(inode);
974 audit_inode(NULL, filp->f_path.dentry); 987 audit_inode(NULL, filp->f_path.dentry);
975 988
976 if (unlikely(!(filp->f_mode & FMODE_READ))) 989 if (unlikely(!(filp->f_mode & FMODE_READ))) {
990 ret = -EBADF;
977 goto out_fput; 991 goto out_fput;
992 }
978 993
979 /* checks if buffer is big enough */ 994 /* checks if buffer is big enough */
980 if (unlikely(msg_len < info->attr.mq_msgsize)) { 995 if (unlikely(msg_len < info->attr.mq_msgsize)) {
@@ -1064,13 +1079,14 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
1064 1079
1065 /* create the notify skb */ 1080 /* create the notify skb */
1066 nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL); 1081 nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
1067 ret = -ENOMEM; 1082 if (!nc) {
1068 if (!nc) 1083 ret = -ENOMEM;
1069 goto out; 1084 goto out;
1070 ret = -EFAULT; 1085 }
1071 if (copy_from_user(nc->data, 1086 if (copy_from_user(nc->data,
1072 notification.sigev_value.sival_ptr, 1087 notification.sigev_value.sival_ptr,
1073 NOTIFY_COOKIE_LEN)) { 1088 NOTIFY_COOKIE_LEN)) {
1089 ret = -EFAULT;
1074 goto out; 1090 goto out;
1075 } 1091 }
1076 1092
@@ -1079,9 +1095,10 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
1079 /* and attach it to the socket */ 1095 /* and attach it to the socket */
1080retry: 1096retry:
1081 filp = fget(notification.sigev_signo); 1097 filp = fget(notification.sigev_signo);
1082 ret = -EBADF; 1098 if (!filp) {
1083 if (!filp) 1099 ret = -EBADF;
1084 goto out; 1100 goto out;
1101 }
1085 sock = netlink_getsockbyfilp(filp); 1102 sock = netlink_getsockbyfilp(filp);
1086 fput(filp); 1103 fput(filp);
1087 if (IS_ERR(sock)) { 1104 if (IS_ERR(sock)) {
@@ -1093,7 +1110,7 @@ retry:
1093 timeo = MAX_SCHEDULE_TIMEOUT; 1110 timeo = MAX_SCHEDULE_TIMEOUT;
1094 ret = netlink_attachskb(sock, nc, &timeo, NULL); 1111 ret = netlink_attachskb(sock, nc, &timeo, NULL);
1095 if (ret == 1) 1112 if (ret == 1)
1096 goto retry; 1113 goto retry;
1097 if (ret) { 1114 if (ret) {
1098 sock = NULL; 1115 sock = NULL;
1099 nc = NULL; 1116 nc = NULL;
@@ -1102,14 +1119,17 @@ retry:
1102 } 1119 }
1103 } 1120 }
1104 1121
1105 ret = -EBADF;
1106 filp = fget(mqdes); 1122 filp = fget(mqdes);
1107 if (!filp) 1123 if (!filp) {
1124 ret = -EBADF;
1108 goto out; 1125 goto out;
1126 }
1109 1127
1110 inode = filp->f_path.dentry->d_inode; 1128 inode = filp->f_path.dentry->d_inode;
1111 if (unlikely(filp->f_op != &mqueue_file_operations)) 1129 if (unlikely(filp->f_op != &mqueue_file_operations)) {
1130 ret = -EBADF;
1112 goto out_fput; 1131 goto out_fput;
1132 }
1113 info = MQUEUE_I(inode); 1133 info = MQUEUE_I(inode);
1114 1134
1115 ret = 0; 1135 ret = 0;
@@ -1172,14 +1192,17 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
1172 return -EINVAL; 1192 return -EINVAL;
1173 } 1193 }
1174 1194
1175 ret = -EBADF;
1176 filp = fget(mqdes); 1195 filp = fget(mqdes);
1177 if (!filp) 1196 if (!filp) {
1197 ret = -EBADF;
1178 goto out; 1198 goto out;
1199 }
1179 1200
1180 inode = filp->f_path.dentry->d_inode; 1201 inode = filp->f_path.dentry->d_inode;
1181 if (unlikely(filp->f_op != &mqueue_file_operations)) 1202 if (unlikely(filp->f_op != &mqueue_file_operations)) {
1203 ret = -EBADF;
1182 goto out_fput; 1204 goto out_fput;
1205 }
1183 info = MQUEUE_I(inode); 1206 info = MQUEUE_I(inode);
1184 1207
1185 spin_lock(&info->lock); 1208 spin_lock(&info->lock);