linux/ipc/msg.c

// 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 <[email protected]>
 *
 * mostly rewritten, threaded and wake-one semantics added
 * MSGMAX limit removed, sysctl's added
 * (c) 1999 Manfred Spraul <[email protected]>
 *
 * support for audit of ipc object properties and permission changes
 * Dustin Kirkland <[email protected]>
 *
 * namespaces support
 * OpenVZ, SWsoft Inc.
 * Pavel Emelianov <[email protected]>
 */

#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 <linux/percpu_counter.h>

#include <asm/current.h>
#include <linux/uaccess.h>
#include "util.h"

/* one msq_queue structure for each present queue on the system */
struct msg_queue {} __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 */
struct msg_receiver {};

/* one msg_sender for each sleeping sender */
struct msg_sender {};

#define SEARCH_ANY
#define SEARCH_EQUAL
#define SEARCH_NOTEQUAL
#define SEARCH_LESSEQUAL
#define SEARCH_NUMBER

#define msg_ids(ns)

static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
{}

static inline struct msg_queue *msq_obtain_object_check(struct ipc_namespace *ns,
							int id)
{}

static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
{}

static void msg_rcu_free(struct rcu_head *head)
{}

/**
 * newque - Create a new msg queue
 * @ns: namespace
 * @params: ptr to the structure that contains the key and msgflg
 *
 * Called with msg_ids.rwsem held (writer)
 */
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{}

static inline bool msg_fits_inqueue(struct msg_queue *msq, size_t msgsz)
{}

static inline void ss_add(struct msg_queue *msq,
			  struct msg_sender *mss, size_t msgsz)
{}

static inline void ss_del(struct msg_sender *mss)
{}

static void ss_wakeup(struct msg_queue *msq,
		      struct wake_q_head *wake_q, bool kill)
{}

static void expunge_all(struct msg_queue *msq, int res,
			struct wake_q_head *wake_q)
{}

/*
 * freeque() wakes up waiters on the sender and receiver waiting queue,
 * removes the message queue from message queue ID IDR, and cleans up all the
 * messages associated with this queue.
 *
 * msg_ids.rwsem (writer) and the spinlock for this message queue are held
 * before freeque() is called. msg_ids.rwsem remains locked on exit.
 */
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
	__releases(RCU)
	__releases(&msq->q_perm)
{}

long ksys_msgget(key_t key, int msgflg)
{}

SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
{}

static inline unsigned long
copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
{}

static inline unsigned long
copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
{}

/*
 * This function handles some msgctl commands which require the rwsem
 * to be held in write mode.
 * NOTE: no locks must be held, the rwsem is taken inside this function.
 */
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
			struct ipc64_perm *perm, int msg_qbytes)
{}

static int msgctl_info(struct ipc_namespace *ns, int msqid,
			 int cmd, struct msginfo *msginfo)
{}

static int msgctl_stat(struct ipc_namespace *ns, int msqid,
			 int cmd, struct msqid64_ds *p)
{}

static long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf, int version)
{}

SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{}

#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
{
	int version = ipc_parse_version(&cmd);

	return ksys_msgctl(msqid, cmd, buf, version);
}

SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{
	return ksys_old_msgctl(msqid, cmd, buf);
}
#endif

#ifdef CONFIG_COMPAT

struct compat_msqid_ds {};

static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf,
					int version)
{}

static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in,
					int version)
{}

static long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr, int version)
{}

COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr)
{}

#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr)
{}

COMPAT_SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, void __user *, uptr)
{}
#endif
#endif

static int testmsg(struct msg_msg *msg, long type, int mode)
{}

static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
				 struct wake_q_head *wake_q)
{}

static long do_msgsnd(int msqid, long mtype, void __user *mtext,
		size_t msgsz, int msgflg)
{}

long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
		 int msgflg)
{}

SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
		int, msgflg)
{}

#ifdef CONFIG_COMPAT

struct compat_msgbuf {};

long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
		       compat_ssize_t msgsz, int msgflg)
{}

COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
		       compat_ssize_t, msgsz, int, msgflg)
{}
#endif

static inline int convert_mode(long *msgtyp, int msgflg)
{}

static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
{}

#ifdef CONFIG_CHECKPOINT_RESTORE
/*
 * This function creates new kernel message structure, large enough to store
 * bufsz message bytes.
 */
static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz)
{}

static inline void free_copy(struct msg_msg *copy)
{}
#else
static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz)
{
	return ERR_PTR(-ENOSYS);
}

static inline void free_copy(struct msg_msg *copy)
{
}
#endif

static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
{}

static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
	       long (*msg_handler)(void __user *, struct msg_msg *, size_t))
{}

long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
		 long msgtyp, int msgflg)
{}

SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
		long, msgtyp, int, msgflg)
{}

#ifdef CONFIG_COMPAT
static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
{}

long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
			compat_long_t msgtyp, int msgflg)
{}

COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
		       compat_ssize_t, msgsz, compat_long_t, msgtyp,
		       int, msgflg)
{}
#endif

int msg_init_ns(struct ipc_namespace *ns)
{}

#ifdef CONFIG_IPC_NS
void msg_exit_ns(struct ipc_namespace *ns)
{}
#endif

#ifdef CONFIG_PROC_FS
static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
{}
#endif

void __init msg_init(void)
{}