aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index 9de48065c1ac..114a21189613 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -43,6 +43,23 @@
43#include <linux/uaccess.h> 43#include <linux/uaccess.h>
44#include "util.h" 44#include "util.h"
45 45
46/* one msq_queue structure for each present queue on the system */
47struct msg_queue {
48 struct kern_ipc_perm q_perm;
49 time64_t q_stime; /* last msgsnd time */
50 time64_t q_rtime; /* last msgrcv time */
51 time64_t q_ctime; /* last change time */
52 unsigned long q_cbytes; /* current number of bytes on queue */
53 unsigned long q_qnum; /* number of messages in queue */
54 unsigned long q_qbytes; /* max number of bytes on queue */
55 struct pid *q_lspid; /* pid of last msgsnd */
56 struct pid *q_lrpid; /* last receive pid */
57
58 struct list_head q_messages;
59 struct list_head q_receivers;
60 struct list_head q_senders;
61} __randomize_layout;
62
46/* one msg_receiver structure for each sleeping receiver */ 63/* one msg_receiver structure for each sleeping receiver */
47struct msg_receiver { 64struct msg_receiver {
48 struct list_head r_list; 65 struct list_head r_list;
@@ -101,7 +118,7 @@ static void msg_rcu_free(struct rcu_head *head)
101 struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu); 118 struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu);
102 struct msg_queue *msq = container_of(p, struct msg_queue, q_perm); 119 struct msg_queue *msq = container_of(p, struct msg_queue, q_perm);
103 120
104 security_msg_queue_free(msq); 121 security_msg_queue_free(&msq->q_perm);
105 kvfree(msq); 122 kvfree(msq);
106} 123}
107 124
@@ -127,7 +144,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
127 msq->q_perm.key = key; 144 msq->q_perm.key = key;
128 145
129 msq->q_perm.security = NULL; 146 msq->q_perm.security = NULL;
130 retval = security_msg_queue_alloc(msq); 147 retval = security_msg_queue_alloc(&msq->q_perm);
131 if (retval) { 148 if (retval) {
132 kvfree(msq); 149 kvfree(msq);
133 return retval; 150 return retval;
@@ -137,7 +154,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
137 msq->q_ctime = ktime_get_real_seconds(); 154 msq->q_ctime = ktime_get_real_seconds();
138 msq->q_cbytes = msq->q_qnum = 0; 155 msq->q_cbytes = msq->q_qnum = 0;
139 msq->q_qbytes = ns->msg_ctlmnb; 156 msq->q_qbytes = ns->msg_ctlmnb;
140 msq->q_lspid = msq->q_lrpid = 0; 157 msq->q_lspid = msq->q_lrpid = NULL;
141 INIT_LIST_HEAD(&msq->q_messages); 158 INIT_LIST_HEAD(&msq->q_messages);
142 INIT_LIST_HEAD(&msq->q_receivers); 159 INIT_LIST_HEAD(&msq->q_receivers);
143 INIT_LIST_HEAD(&msq->q_senders); 160 INIT_LIST_HEAD(&msq->q_senders);
@@ -250,25 +267,17 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
250 free_msg(msg); 267 free_msg(msg);
251 } 268 }
252 atomic_sub(msq->q_cbytes, &ns->msg_bytes); 269 atomic_sub(msq->q_cbytes, &ns->msg_bytes);
270 ipc_update_pid(&msq->q_lspid, NULL);
271 ipc_update_pid(&msq->q_lrpid, NULL);
253 ipc_rcu_putref(&msq->q_perm, msg_rcu_free); 272 ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
254} 273}
255 274
256/*
257 * Called with msg_ids.rwsem and ipcp locked.
258 */
259static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
260{
261 struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
262
263 return security_msg_queue_associate(msq, msgflg);
264}
265
266long ksys_msgget(key_t key, int msgflg) 275long ksys_msgget(key_t key, int msgflg)
267{ 276{
268 struct ipc_namespace *ns; 277 struct ipc_namespace *ns;
269 static const struct ipc_ops msg_ops = { 278 static const struct ipc_ops msg_ops = {
270 .getnew = newque, 279 .getnew = newque,
271 .associate = msg_security, 280 .associate = security_msg_queue_associate,
272 }; 281 };
273 struct ipc_params msg_params; 282 struct ipc_params msg_params;
274 283
@@ -385,7 +394,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
385 394
386 msq = container_of(ipcp, struct msg_queue, q_perm); 395 msq = container_of(ipcp, struct msg_queue, q_perm);
387 396
388 err = security_msg_queue_msgctl(msq, cmd); 397 err = security_msg_queue_msgctl(&msq->q_perm, cmd);
389 if (err) 398 if (err)
390 goto out_unlock1; 399 goto out_unlock1;
391 400
@@ -507,7 +516,7 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
507 if (ipcperms(ns, &msq->q_perm, S_IRUGO)) 516 if (ipcperms(ns, &msq->q_perm, S_IRUGO))
508 goto out_unlock; 517 goto out_unlock;
509 518
510 err = security_msg_queue_msgctl(msq, cmd); 519 err = security_msg_queue_msgctl(&msq->q_perm, cmd);
511 if (err) 520 if (err)
512 goto out_unlock; 521 goto out_unlock;
513 522
@@ -526,8 +535,8 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
526 p->msg_cbytes = msq->q_cbytes; 535 p->msg_cbytes = msq->q_cbytes;
527 p->msg_qnum = msq->q_qnum; 536 p->msg_qnum = msq->q_qnum;
528 p->msg_qbytes = msq->q_qbytes; 537 p->msg_qbytes = msq->q_qbytes;
529 p->msg_lspid = msq->q_lspid; 538 p->msg_lspid = pid_vnr(msq->q_lspid);
530 p->msg_lrpid = msq->q_lrpid; 539 p->msg_lrpid = pid_vnr(msq->q_lrpid);
531 540
532 ipc_unlock_object(&msq->q_perm); 541 ipc_unlock_object(&msq->q_perm);
533 rcu_read_unlock(); 542 rcu_read_unlock();
@@ -733,7 +742,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
733 742
734 list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { 743 list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
735 if (testmsg(msg, msr->r_msgtype, msr->r_mode) && 744 if (testmsg(msg, msr->r_msgtype, msr->r_mode) &&
736 !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, 745 !security_msg_queue_msgrcv(&msq->q_perm, msg, msr->r_tsk,
737 msr->r_msgtype, msr->r_mode)) { 746 msr->r_msgtype, msr->r_mode)) {
738 747
739 list_del(&msr->r_list); 748 list_del(&msr->r_list);
@@ -741,7 +750,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
741 wake_q_add(wake_q, msr->r_tsk); 750 wake_q_add(wake_q, msr->r_tsk);
742 WRITE_ONCE(msr->r_msg, ERR_PTR(-E2BIG)); 751 WRITE_ONCE(msr->r_msg, ERR_PTR(-E2BIG));
743 } else { 752 } else {
744 msq->q_lrpid = task_pid_vnr(msr->r_tsk); 753 ipc_update_pid(&msq->q_lrpid, task_pid(msr->r_tsk));
745 msq->q_rtime = get_seconds(); 754 msq->q_rtime = get_seconds();
746 755
747 wake_q_add(wake_q, msr->r_tsk); 756 wake_q_add(wake_q, msr->r_tsk);
@@ -799,7 +808,7 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
799 goto out_unlock0; 808 goto out_unlock0;
800 } 809 }
801 810
802 err = security_msg_queue_msgsnd(msq, msg, msgflg); 811 err = security_msg_queue_msgsnd(&msq->q_perm, msg, msgflg);
803 if (err) 812 if (err)
804 goto out_unlock0; 813 goto out_unlock0;
805 814
@@ -842,7 +851,7 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
842 851
843 } 852 }
844 853
845 msq->q_lspid = task_tgid_vnr(current); 854 ipc_update_pid(&msq->q_lspid, task_tgid(current));
846 msq->q_stime = get_seconds(); 855 msq->q_stime = get_seconds();
847 856
848 if (!pipelined_send(msq, msg, &wake_q)) { 857 if (!pipelined_send(msq, msg, &wake_q)) {
@@ -987,7 +996,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
987 996
988 list_for_each_entry(msg, &msq->q_messages, m_list) { 997 list_for_each_entry(msg, &msq->q_messages, m_list) {
989 if (testmsg(msg, *msgtyp, mode) && 998 if (testmsg(msg, *msgtyp, mode) &&
990 !security_msg_queue_msgrcv(msq, msg, current, 999 !security_msg_queue_msgrcv(&msq->q_perm, msg, current,
991 *msgtyp, mode)) { 1000 *msgtyp, mode)) {
992 if (mode == SEARCH_LESSEQUAL && msg->m_type != 1) { 1001 if (mode == SEARCH_LESSEQUAL && msg->m_type != 1) {
993 *msgtyp = msg->m_type - 1; 1002 *msgtyp = msg->m_type - 1;
@@ -1072,7 +1081,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
1072 list_del(&msg->m_list); 1081 list_del(&msg->m_list);
1073 msq->q_qnum--; 1082 msq->q_qnum--;
1074 msq->q_rtime = get_seconds(); 1083 msq->q_rtime = get_seconds();
1075 msq->q_lrpid = task_tgid_vnr(current); 1084 ipc_update_pid(&msq->q_lrpid, task_tgid(current));
1076 msq->q_cbytes -= msg->m_ts; 1085 msq->q_cbytes -= msg->m_ts;
1077 atomic_sub(msg->m_ts, &ns->msg_bytes); 1086 atomic_sub(msg->m_ts, &ns->msg_bytes);
1078 atomic_dec(&ns->msg_hdrs); 1087 atomic_dec(&ns->msg_hdrs);
@@ -1227,6 +1236,7 @@ void msg_exit_ns(struct ipc_namespace *ns)
1227#ifdef CONFIG_PROC_FS 1236#ifdef CONFIG_PROC_FS
1228static int sysvipc_msg_proc_show(struct seq_file *s, void *it) 1237static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
1229{ 1238{
1239 struct pid_namespace *pid_ns = ipc_seq_pid_ns(s);
1230 struct user_namespace *user_ns = seq_user_ns(s); 1240 struct user_namespace *user_ns = seq_user_ns(s);
1231 struct kern_ipc_perm *ipcp = it; 1241 struct kern_ipc_perm *ipcp = it;
1232 struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); 1242 struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
@@ -1238,8 +1248,8 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
1238 msq->q_perm.mode, 1248 msq->q_perm.mode,
1239 msq->q_cbytes, 1249 msq->q_cbytes,
1240 msq->q_qnum, 1250 msq->q_qnum,
1241 msq->q_lspid, 1251 pid_nr_ns(msq->q_lspid, pid_ns),
1242 msq->q_lrpid, 1252 pid_nr_ns(msq->q_lrpid, pid_ns),
1243 from_kuid_munged(user_ns, msq->q_perm.uid), 1253 from_kuid_munged(user_ns, msq->q_perm.uid),
1244 from_kgid_munged(user_ns, msq->q_perm.gid), 1254 from_kgid_munged(user_ns, msq->q_perm.gid),
1245 from_kuid_munged(user_ns, msq->q_perm.cuid), 1255 from_kuid_munged(user_ns, msq->q_perm.cuid),