diff options
| author | Chris Wright <chrisw@osdl.org> | 2004-06-17 17:57:18 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-17 17:57:18 -0700 |
| commit | b1cae1ec2c69ab3ca6ad80a86e16d9a87b12daed (patch) | |
| tree | 53981f47917ad6747779c8058f0b6e4835f6ac59 | |
| parent | 9d9f6e8b61400f3292be2a85b6aa84d3e47a60c8 (diff) | |
[PATCH] RLIM: add mq_attr_ok() helper
Add helper function mq_attr_ok() to do mq_attr sanity checking, and do some
extra overlow checking.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | ipc/mqueue.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 40a8d414e3ba..a88fc89eaa1c 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -534,6 +534,28 @@ static void remove_notification(struct mqueue_inode_info *info) info->notify_owner = 0; } +static int mq_attr_ok(struct mq_attr *attr) +{ + if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) + return 0; + if (capable(CAP_SYS_RESOURCE)) { + if (attr->mq_maxmsg > HARD_MSGMAX) + return 0; + } else { + if (attr->mq_maxmsg > msg_max || + attr->mq_msgsize > msgsize_max) + return 0; + } + /* check for overflow */ + if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg) + return 0; + if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) + + (attr->mq_maxmsg * sizeof (struct msg_msg *)) < + (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize)) + return 0; + return 1; +} + /* * Invoked when creating a new queue via sys_mq_open */ @@ -547,17 +569,8 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, if (u_attr != NULL) { if (copy_from_user(&attr, u_attr, sizeof(attr))) return ERR_PTR(-EFAULT); - - if (attr.mq_maxmsg <= 0 || attr.mq_msgsize <= 0) + if (!mq_attr_ok(&attr)) return ERR_PTR(-EINVAL); - if (capable(CAP_SYS_RESOURCE)) { - if (attr.mq_maxmsg > HARD_MSGMAX) - return ERR_PTR(-EINVAL); - } else { - if (attr.mq_maxmsg > msg_max || - attr.mq_msgsize > msgsize_max) - return ERR_PTR(-EINVAL); - } /* store for use during create */ dentry->d_fsdata = &attr; } |
