root/ipc/msg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. msq_obtain_object
  2. msq_obtain_object_check
  3. msg_rmid
  4. msg_rcu_free
  5. newque
  6. msg_fits_inqueue
  7. ss_add
  8. ss_del
  9. ss_wakeup
  10. expunge_all
  11. freeque
  12. ksys_msgget
  13. SYSCALL_DEFINE2
  14. copy_msqid_to_user
  15. copy_msqid_from_user
  16. msgctl_down
  17. msgctl_info
  18. msgctl_stat
  19. ksys_msgctl
  20. SYSCALL_DEFINE3
  21. ksys_old_msgctl
  22. SYSCALL_DEFINE3
  23. copy_compat_msqid_from_user
  24. copy_compat_msqid_to_user
  25. compat_ksys_msgctl
  26. COMPAT_SYSCALL_DEFINE3
  27. compat_ksys_old_msgctl
  28. COMPAT_SYSCALL_DEFINE3
  29. testmsg
  30. pipelined_send
  31. do_msgsnd
  32. ksys_msgsnd
  33. SYSCALL_DEFINE4
  34. compat_ksys_msgsnd
  35. COMPAT_SYSCALL_DEFINE4
  36. convert_mode
  37. do_msg_fill
  38. prepare_copy
  39. free_copy
  40. prepare_copy
  41. free_copy
  42. find_msg
  43. do_msgrcv
  44. ksys_msgrcv
  45. SYSCALL_DEFINE5
  46. compat_do_msg_fill
  47. compat_ksys_msgrcv
  48. COMPAT_SYSCALL_DEFINE5
  49. msg_init_ns
  50. msg_exit_ns
  51. sysvipc_msg_proc_show
  52. msg_init

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

/* [<][>][^][v][top][bottom][index][help] */