^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/ipc/msg.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1992 Krishna Balasubramanian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Removed all the remaining kerneld mess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Catch the -EFAULT stuff properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Use GFP_KERNEL for messages as in 1.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Fixed up the unchecked user space derefs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1998 Alan Cox & Andi Kleen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * /proc/sysvipc/msg support (c) 1999 Dragos Acostachioaie <dragos@iname.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * mostly rewritten, threaded and wake-one semantics added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MSGMAX limit removed, sysctl's added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * (c) 1999 Manfred Spraul <manfred@colorfullife.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * support for audit of ipc object properties and permission changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Dustin Kirkland <dustin.kirkland@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * namespaces support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * OpenVZ, SWsoft Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Pavel Emelianov <xemul@openvz.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/msg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/sched/wake_q.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/nsproxy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/ipc_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/rhashtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/current.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* one msq_queue structure for each present queue on the system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct msg_queue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct kern_ipc_perm q_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) time64_t q_stime; /* last msgsnd time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) time64_t q_rtime; /* last msgrcv time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) time64_t q_ctime; /* last change time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long q_cbytes; /* current number of bytes on queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long q_qnum; /* number of messages in queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long q_qbytes; /* max number of bytes on queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct pid *q_lspid; /* pid of last msgsnd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct pid *q_lrpid; /* last receive pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct list_head q_messages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct list_head q_receivers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct list_head q_senders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } __randomize_layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * MSG_BARRIER Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Similar to the optimization used in ipc/mqueue.c, one syscall return path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * does not acquire any locks when it sees that a message exists in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * msg_receiver.r_msg. Therefore r_msg is set using smp_store_release()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * and accessed using READ_ONCE()+smp_acquire__after_ctrl_dep(). In addition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * wake_q_add_safe() is used. See ipc/mqueue.c for more details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* one msg_receiver structure for each sleeping receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct msg_receiver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct list_head r_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct task_struct *r_tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int r_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) long r_msgtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) long r_maxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct msg_msg *r_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* one msg_sender for each sleeping sender */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct msg_sender {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct task_struct *tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) size_t msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SEARCH_ANY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SEARCH_EQUAL 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SEARCH_NOTEQUAL 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SEARCH_LESSEQUAL 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SEARCH_NUMBER 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct kern_ipc_perm *ipcp = ipc_obtain_object_idr(&msg_ids(ns), id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (IS_ERR(ipcp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ERR_CAST(ipcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return container_of(ipcp, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline struct msg_queue *msq_obtain_object_check(struct ipc_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&msg_ids(ns), id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (IS_ERR(ipcp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ERR_CAST(ipcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return container_of(ipcp, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ipc_rmid(&msg_ids(ns), &s->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void msg_rcu_free(struct rcu_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct msg_queue *msq = container_of(p, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) security_msg_queue_free(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kvfree(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * newque - Create a new msg queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @ns: namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @params: ptr to the structure that contains the key and msgflg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Called with msg_ids.rwsem held (writer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int newque(struct ipc_namespace *ns, struct ipc_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct msg_queue *msq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) key_t key = params->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int msgflg = params->flg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) msq = kvmalloc(sizeof(*msq), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (unlikely(!msq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) msq->q_perm.mode = msgflg & S_IRWXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) msq->q_perm.key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) msq->q_perm.security = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) retval = security_msg_queue_alloc(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kvfree(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) msq->q_stime = msq->q_rtime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) msq->q_ctime = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) msq->q_cbytes = msq->q_qnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) msq->q_qbytes = ns->msg_ctlmnb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) msq->q_lspid = msq->q_lrpid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) INIT_LIST_HEAD(&msq->q_messages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) INIT_LIST_HEAD(&msq->q_receivers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) INIT_LIST_HEAD(&msq->q_senders);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* ipc_addid() locks msq upon success. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) retval = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return msq->q_perm.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static inline bool msg_fits_inqueue(struct msg_queue *msq, size_t msgsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return msgsz + msq->q_cbytes <= msq->q_qbytes &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 1 + msq->q_qnum <= msq->q_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static inline void ss_add(struct msg_queue *msq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct msg_sender *mss, size_t msgsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mss->tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mss->msgsz = msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * No memory barrier required: we did ipc_lock_object(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * and the waker obtains that lock before calling wake_q_add().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) list_add_tail(&mss->list, &msq->q_senders);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static inline void ss_del(struct msg_sender *mss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (mss->list.next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) list_del(&mss->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void ss_wakeup(struct msg_queue *msq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct wake_q_head *wake_q, bool kill)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct msg_sender *mss, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct task_struct *stop_tsk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct list_head *h = &msq->q_senders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) list_for_each_entry_safe(mss, t, h, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (kill)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mss->list.next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * Stop at the first task we don't wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * we've already iterated the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * sender queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) else if (stop_tsk == mss->tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * We are not in an EIDRM scenario here, therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * verify that we really need to wakeup the task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * To maintain current semantics and wakeup order,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * move the sender to the tail on behalf of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * blocked task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else if (!msg_fits_inqueue(msq, mss->msgsz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (!stop_tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) stop_tsk = mss->tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) list_move_tail(&mss->list, &msq->q_senders);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) wake_q_add(wake_q, mss->tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static void expunge_all(struct msg_queue *msq, int res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct wake_q_head *wake_q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct msg_receiver *msr, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct task_struct *r_tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) r_tsk = get_task_struct(msr->r_tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* see MSG_BARRIER for purpose/pairing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) smp_store_release(&msr->r_msg, ERR_PTR(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) wake_q_add_safe(wake_q, r_tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * freeque() wakes up waiters on the sender and receiver waiting queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * removes the message queue from message queue ID IDR, and cleans up all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * messages associated with this queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * msg_ids.rwsem (writer) and the spinlock for this message queue are held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * before freeque() is called. msg_ids.rwsem remains locked on exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) __releases(RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __releases(&msq->q_perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct msg_msg *msg, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) DEFINE_WAKE_Q(wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) expunge_all(msq, -EIDRM, &wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ss_wakeup(msq, &wake_q, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) msg_rmid(ns, msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) wake_up_q(&wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) atomic_dec(&ns->msg_hdrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) free_msg(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) atomic_sub(msq->q_cbytes, &ns->msg_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ipc_update_pid(&msq->q_lspid, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ipc_update_pid(&msq->q_lrpid, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) long ksys_msgget(key_t key, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct ipc_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static const struct ipc_ops msg_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .getnew = newque,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .associate = security_msg_queue_associate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct ipc_params msg_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ns = current->nsproxy->ipc_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) msg_params.key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) msg_params.flg = msgflg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ksys_msgget(key, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) switch (version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case IPC_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return copy_to_user(buf, in, sizeof(*in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case IPC_OLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct msqid_ds out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) memset(&out, 0, sizeof(out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ipc64_perm_to_ipc_perm(&in->msg_perm, &out.msg_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) out.msg_stime = in->msg_stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) out.msg_rtime = in->msg_rtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) out.msg_ctime = in->msg_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (in->msg_cbytes > USHRT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) out.msg_cbytes = USHRT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) out.msg_cbytes = in->msg_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) out.msg_lcbytes = in->msg_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (in->msg_qnum > USHRT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) out.msg_qnum = USHRT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) out.msg_qnum = in->msg_qnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (in->msg_qbytes > USHRT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) out.msg_qbytes = USHRT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) out.msg_qbytes = in->msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) out.msg_lqbytes = in->msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) out.msg_lspid = in->msg_lspid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) out.msg_lrpid = in->msg_lrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return copy_to_user(buf, &out, sizeof(out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) switch (version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case IPC_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (copy_from_user(out, buf, sizeof(*out)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case IPC_OLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct msqid_ds tbuf_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) out->msg_perm.uid = tbuf_old.msg_perm.uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) out->msg_perm.gid = tbuf_old.msg_perm.gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) out->msg_perm.mode = tbuf_old.msg_perm.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (tbuf_old.msg_qbytes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) out->msg_qbytes = tbuf_old.msg_lqbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) out->msg_qbytes = tbuf_old.msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * This function handles some msgctl commands which require the rwsem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * to be held in write mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * NOTE: no locks must be held, the rwsem is taken inside this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct ipc64_perm *perm, int msg_qbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct kern_ipc_perm *ipcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct msg_queue *msq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) down_write(&msg_ids(ns).rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) perm, msg_qbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (IS_ERR(ipcp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) err = PTR_ERR(ipcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) msq = container_of(ipcp, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) err = security_msg_queue_msgctl(&msq->q_perm, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case IPC_RMID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* freeque unlocks the ipc object and rcu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) freeque(ns, ipcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto out_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case IPC_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) DEFINE_WAKE_Q(wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (msg_qbytes > ns->msg_ctlmnb &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) !capable(CAP_SYS_RESOURCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err = ipc_update_perm(perm, ipcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) msq->q_qbytes = msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) msq->q_ctime = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Sleeping receivers might be excluded by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * stricter permissions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) expunge_all(msq, -EAGAIN, &wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * Sleeping senders might be able to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * due to a larger queue size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ss_wakeup(msq, &wake_q, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) wake_up_q(&wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) out_unlock0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) out_unlock1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) out_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) up_write(&msg_ids(ns).rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int msgctl_info(struct ipc_namespace *ns, int msqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int cmd, struct msginfo *msginfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * We must not return kernel stack data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * due to padding, it's not enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * to set all member fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) err = security_msg_queue_msgctl(NULL, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) memset(msginfo, 0, sizeof(*msginfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) msginfo->msgmni = ns->msg_ctlmni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) msginfo->msgmax = ns->msg_ctlmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) msginfo->msgmnb = ns->msg_ctlmnb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) msginfo->msgssz = MSGSSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) msginfo->msgseg = MSGSEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) down_read(&msg_ids(ns).rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (cmd == MSG_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) msginfo->msgpool = msg_ids(ns).in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) msginfo->msgmap = atomic_read(&ns->msg_hdrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) msginfo->msgtql = atomic_read(&ns->msg_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) msginfo->msgmap = MSGMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) msginfo->msgpool = MSGPOOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) msginfo->msgtql = MSGTQL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) max_idx = ipc_get_maxidx(&msg_ids(ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) up_read(&msg_ids(ns).rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return (max_idx < 0) ? 0 : max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int msgctl_stat(struct ipc_namespace *ns, int msqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int cmd, struct msqid64_ds *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct msg_queue *msq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) memset(p, 0, sizeof(*p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (cmd == MSG_STAT || cmd == MSG_STAT_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) msq = msq_obtain_object(ns, msqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (IS_ERR(msq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) err = PTR_ERR(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) } else { /* IPC_STAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) msq = msq_obtain_object_check(ns, msqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (IS_ERR(msq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) err = PTR_ERR(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* see comment for SHM_STAT_ANY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (cmd == MSG_STAT_ANY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) audit_ipc_obj(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (ipcperms(ns, &msq->q_perm, S_IRUGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err = security_msg_queue_msgctl(&msq->q_perm, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!ipc_valid_object(&msq->q_perm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) err = -EIDRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) p->msg_stime = msq->q_stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) p->msg_rtime = msq->q_rtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) p->msg_ctime = msq->q_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #ifndef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) p->msg_stime_high = msq->q_stime >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) p->msg_rtime_high = msq->q_rtime >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) p->msg_ctime_high = msq->q_ctime >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) p->msg_cbytes = msq->q_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) p->msg_qnum = msq->q_qnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) p->msg_qbytes = msq->q_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) p->msg_lspid = pid_vnr(msq->q_lspid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) p->msg_lrpid = pid_vnr(msq->q_lrpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (cmd == IPC_STAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * As defined in SUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * Return 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * MSG_STAT and MSG_STAT_ANY (both Linux specific)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * Return the full id, including the sequence number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) err = msq->q_perm.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf, int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct ipc_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct msqid64_ds msqid64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (msqid < 0 || cmd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ns = current->nsproxy->ipc_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case IPC_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) case MSG_INFO: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct msginfo msginfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) err = msgctl_info(ns, msqid, cmd, &msginfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case MSG_STAT: /* msqid is an index rather than a msg queue id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case MSG_STAT_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case IPC_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) err = msgctl_stat(ns, msqid, cmd, &msqid64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (copy_msqid_to_user(buf, &msqid64, version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case IPC_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (copy_msqid_from_user(&msqid64, buf, version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) msqid64.msg_qbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case IPC_RMID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return msgctl_down(ns, msqid, cmd, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return ksys_msgctl(msqid, cmd, buf, IPC_64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int version = ipc_parse_version(&cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return ksys_msgctl(msqid, cmd, buf, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return ksys_old_msgctl(msqid, cmd, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct compat_msqid_ds {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct compat_ipc_perm msg_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) compat_uptr_t msg_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) compat_uptr_t msg_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) old_time32_t msg_stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) old_time32_t msg_rtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) old_time32_t msg_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) compat_ulong_t msg_lcbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) compat_ulong_t msg_lqbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned short msg_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned short msg_qnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) unsigned short msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) compat_ipc_pid_t msg_lspid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) compat_ipc_pid_t msg_lrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) memset(out, 0, sizeof(*out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (version == IPC_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct compat_msqid64_ds __user *p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (get_compat_ipc64_perm(&out->msg_perm, &p->msg_perm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (get_user(out->msg_qbytes, &p->msg_qbytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct compat_msqid_ds __user *p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (get_compat_ipc_perm(&out->msg_perm, &p->msg_perm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (get_user(out->msg_qbytes, &p->msg_qbytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (version == IPC_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct compat_msqid64_ds v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) memset(&v, 0, sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) to_compat_ipc64_perm(&v.msg_perm, &in->msg_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) v.msg_stime = lower_32_bits(in->msg_stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) v.msg_stime_high = upper_32_bits(in->msg_stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) v.msg_rtime = lower_32_bits(in->msg_rtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) v.msg_rtime_high = upper_32_bits(in->msg_rtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) v.msg_ctime = lower_32_bits(in->msg_ctime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) v.msg_ctime_high = upper_32_bits(in->msg_ctime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) v.msg_cbytes = in->msg_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) v.msg_qnum = in->msg_qnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) v.msg_qbytes = in->msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) v.msg_lspid = in->msg_lspid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) v.msg_lrpid = in->msg_lrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return copy_to_user(buf, &v, sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct compat_msqid_ds v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) memset(&v, 0, sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) to_compat_ipc_perm(&v.msg_perm, &in->msg_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) v.msg_stime = in->msg_stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) v.msg_rtime = in->msg_rtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) v.msg_ctime = in->msg_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) v.msg_cbytes = in->msg_cbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) v.msg_qnum = in->msg_qnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) v.msg_qbytes = in->msg_qbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) v.msg_lspid = in->msg_lspid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) v.msg_lrpid = in->msg_lrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return copy_to_user(buf, &v, sizeof(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr, int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct ipc_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct msqid64_ds msqid64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ns = current->nsproxy->ipc_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (msqid < 0 || cmd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) switch (cmd & (~IPC_64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case IPC_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) case MSG_INFO: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct msginfo msginfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err = msgctl_info(ns, msqid, cmd, &msginfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (copy_to_user(uptr, &msginfo, sizeof(struct msginfo)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case IPC_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) case MSG_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case MSG_STAT_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) err = msgctl_stat(ns, msqid, cmd, &msqid64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (copy_compat_msqid_to_user(uptr, &msqid64, version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) case IPC_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (copy_compat_msqid_from_user(&msqid64, uptr, version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm, msqid64.msg_qbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case IPC_RMID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return msgctl_down(ns, msqid, cmd, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return compat_ksys_msgctl(msqid, cmd, uptr, IPC_64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int version = compat_ipc_parse_version(&cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return compat_ksys_msgctl(msqid, cmd, uptr, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) COMPAT_SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, void __user *, uptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return compat_ksys_old_msgctl(msqid, cmd, uptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) static int testmsg(struct msg_msg *msg, long type, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case SEARCH_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case SEARCH_NUMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case SEARCH_LESSEQUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (msg->m_type <= type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case SEARCH_EQUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (msg->m_type == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) case SEARCH_NOTEQUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (msg->m_type != type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct wake_q_head *wake_q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct msg_receiver *msr, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (testmsg(msg, msr->r_msgtype, msr->r_mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) !security_msg_queue_msgrcv(&msq->q_perm, msg, msr->r_tsk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) msr->r_msgtype, msr->r_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) list_del(&msr->r_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (msr->r_maxsize < msg->m_ts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) wake_q_add(wake_q, msr->r_tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* See expunge_all regarding memory barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) smp_store_release(&msr->r_msg, ERR_PTR(-E2BIG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ipc_update_pid(&msq->q_lrpid, task_pid(msr->r_tsk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) msq->q_rtime = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) wake_q_add(wake_q, msr->r_tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* See expunge_all regarding memory barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) smp_store_release(&msr->r_msg, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static long do_msgsnd(int msqid, long mtype, void __user *mtext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) size_t msgsz, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct msg_queue *msq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct msg_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct ipc_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) DEFINE_WAKE_Q(wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ns = current->nsproxy->ipc_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (mtype < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) msg = load_msg(mtext, msgsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (IS_ERR(msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return PTR_ERR(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) msg->m_type = mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) msg->m_ts = msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) msq = msq_obtain_object_check(ns, msqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (IS_ERR(msq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) err = PTR_ERR(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct msg_sender s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (ipcperms(ns, &msq->q_perm, S_IWUGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* raced with RMID? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!ipc_valid_object(&msq->q_perm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) err = -EIDRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) err = security_msg_queue_msgsnd(&msq->q_perm, msg, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (msg_fits_inqueue(msq, msgsz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* queue full, wait: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (msgflg & IPC_NOWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* enqueue the sender and prepare to block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ss_add(msq, &s, msgsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (!ipc_rcu_getref(&msq->q_perm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) err = -EIDRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* raced with RMID? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (!ipc_valid_object(&msq->q_perm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) err = -EIDRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ss_del(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) err = -ERESTARTNOHAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) ipc_update_pid(&msq->q_lspid, task_tgid(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) msq->q_stime = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (!pipelined_send(msq, msg, &wake_q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /* no one is waiting for this message, enqueue it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) list_add_tail(&msg->m_list, &msq->q_messages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) msq->q_cbytes += msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) msq->q_qnum++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) atomic_add(msgsz, &ns->msg_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) atomic_inc(&ns->msg_hdrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) out_unlock0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) wake_up_q(&wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) out_unlock1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (msg != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) free_msg(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) long mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (get_user(mtype, &msgp->mtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) int, msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return ksys_msgsnd(msqid, msgp, msgsz, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct compat_msgbuf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) compat_long_t mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) char mtext[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) compat_ssize_t msgsz, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct compat_msgbuf __user *up = compat_ptr(msgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) compat_long_t mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (get_user(mtype, &up->mtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) compat_ssize_t, msgsz, int, msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return compat_ksys_msgsnd(msqid, msgp, msgsz, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static inline int convert_mode(long *msgtyp, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (msgflg & MSG_COPY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return SEARCH_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * find message of correct type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * msgtyp = 0 => get first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * msgtyp > 0 => get first message of matching type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * msgtyp < 0 => get message with least type must be < abs(msgtype).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (*msgtyp == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return SEARCH_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (*msgtyp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (*msgtyp == LONG_MIN) /* -LONG_MIN is undefined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) *msgtyp = LONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *msgtyp = -*msgtyp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return SEARCH_LESSEQUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (msgflg & MSG_EXCEPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return SEARCH_NOTEQUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return SEARCH_EQUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct msgbuf __user *msgp = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) size_t msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (put_user(msg->m_type, &msgp->mtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (store_msg(msgp->mtext, msg, msgsz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) #ifdef CONFIG_CHECKPOINT_RESTORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * This function creates new kernel message structure, large enough to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * bufsz message bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct msg_msg *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * Create dummy message to copy real message to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) copy = load_msg(buf, bufsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (!IS_ERR(copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) copy->m_ts = bufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static inline void free_copy(struct msg_msg *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) free_msg(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return ERR_PTR(-ENOSYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static inline void free_copy(struct msg_msg *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct msg_msg *msg, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) long count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) list_for_each_entry(msg, &msq->q_messages, m_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (testmsg(msg, *msgtyp, mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) !security_msg_queue_msgrcv(&msq->q_perm, msg, current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) *msgtyp, mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (mode == SEARCH_LESSEQUAL && msg->m_type != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) *msgtyp = msg->m_type - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) found = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) } else if (mode == SEARCH_NUMBER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (*msgtyp == count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return found ?: ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) long (*msg_handler)(void __user *, struct msg_msg *, size_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct msg_queue *msq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct ipc_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct msg_msg *msg, *copy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) DEFINE_WAKE_Q(wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ns = current->nsproxy->ipc_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (msqid < 0 || (long) bufsz < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (msgflg & MSG_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if ((msgflg & MSG_EXCEPT) || !(msgflg & IPC_NOWAIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (IS_ERR(copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return PTR_ERR(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) mode = convert_mode(&msgtyp, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) msq = msq_obtain_object_check(ns, msqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (IS_ERR(msq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) free_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return PTR_ERR(msq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct msg_receiver msr_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) msg = ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (ipcperms(ns, &msq->q_perm, S_IRUGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* raced with RMID? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (!ipc_valid_object(&msq->q_perm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) msg = ERR_PTR(-EIDRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) msg = find_msg(msq, &msgtyp, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (!IS_ERR(msg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * Found a suitable message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * Unlink it from the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) msg = ERR_PTR(-E2BIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * If we are copying, then do not unlink message and do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * not update queue parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (msgflg & MSG_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) msg = copy_msg(msg, copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) list_del(&msg->m_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) msq->q_qnum--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) msq->q_rtime = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ipc_update_pid(&msq->q_lrpid, task_tgid(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) msq->q_cbytes -= msg->m_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) atomic_sub(msg->m_ts, &ns->msg_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) atomic_dec(&ns->msg_hdrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ss_wakeup(msq, &wake_q, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* No message waiting. Wait for a message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (msgflg & IPC_NOWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) msg = ERR_PTR(-ENOMSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) list_add_tail(&msr_d.r_list, &msq->q_receivers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) msr_d.r_tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) msr_d.r_msgtype = msgtyp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) msr_d.r_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (msgflg & MSG_NOERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) msr_d.r_maxsize = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) msr_d.r_maxsize = bufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* memory barrier not require due to ipc_lock_object() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) WRITE_ONCE(msr_d.r_msg, ERR_PTR(-EAGAIN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* memory barrier not required, we own ipc_lock_object() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) __set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * Lockless receive, part 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * We don't hold a reference to the queue and getting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * reference would defeat the idea of a lockless operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * thus the code relies on rcu to guarantee the existence of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * msq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * Prior to destruction, expunge_all(-EIRDM) changes r_msg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * Thus if r_msg is -EAGAIN, then the queue not yet destroyed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * Lockless receive, part 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * The work in pipelined_send() and expunge_all():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * - Set pointer to message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * - Queue the receiver task for later wakeup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * - Wake up the process after the lock is dropped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * Should the process wake up before this wakeup (due to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * signal) it will either see the message and continue ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) msg = READ_ONCE(msr_d.r_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (msg != ERR_PTR(-EAGAIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* see MSG_BARRIER for purpose/pairing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) smp_acquire__after_ctrl_dep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) goto out_unlock1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * ... or see -EAGAIN, acquire the lock to check the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ipc_lock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) msg = READ_ONCE(msr_d.r_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (msg != ERR_PTR(-EAGAIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) list_del(&msr_d.r_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) msg = ERR_PTR(-ERESTARTNOHAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) goto out_unlock0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) out_unlock0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ipc_unlock_object(&msq->q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) wake_up_q(&wake_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) out_unlock1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (IS_ERR(msg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) free_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return PTR_ERR(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) bufsz = msg_handler(buf, msg, bufsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) free_msg(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return bufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) long msgtyp, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) long, msgtyp, int, msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct compat_msgbuf __user *msgp = dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) size_t msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (put_user(msg->m_type, &msgp->mtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (store_msg(msgp->mtext, msg, msgsz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return msgsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) compat_long_t msgtyp, int msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) msgflg, compat_do_msg_fill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) compat_ssize_t, msgsz, compat_long_t, msgtyp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) int, msgflg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) void msg_init_ns(struct ipc_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) ns->msg_ctlmax = MSGMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ns->msg_ctlmnb = MSGMNB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ns->msg_ctlmni = MSGMNI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) atomic_set(&ns->msg_bytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) atomic_set(&ns->msg_hdrs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) #ifdef CONFIG_IPC_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) void msg_exit_ns(struct ipc_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) free_ipcs(ns, &msg_ids(ns), freeque);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) rhashtable_destroy(&ns->ids[IPC_MSG_IDS].key_ht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct pid_namespace *pid_ns = ipc_seq_pid_ns(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct user_namespace *user_ns = seq_user_ns(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct kern_ipc_perm *ipcp = it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) seq_printf(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10llu %10llu %10llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) msq->q_perm.key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) msq->q_perm.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) msq->q_perm.mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) msq->q_cbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) msq->q_qnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) pid_nr_ns(msq->q_lspid, pid_ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) pid_nr_ns(msq->q_lrpid, pid_ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) from_kuid_munged(user_ns, msq->q_perm.uid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) from_kgid_munged(user_ns, msq->q_perm.gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) from_kuid_munged(user_ns, msq->q_perm.cuid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) from_kgid_munged(user_ns, msq->q_perm.cgid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) msq->q_stime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) msq->q_rtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) msq->q_ctime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) void __init msg_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) msg_init_ns(&init_ipc_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) ipc_init_proc_interface("sysvipc/msg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) IPC_MSG_IDS, sysvipc_msg_proc_show);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }