aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/mqueue.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 076399ce363a..af1692556c52 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -680,26 +680,26 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
680 unsigned long total_size; 680 unsigned long total_size;
681 681
682 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) 682 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
683 return 0; 683 return -EINVAL;
684 if (capable(CAP_SYS_RESOURCE)) { 684 if (capable(CAP_SYS_RESOURCE)) {
685 if (attr->mq_maxmsg > HARD_MSGMAX || 685 if (attr->mq_maxmsg > HARD_MSGMAX ||
686 attr->mq_msgsize > HARD_MSGSIZEMAX) 686 attr->mq_msgsize > HARD_MSGSIZEMAX)
687 return 0; 687 return -EINVAL;
688 } else { 688 } else {
689 if (attr->mq_maxmsg > ipc_ns->mq_msg_max || 689 if (attr->mq_maxmsg > ipc_ns->mq_msg_max ||
690 attr->mq_msgsize > ipc_ns->mq_msgsize_max) 690 attr->mq_msgsize > ipc_ns->mq_msgsize_max)
691 return 0; 691 return -EINVAL;
692 } 692 }
693 /* check for overflow */ 693 /* check for overflow */
694 if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg) 694 if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
695 return 0; 695 return -EOVERFLOW;
696 mq_treesize = attr->mq_maxmsg * sizeof(struct msg_msg) + 696 mq_treesize = attr->mq_maxmsg * sizeof(struct msg_msg) +
697 min_t(unsigned int, attr->mq_maxmsg, MQ_PRIO_MAX) * 697 min_t(unsigned int, attr->mq_maxmsg, MQ_PRIO_MAX) *
698 sizeof(struct posix_msg_tree_node); 698 sizeof(struct posix_msg_tree_node);
699 total_size = attr->mq_maxmsg * attr->mq_msgsize; 699 total_size = attr->mq_maxmsg * attr->mq_msgsize;
700 if (total_size + mq_treesize < total_size) 700 if (total_size + mq_treesize < total_size)
701 return 0; 701 return -EOVERFLOW;
702 return 1; 702 return 0;
703} 703}
704 704
705/* 705/*
@@ -714,12 +714,21 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
714 int ret; 714 int ret;
715 715
716 if (attr) { 716 if (attr) {
717 if (!mq_attr_ok(ipc_ns, attr)) { 717 ret = mq_attr_ok(ipc_ns, attr);
718 ret = -EINVAL; 718 if (ret)
719 goto out; 719 goto out;
720 }
721 /* store for use during create */ 720 /* store for use during create */
722 dentry->d_fsdata = attr; 721 dentry->d_fsdata = attr;
722 } else {
723 struct mq_attr def_attr;
724
725 def_attr.mq_maxmsg = min(ipc_ns->mq_msg_max,
726 ipc_ns->mq_msg_default);
727 def_attr.mq_msgsize = min(ipc_ns->mq_msgsize_max,
728 ipc_ns->mq_msgsize_default);
729 ret = mq_attr_ok(ipc_ns, &def_attr);
730 if (ret)
731 goto out;
723 } 732 }
724 733
725 mode &= ~current_umask(); 734 mode &= ~current_umask();