#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"
struct msg_queue { … } __randomize_layout;
struct msg_receiver { … };
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)
{ … }
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)
{ … }
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)
{ … }
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
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)
{ … }