// SPDX-License-Identifier: GPL-2.0/* * linux/ipc/msg.c * Copyright (C) 1992 Krishna Balasubramanian * * Removed all the remaining kerneld mess * Catch the -EFAULT stuff properly * Use GFP_KERNEL for messages as in 1.2 * Fixed up the unchecked user space derefs * Copyright (C) 1998 Alan Cox & Andi Kleen * * /proc/sysvipc/msg support (c) 1999 Dragos Acostachioaie <dragos@iname.com> * * mostly rewritten, threaded and wake-one semantics added * MSGMAX limit removed, sysctl's added * (c) 1999 Manfred Spraul <manfred@colorfullife.com> * * support for audit of ipc object properties and permission changes * Dustin Kirkland <dustin.kirkland@us.ibm.com> * * namespaces support * OpenVZ, SWsoft Inc. * Pavel Emelianov <xemul@openvz.org> */#include<linux/capability.h>#include<linux/msg.h>#include<linux/spinlock.h>#include<linux/init.h>#include<linux/mm.h>#include<linux/proc_fs.h>#include<linux/list.h>#include<linux/security.h>#include<linux/sched/wake_q.h>#include<linux/syscalls.h>#include<linux/audit.h>#include<linux/seq_file.h>#include<linux/rwsem.h>#include<linux/nsproxy.h>#include<linux/ipc_namespace.h>#include<linux/rhashtable.h>#include<asm/current.h>#include<linux/uaccess.h>#include"util.h"/* one msq_queue structure for each present queue on the system */structmsg_queue{structkern_ipc_permq_perm;time64_tq_stime;/* last msgsnd time */time64_tq_rtime;/* last msgrcv time */time64_tq_ctime;/* last change time */unsignedlongq_cbytes;/* current number of bytes on queue */unsignedlongq_qnum;/* number of messages in queue */unsignedlongq_qbytes;/* max number of bytes on queue */structpid*q_lspid;/* pid of last msgsnd */structpid*q_lrpid;/* last receive pid */structlist_headq_messages;structlist_headq_receivers;structlist_headq_senders;}__randomize_layout;/* * MSG_BARRIER Locking: * * Similar to the optimization used in ipc/mqueue.c, one syscall return path * does not acquire any locks when it sees that a message exists in * msg_receiver.r_msg. Therefore r_msg is set using smp_store_release() * and accessed using READ_ONCE()+smp_acquire__after_ctrl_dep(). In addition, * wake_q_add_safe() is used. See ipc/mqueue.c for more details *//* one msg_receiver structure for each sleeping receiver */structmsg_receiver{structlist_headr_list;structtask_struct*r_tsk;intr_mode;longr_msgtype;longr_maxsize;structmsg_msg*r_msg;};/* one msg_sender for each sleeping sender */structmsg_sender{structlist_headlist;structtask_struct*tsk;size_tmsgsz;};#define SEARCH_ANY 1#define SEARCH_EQUAL 2#define SEARCH_NOTEQUAL 3#define SEARCH_LESSEQUAL 4#define SEARCH_NUMBER 5#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])staticinlinestructmsg_queue*msq_obtain_object(structipc_namespace*ns,intid){structkern_ipc_perm*