diff options
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 366 |
1 files changed, 255 insertions, 111 deletions
@@ -133,7 +133,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) | |||
133 | } | 133 | } |
134 | 134 | ||
135 | msq->q_stime = msq->q_rtime = 0; | 135 | msq->q_stime = msq->q_rtime = 0; |
136 | msq->q_ctime = get_seconds(); | 136 | msq->q_ctime = ktime_get_real_seconds(); |
137 | msq->q_cbytes = msq->q_qnum = 0; | 137 | msq->q_cbytes = msq->q_qnum = 0; |
138 | msq->q_qbytes = ns->msg_ctlmnb; | 138 | msq->q_qbytes = ns->msg_ctlmnb; |
139 | msq->q_lspid = msq->q_lrpid = 0; | 139 | msq->q_lspid = msq->q_lrpid = 0; |
@@ -361,23 +361,17 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) | |||
361 | * NOTE: no locks must be held, the rwsem is taken inside this function. | 361 | * NOTE: no locks must be held, the rwsem is taken inside this function. |
362 | */ | 362 | */ |
363 | static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | 363 | static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, |
364 | struct msqid_ds __user *buf, int version) | 364 | struct msqid64_ds *msqid64) |
365 | { | 365 | { |
366 | struct kern_ipc_perm *ipcp; | 366 | struct kern_ipc_perm *ipcp; |
367 | struct msqid64_ds uninitialized_var(msqid64); | ||
368 | struct msg_queue *msq; | 367 | struct msg_queue *msq; |
369 | int err; | 368 | int err; |
370 | 369 | ||
371 | if (cmd == IPC_SET) { | ||
372 | if (copy_msqid_from_user(&msqid64, buf, version)) | ||
373 | return -EFAULT; | ||
374 | } | ||
375 | |||
376 | down_write(&msg_ids(ns).rwsem); | 370 | down_write(&msg_ids(ns).rwsem); |
377 | rcu_read_lock(); | 371 | rcu_read_lock(); |
378 | 372 | ||
379 | ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, | 373 | ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, |
380 | &msqid64.msg_perm, msqid64.msg_qbytes); | 374 | &msqid64->msg_perm, msqid64->msg_qbytes); |
381 | if (IS_ERR(ipcp)) { | 375 | if (IS_ERR(ipcp)) { |
382 | err = PTR_ERR(ipcp); | 376 | err = PTR_ERR(ipcp); |
383 | goto out_unlock1; | 377 | goto out_unlock1; |
@@ -399,20 +393,20 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
399 | { | 393 | { |
400 | DEFINE_WAKE_Q(wake_q); | 394 | DEFINE_WAKE_Q(wake_q); |
401 | 395 | ||
402 | if (msqid64.msg_qbytes > ns->msg_ctlmnb && | 396 | if (msqid64->msg_qbytes > ns->msg_ctlmnb && |
403 | !capable(CAP_SYS_RESOURCE)) { | 397 | !capable(CAP_SYS_RESOURCE)) { |
404 | err = -EPERM; | 398 | err = -EPERM; |
405 | goto out_unlock1; | 399 | goto out_unlock1; |
406 | } | 400 | } |
407 | 401 | ||
408 | ipc_lock_object(&msq->q_perm); | 402 | ipc_lock_object(&msq->q_perm); |
409 | err = ipc_update_perm(&msqid64.msg_perm, ipcp); | 403 | err = ipc_update_perm(&msqid64->msg_perm, ipcp); |
410 | if (err) | 404 | if (err) |
411 | goto out_unlock0; | 405 | goto out_unlock0; |
412 | 406 | ||
413 | msq->q_qbytes = msqid64.msg_qbytes; | 407 | msq->q_qbytes = msqid64->msg_qbytes; |
414 | 408 | ||
415 | msq->q_ctime = get_seconds(); | 409 | msq->q_ctime = ktime_get_real_seconds(); |
416 | /* | 410 | /* |
417 | * Sleeping receivers might be excluded by | 411 | * Sleeping receivers might be excluded by |
418 | * stricter permissions. | 412 | * stricter permissions. |
@@ -442,111 +436,89 @@ out_up: | |||
442 | return err; | 436 | return err; |
443 | } | 437 | } |
444 | 438 | ||
445 | static int msgctl_nolock(struct ipc_namespace *ns, int msqid, | 439 | static int msgctl_info(struct ipc_namespace *ns, int msqid, |
446 | int cmd, int version, void __user *buf) | 440 | int cmd, struct msginfo *msginfo) |
447 | { | 441 | { |
448 | int err; | 442 | int err; |
449 | struct msg_queue *msq; | 443 | int max_id; |
450 | |||
451 | switch (cmd) { | ||
452 | case IPC_INFO: | ||
453 | case MSG_INFO: | ||
454 | { | ||
455 | struct msginfo msginfo; | ||
456 | int max_id; | ||
457 | |||
458 | if (!buf) | ||
459 | return -EFAULT; | ||
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 | 444 | ||
470 | memset(&msginfo, 0, sizeof(msginfo)); | 445 | /* |
471 | msginfo.msgmni = ns->msg_ctlmni; | 446 | * We must not return kernel stack data. |
472 | msginfo.msgmax = ns->msg_ctlmax; | 447 | * due to padding, it's not enough |
473 | msginfo.msgmnb = ns->msg_ctlmnb; | 448 | * to set all member fields. |
474 | msginfo.msgssz = MSGSSZ; | 449 | */ |
475 | msginfo.msgseg = MSGSEG; | 450 | err = security_msg_queue_msgctl(NULL, cmd); |
476 | down_read(&msg_ids(ns).rwsem); | 451 | if (err) |
477 | if (cmd == MSG_INFO) { | 452 | return err; |
478 | msginfo.msgpool = msg_ids(ns).in_use; | 453 | |
479 | msginfo.msgmap = atomic_read(&ns->msg_hdrs); | 454 | memset(msginfo, 0, sizeof(*msginfo)); |
480 | msginfo.msgtql = atomic_read(&ns->msg_bytes); | 455 | msginfo->msgmni = ns->msg_ctlmni; |
481 | } else { | 456 | msginfo->msgmax = ns->msg_ctlmax; |
482 | msginfo.msgmap = MSGMAP; | 457 | msginfo->msgmnb = ns->msg_ctlmnb; |
483 | msginfo.msgpool = MSGPOOL; | 458 | msginfo->msgssz = MSGSSZ; |
484 | msginfo.msgtql = MSGTQL; | 459 | msginfo->msgseg = MSGSEG; |
485 | } | 460 | down_read(&msg_ids(ns).rwsem); |
486 | max_id = ipc_get_maxid(&msg_ids(ns)); | 461 | if (cmd == MSG_INFO) { |
487 | up_read(&msg_ids(ns).rwsem); | 462 | msginfo->msgpool = msg_ids(ns).in_use; |
488 | if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) | 463 | msginfo->msgmap = atomic_read(&ns->msg_hdrs); |
489 | return -EFAULT; | 464 | msginfo->msgtql = atomic_read(&ns->msg_bytes); |
490 | return (max_id < 0) ? 0 : max_id; | 465 | } else { |
466 | msginfo->msgmap = MSGMAP; | ||
467 | msginfo->msgpool = MSGPOOL; | ||
468 | msginfo->msgtql = MSGTQL; | ||
491 | } | 469 | } |
470 | max_id = ipc_get_maxid(&msg_ids(ns)); | ||
471 | up_read(&msg_ids(ns).rwsem); | ||
472 | return (max_id < 0) ? 0 : max_id; | ||
473 | } | ||
492 | 474 | ||
493 | case MSG_STAT: | 475 | static int msgctl_stat(struct ipc_namespace *ns, int msqid, |
494 | case IPC_STAT: | 476 | int cmd, struct msqid64_ds *p) |
495 | { | 477 | { |
496 | struct msqid64_ds tbuf; | 478 | int err; |
497 | int success_return; | 479 | struct msg_queue *msq; |
498 | 480 | int success_return; | |
499 | if (!buf) | ||
500 | return -EFAULT; | ||
501 | |||
502 | memset(&tbuf, 0, sizeof(tbuf)); | ||
503 | 481 | ||
504 | rcu_read_lock(); | 482 | memset(p, 0, sizeof(*p)); |
505 | if (cmd == MSG_STAT) { | ||
506 | msq = msq_obtain_object(ns, msqid); | ||
507 | if (IS_ERR(msq)) { | ||
508 | err = PTR_ERR(msq); | ||
509 | goto out_unlock; | ||
510 | } | ||
511 | success_return = msq->q_perm.id; | ||
512 | } else { | ||
513 | msq = msq_obtain_object_check(ns, msqid); | ||
514 | if (IS_ERR(msq)) { | ||
515 | err = PTR_ERR(msq); | ||
516 | goto out_unlock; | ||
517 | } | ||
518 | success_return = 0; | ||
519 | } | ||
520 | 483 | ||
521 | err = -EACCES; | 484 | rcu_read_lock(); |
522 | if (ipcperms(ns, &msq->q_perm, S_IRUGO)) | 485 | if (cmd == MSG_STAT) { |
486 | msq = msq_obtain_object(ns, msqid); | ||
487 | if (IS_ERR(msq)) { | ||
488 | err = PTR_ERR(msq); | ||
523 | goto out_unlock; | 489 | goto out_unlock; |
524 | 490 | } | |
525 | err = security_msg_queue_msgctl(msq, cmd); | 491 | success_return = msq->q_perm.id; |
526 | if (err) | 492 | } else { |
493 | msq = msq_obtain_object_check(ns, msqid); | ||
494 | if (IS_ERR(msq)) { | ||
495 | err = PTR_ERR(msq); | ||
527 | goto out_unlock; | 496 | goto out_unlock; |
497 | } | ||
498 | success_return = 0; | ||
499 | } | ||
528 | 500 | ||
529 | kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); | 501 | err = -EACCES; |
530 | tbuf.msg_stime = msq->q_stime; | 502 | if (ipcperms(ns, &msq->q_perm, S_IRUGO)) |
531 | tbuf.msg_rtime = msq->q_rtime; | 503 | goto out_unlock; |
532 | tbuf.msg_ctime = msq->q_ctime; | ||
533 | tbuf.msg_cbytes = msq->q_cbytes; | ||
534 | tbuf.msg_qnum = msq->q_qnum; | ||
535 | tbuf.msg_qbytes = msq->q_qbytes; | ||
536 | tbuf.msg_lspid = msq->q_lspid; | ||
537 | tbuf.msg_lrpid = msq->q_lrpid; | ||
538 | rcu_read_unlock(); | ||
539 | 504 | ||
540 | if (copy_msqid_to_user(buf, &tbuf, version)) | 505 | err = security_msg_queue_msgctl(msq, cmd); |
541 | return -EFAULT; | 506 | if (err) |
542 | return success_return; | 507 | goto out_unlock; |
543 | } | 508 | |
509 | kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm); | ||
510 | p->msg_stime = msq->q_stime; | ||
511 | p->msg_rtime = msq->q_rtime; | ||
512 | p->msg_ctime = msq->q_ctime; | ||
513 | p->msg_cbytes = msq->q_cbytes; | ||
514 | p->msg_qnum = msq->q_qnum; | ||
515 | p->msg_qbytes = msq->q_qbytes; | ||
516 | p->msg_lspid = msq->q_lspid; | ||
517 | p->msg_lrpid = msq->q_lrpid; | ||
518 | rcu_read_unlock(); | ||
544 | 519 | ||
545 | default: | 520 | return success_return; |
546 | return -EINVAL; | ||
547 | } | ||
548 | 521 | ||
549 | return err; | ||
550 | out_unlock: | 522 | out_unlock: |
551 | rcu_read_unlock(); | 523 | rcu_read_unlock(); |
552 | return err; | 524 | return err; |
@@ -556,6 +528,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) | |||
556 | { | 528 | { |
557 | int version; | 529 | int version; |
558 | struct ipc_namespace *ns; | 530 | struct ipc_namespace *ns; |
531 | struct msqid64_ds msqid64; | ||
532 | int err; | ||
559 | 533 | ||
560 | if (msqid < 0 || cmd < 0) | 534 | if (msqid < 0 || cmd < 0) |
561 | return -EINVAL; | 535 | return -EINVAL; |
@@ -565,18 +539,147 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) | |||
565 | 539 | ||
566 | switch (cmd) { | 540 | switch (cmd) { |
567 | case IPC_INFO: | 541 | case IPC_INFO: |
568 | case MSG_INFO: | 542 | case MSG_INFO: { |
543 | struct msginfo msginfo; | ||
544 | err = msgctl_info(ns, msqid, cmd, &msginfo); | ||
545 | if (err < 0) | ||
546 | return err; | ||
547 | if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) | ||
548 | err = -EFAULT; | ||
549 | return err; | ||
550 | } | ||
569 | case MSG_STAT: /* msqid is an index rather than a msg queue id */ | 551 | case MSG_STAT: /* msqid is an index rather than a msg queue id */ |
570 | case IPC_STAT: | 552 | case IPC_STAT: |
571 | return msgctl_nolock(ns, msqid, cmd, version, buf); | 553 | err = msgctl_stat(ns, msqid, cmd, &msqid64); |
554 | if (err < 0) | ||
555 | return err; | ||
556 | if (copy_msqid_to_user(buf, &msqid64, version)) | ||
557 | err = -EFAULT; | ||
558 | return err; | ||
572 | case IPC_SET: | 559 | case IPC_SET: |
560 | if (copy_msqid_from_user(&msqid64, buf, version)) | ||
561 | return -EFAULT; | ||
562 | /* fallthru */ | ||
573 | case IPC_RMID: | 563 | case IPC_RMID: |
574 | return msgctl_down(ns, msqid, cmd, buf, version); | 564 | return msgctl_down(ns, msqid, cmd, &msqid64); |
575 | default: | 565 | default: |
576 | return -EINVAL; | 566 | return -EINVAL; |
577 | } | 567 | } |
578 | } | 568 | } |
579 | 569 | ||
570 | #ifdef CONFIG_COMPAT | ||
571 | |||
572 | struct compat_msqid_ds { | ||
573 | struct compat_ipc_perm msg_perm; | ||
574 | compat_uptr_t msg_first; | ||
575 | compat_uptr_t msg_last; | ||
576 | compat_time_t msg_stime; | ||
577 | compat_time_t msg_rtime; | ||
578 | compat_time_t msg_ctime; | ||
579 | compat_ulong_t msg_lcbytes; | ||
580 | compat_ulong_t msg_lqbytes; | ||
581 | unsigned short msg_cbytes; | ||
582 | unsigned short msg_qnum; | ||
583 | unsigned short msg_qbytes; | ||
584 | compat_ipc_pid_t msg_lspid; | ||
585 | compat_ipc_pid_t msg_lrpid; | ||
586 | }; | ||
587 | |||
588 | static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf, | ||
589 | int version) | ||
590 | { | ||
591 | memset(out, 0, sizeof(*out)); | ||
592 | if (version == IPC_64) { | ||
593 | struct compat_msqid64_ds *p = buf; | ||
594 | if (get_compat_ipc64_perm(&out->msg_perm, &p->msg_perm)) | ||
595 | return -EFAULT; | ||
596 | if (get_user(out->msg_qbytes, &p->msg_qbytes)) | ||
597 | return -EFAULT; | ||
598 | } else { | ||
599 | struct compat_msqid_ds *p = buf; | ||
600 | if (get_compat_ipc_perm(&out->msg_perm, &p->msg_perm)) | ||
601 | return -EFAULT; | ||
602 | if (get_user(out->msg_qbytes, &p->msg_qbytes)) | ||
603 | return -EFAULT; | ||
604 | } | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in, | ||
609 | int version) | ||
610 | { | ||
611 | if (version == IPC_64) { | ||
612 | struct compat_msqid64_ds v; | ||
613 | memset(&v, 0, sizeof(v)); | ||
614 | to_compat_ipc64_perm(&v.msg_perm, &in->msg_perm); | ||
615 | v.msg_stime = in->msg_stime; | ||
616 | v.msg_rtime = in->msg_rtime; | ||
617 | v.msg_ctime = in->msg_ctime; | ||
618 | v.msg_cbytes = in->msg_cbytes; | ||
619 | v.msg_qnum = in->msg_qnum; | ||
620 | v.msg_qbytes = in->msg_qbytes; | ||
621 | v.msg_lspid = in->msg_lspid; | ||
622 | v.msg_lrpid = in->msg_lrpid; | ||
623 | return copy_to_user(buf, &v, sizeof(v)); | ||
624 | } else { | ||
625 | struct compat_msqid_ds v; | ||
626 | memset(&v, 0, sizeof(v)); | ||
627 | to_compat_ipc_perm(&v.msg_perm, &in->msg_perm); | ||
628 | v.msg_stime = in->msg_stime; | ||
629 | v.msg_rtime = in->msg_rtime; | ||
630 | v.msg_ctime = in->msg_ctime; | ||
631 | v.msg_cbytes = in->msg_cbytes; | ||
632 | v.msg_qnum = in->msg_qnum; | ||
633 | v.msg_qbytes = in->msg_qbytes; | ||
634 | v.msg_lspid = in->msg_lspid; | ||
635 | v.msg_lrpid = in->msg_lrpid; | ||
636 | return copy_to_user(buf, &v, sizeof(v)); | ||
637 | } | ||
638 | } | ||
639 | |||
640 | COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) | ||
641 | { | ||
642 | struct ipc_namespace *ns; | ||
643 | int err; | ||
644 | struct msqid64_ds msqid64; | ||
645 | int version = compat_ipc_parse_version(&cmd); | ||
646 | |||
647 | ns = current->nsproxy->ipc_ns; | ||
648 | |||
649 | if (msqid < 0 || cmd < 0) | ||
650 | return -EINVAL; | ||
651 | |||
652 | switch (cmd & (~IPC_64)) { | ||
653 | case IPC_INFO: | ||
654 | case MSG_INFO: { | ||
655 | struct msginfo msginfo; | ||
656 | err = msgctl_info(ns, msqid, cmd, &msginfo); | ||
657 | if (err < 0) | ||
658 | return err; | ||
659 | if (copy_to_user(uptr, &msginfo, sizeof(struct msginfo))) | ||
660 | err = -EFAULT; | ||
661 | return err; | ||
662 | } | ||
663 | case IPC_STAT: | ||
664 | case MSG_STAT: | ||
665 | err = msgctl_stat(ns, msqid, cmd, &msqid64); | ||
666 | if (err < 0) | ||
667 | return err; | ||
668 | if (copy_compat_msqid_to_user(uptr, &msqid64, version)) | ||
669 | err = -EFAULT; | ||
670 | return err; | ||
671 | case IPC_SET: | ||
672 | if (copy_compat_msqid_from_user(&msqid64, uptr, version)) | ||
673 | return -EFAULT; | ||
674 | /* fallthru */ | ||
675 | case IPC_RMID: | ||
676 | return msgctl_down(ns, msqid, cmd, &msqid64); | ||
677 | default: | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | } | ||
681 | #endif | ||
682 | |||
580 | static int testmsg(struct msg_msg *msg, long type, int mode) | 683 | static int testmsg(struct msg_msg *msg, long type, int mode) |
581 | { | 684 | { |
582 | switch (mode) { | 685 | switch (mode) { |
@@ -627,7 +730,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, | |||
627 | return 0; | 730 | return 0; |
628 | } | 731 | } |
629 | 732 | ||
630 | long do_msgsnd(int msqid, long mtype, void __user *mtext, | 733 | static long do_msgsnd(int msqid, long mtype, void __user *mtext, |
631 | size_t msgsz, int msgflg) | 734 | size_t msgsz, int msgflg) |
632 | { | 735 | { |
633 | struct msg_queue *msq; | 736 | struct msg_queue *msq; |
@@ -750,6 +853,25 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, | |||
750 | return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); | 853 | return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); |
751 | } | 854 | } |
752 | 855 | ||
856 | #ifdef CONFIG_COMPAT | ||
857 | |||
858 | struct compat_msgbuf { | ||
859 | compat_long_t mtype; | ||
860 | char mtext[1]; | ||
861 | }; | ||
862 | |||
863 | COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, | ||
864 | compat_ssize_t, msgsz, int, msgflg) | ||
865 | { | ||
866 | struct compat_msgbuf __user *up = compat_ptr(msgp); | ||
867 | compat_long_t mtype; | ||
868 | |||
869 | if (get_user(mtype, &up->mtype)) | ||
870 | return -EFAULT; | ||
871 | return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg); | ||
872 | } | ||
873 | #endif | ||
874 | |||
753 | static inline int convert_mode(long *msgtyp, int msgflg) | 875 | static inline int convert_mode(long *msgtyp, int msgflg) |
754 | { | 876 | { |
755 | if (msgflg & MSG_COPY) | 877 | if (msgflg & MSG_COPY) |
@@ -846,7 +968,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode) | |||
846 | return found ?: ERR_PTR(-EAGAIN); | 968 | return found ?: ERR_PTR(-EAGAIN); |
847 | } | 969 | } |
848 | 970 | ||
849 | long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, | 971 | static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, |
850 | long (*msg_handler)(void __user *, struct msg_msg *, size_t)) | 972 | long (*msg_handler)(void __user *, struct msg_msg *, size_t)) |
851 | { | 973 | { |
852 | int mode; | 974 | int mode; |
@@ -1010,6 +1132,28 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, | |||
1010 | return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); | 1132 | return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); |
1011 | } | 1133 | } |
1012 | 1134 | ||
1135 | #ifdef CONFIG_COMPAT | ||
1136 | static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) | ||
1137 | { | ||
1138 | struct compat_msgbuf __user *msgp = dest; | ||
1139 | size_t msgsz; | ||
1140 | |||
1141 | if (put_user(msg->m_type, &msgp->mtype)) | ||
1142 | return -EFAULT; | ||
1143 | |||
1144 | msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz; | ||
1145 | if (store_msg(msgp->mtext, msg, msgsz)) | ||
1146 | return -EFAULT; | ||
1147 | return msgsz; | ||
1148 | } | ||
1149 | |||
1150 | COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | ||
1151 | compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg) | ||
1152 | { | ||
1153 | return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, | ||
1154 | msgflg, compat_do_msg_fill); | ||
1155 | } | ||
1156 | #endif | ||
1013 | 1157 | ||
1014 | int msg_init_ns(struct ipc_namespace *ns) | 1158 | int msg_init_ns(struct ipc_namespace *ns) |
1015 | { | 1159 | { |
@@ -1039,7 +1183,7 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | |||
1039 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); | 1183 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); |
1040 | 1184 | ||
1041 | seq_printf(s, | 1185 | seq_printf(s, |
1042 | "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", | 1186 | "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10llu %10llu %10llu\n", |
1043 | msq->q_perm.key, | 1187 | msq->q_perm.key, |
1044 | msq->q_perm.id, | 1188 | msq->q_perm.id, |
1045 | msq->q_perm.mode, | 1189 | msq->q_perm.mode, |