Loading ipc/mqueue.c +21 −50 Original line number Diff line number Diff line Loading @@ -270,13 +270,30 @@ static struct inode *mqueue_get_inode(struct super_block *sb, * that means the min(mq_maxmsg, max_priorities) * struct * posix_msg_tree_node. */ ret = -EINVAL; if (info->attr.mq_maxmsg <= 0 || info->attr.mq_msgsize <= 0) goto out_inode; if (capable(CAP_SYS_RESOURCE)) { if (info->attr.mq_maxmsg > HARD_MSGMAX || info->attr.mq_msgsize > HARD_MSGSIZEMAX) goto out_inode; } else { if (info->attr.mq_maxmsg > ipc_ns->mq_msg_max || info->attr.mq_msgsize > ipc_ns->mq_msgsize_max) goto out_inode; } ret = -EOVERFLOW; /* check for overflow */ if (info->attr.mq_msgsize > ULONG_MAX/info->attr.mq_maxmsg) goto out_inode; mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) + min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) * sizeof(struct posix_msg_tree_node); mq_bytes = mq_treesize + (info->attr.mq_maxmsg * info->attr.mq_msgsize); mq_bytes = info->attr.mq_maxmsg * info->attr.mq_msgsize; if (mq_bytes + mq_treesize < mq_bytes) goto out_inode; mq_bytes += mq_treesize; spin_lock(&mq_lock); if (u->mq_bytes + mq_bytes < u->mq_bytes || u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) { Loading Loading @@ -696,34 +713,6 @@ static void remove_notification(struct mqueue_inode_info *info) info->notify_user_ns = NULL; } static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) { int mq_treesize; unsigned long total_size; if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) return -EINVAL; if (capable(CAP_SYS_RESOURCE)) { if (attr->mq_maxmsg > HARD_MSGMAX || attr->mq_msgsize > HARD_MSGSIZEMAX) return -EINVAL; } else { if (attr->mq_maxmsg > ipc_ns->mq_msg_max || attr->mq_msgsize > ipc_ns->mq_msgsize_max) return -EINVAL; } /* check for overflow */ if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg) return -EOVERFLOW; mq_treesize = attr->mq_maxmsg * sizeof(struct msg_msg) + min_t(unsigned int, attr->mq_maxmsg, MQ_PRIO_MAX) * sizeof(struct posix_msg_tree_node); total_size = attr->mq_maxmsg * attr->mq_msgsize; if (total_size + mq_treesize < total_size) return -EOVERFLOW; return 0; } /* * Invoked when creating a new queue via sys_mq_open */ Loading @@ -731,24 +720,6 @@ static int do_create(struct ipc_namespace *ipc_ns, struct inode *dir, struct path *path, int oflag, umode_t mode, struct mq_attr *attr) { int ret; if (attr) { ret = mq_attr_ok(ipc_ns, attr); if (ret) return ret; } else { struct mq_attr def_attr; def_attr.mq_maxmsg = min(ipc_ns->mq_msg_max, ipc_ns->mq_msg_default); def_attr.mq_msgsize = min(ipc_ns->mq_msgsize_max, ipc_ns->mq_msgsize_default); ret = mq_attr_ok(ipc_ns, &def_attr); if (ret) return ret; } return vfs_mkobj(path->dentry, mode & ~current_umask(), mqueue_create_attr, attr); } Loading Loading
ipc/mqueue.c +21 −50 Original line number Diff line number Diff line Loading @@ -270,13 +270,30 @@ static struct inode *mqueue_get_inode(struct super_block *sb, * that means the min(mq_maxmsg, max_priorities) * struct * posix_msg_tree_node. */ ret = -EINVAL; if (info->attr.mq_maxmsg <= 0 || info->attr.mq_msgsize <= 0) goto out_inode; if (capable(CAP_SYS_RESOURCE)) { if (info->attr.mq_maxmsg > HARD_MSGMAX || info->attr.mq_msgsize > HARD_MSGSIZEMAX) goto out_inode; } else { if (info->attr.mq_maxmsg > ipc_ns->mq_msg_max || info->attr.mq_msgsize > ipc_ns->mq_msgsize_max) goto out_inode; } ret = -EOVERFLOW; /* check for overflow */ if (info->attr.mq_msgsize > ULONG_MAX/info->attr.mq_maxmsg) goto out_inode; mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) + min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) * sizeof(struct posix_msg_tree_node); mq_bytes = mq_treesize + (info->attr.mq_maxmsg * info->attr.mq_msgsize); mq_bytes = info->attr.mq_maxmsg * info->attr.mq_msgsize; if (mq_bytes + mq_treesize < mq_bytes) goto out_inode; mq_bytes += mq_treesize; spin_lock(&mq_lock); if (u->mq_bytes + mq_bytes < u->mq_bytes || u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) { Loading Loading @@ -696,34 +713,6 @@ static void remove_notification(struct mqueue_inode_info *info) info->notify_user_ns = NULL; } static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) { int mq_treesize; unsigned long total_size; if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) return -EINVAL; if (capable(CAP_SYS_RESOURCE)) { if (attr->mq_maxmsg > HARD_MSGMAX || attr->mq_msgsize > HARD_MSGSIZEMAX) return -EINVAL; } else { if (attr->mq_maxmsg > ipc_ns->mq_msg_max || attr->mq_msgsize > ipc_ns->mq_msgsize_max) return -EINVAL; } /* check for overflow */ if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg) return -EOVERFLOW; mq_treesize = attr->mq_maxmsg * sizeof(struct msg_msg) + min_t(unsigned int, attr->mq_maxmsg, MQ_PRIO_MAX) * sizeof(struct posix_msg_tree_node); total_size = attr->mq_maxmsg * attr->mq_msgsize; if (total_size + mq_treesize < total_size) return -EOVERFLOW; return 0; } /* * Invoked when creating a new queue via sys_mq_open */ Loading @@ -731,24 +720,6 @@ static int do_create(struct ipc_namespace *ipc_ns, struct inode *dir, struct path *path, int oflag, umode_t mode, struct mq_attr *attr) { int ret; if (attr) { ret = mq_attr_ok(ipc_ns, attr); if (ret) return ret; } else { struct mq_attr def_attr; def_attr.mq_maxmsg = min(ipc_ns->mq_msg_max, ipc_ns->mq_msg_default); def_attr.mq_msgsize = min(ipc_ns->mq_msgsize_max, ipc_ns->mq_msgsize_default); ret = mq_attr_ok(ipc_ns, &def_attr); if (ret) return ret; } return vfs_mkobj(path->dentry, mode & ~current_umask(), mqueue_create_attr, attr); } Loading