if (allowed < MSGMNI) {
ns->msg_ctlmni = MSGMNI;
- goto out_callback;
+ return;
}
if (allowed > IPCMNI / nb_ns) {
ns->msg_ctlmni = IPCMNI / nb_ns;
- goto out_callback;
+ return;
}
ns->msg_ctlmni = allowed;
-
-out_callback:
-
- printk(KERN_INFO "msgmni has been set to %d for ipc namespace %p\n",
- ns->msg_ctlmni, ns);
}
void msg_init_ns(struct ipc_namespace *ns)
void __init msg_init(void)
{
msg_init_ns(&init_ipc_ns);
+
+ printk(KERN_INFO "msgmni has been set to %d\n",
+ init_ipc_ns.msg_ctlmni);
+
ipc_init_proc_interface("sysvipc/msg",
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
IPC_MSG_IDS, sysvipc_msg_proc_show);
}
-/*
- * This routine is called in the paths where the rw_mutex is held to protect
- * access to the idr tree.
- */
-static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns,
- int id)
-{
- struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id);
-
- if (IS_ERR(ipcp))
- return (struct msg_queue *)ipcp;
-
- return container_of(ipcp, struct msg_queue, q_perm);
-}
-
/*
* msg_lock_(check_) routines are called in the paths where the rw_mutex
* is not held.
out.msg_rtime = in->msg_rtime;
out.msg_ctime = in->msg_ctime;
- if (in->msg_cbytes > USHRT_MAX)
- out.msg_cbytes = USHRT_MAX;
+ if (in->msg_cbytes > USHORT_MAX)
+ out.msg_cbytes = USHORT_MAX;
else
out.msg_cbytes = in->msg_cbytes;
out.msg_lcbytes = in->msg_cbytes;
- if (in->msg_qnum > USHRT_MAX)
- out.msg_qnum = USHRT_MAX;
+ if (in->msg_qnum > USHORT_MAX)
+ out.msg_qnum = USHORT_MAX;
else
out.msg_qnum = in->msg_qnum;
- if (in->msg_qbytes > USHRT_MAX)
- out.msg_qbytes = USHRT_MAX;
+ if (in->msg_qbytes > USHORT_MAX)
+ out.msg_qbytes = USHORT_MAX;
else
out.msg_qbytes = in->msg_qbytes;
out.msg_lqbytes = in->msg_qbytes;
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
- msq = msg_lock_check_down(ns, msqid);
- if (IS_ERR(msq)) {
- err = PTR_ERR(msq);
- goto out_up;
- }
-
- ipcp = &msq->q_perm;
-
- err = audit_ipc_obj(ipcp);
- if (err)
- goto out_unlock;
-
- if (cmd == IPC_SET) {
- err = audit_ipc_set_perm(msqid64.msg_qbytes,
- msqid64.msg_perm.uid,
- msqid64.msg_perm.gid,
- msqid64.msg_perm.mode);
- if (err)
- goto out_unlock;
- }
+ ipcp = ipcctl_pre_down(&msg_ids(ns), msqid, cmd,
+ &msqid64.msg_perm, msqid64.msg_qbytes);
+ if (IS_ERR(ipcp))
+ return PTR_ERR(ipcp);
- if (current->euid != ipcp->cuid &&
- current->euid != ipcp->uid &&
- !capable(CAP_SYS_ADMIN)) {
- /* We _could_ check for CAP_CHOWN above, but we don't */
- err = -EPERM;
- goto out_unlock;
- }
+ msq = container_of(ipcp, struct msg_queue, q_perm);
err = security_msg_queue_msgctl(msq, cmd);
if (err)
msq->q_qbytes = msqid64.msg_qbytes;
- ipcp->uid = msqid64.msg_perm.uid;
- ipcp->gid = msqid64.msg_perm.gid;
- ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
- (S_IRWXUGO & msqid64.msg_perm.mode);
+ ipc_update_perm(&msqid64.msg_perm, ipcp);
msq->q_ctime = get_seconds();
/* sleeping receivers might be excluded by
* stricter permissions.