diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-09 08:31:16 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-15 20:46:43 -0400 |
commit | 4693916846269d633a3664586650dbfac2c5562f (patch) | |
tree | e7dd196843fc6af4a67b20588403dd696e5262e9 /ipc | |
parent | 156d9ed1260ee566f2be09c13254b58247edfb29 (diff) |
msgctl(): move compat to native
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/compat.c | 132 | ||||
-rw-r--r-- | ipc/msg.c | 133 |
2 files changed, 133 insertions, 132 deletions
diff --git a/ipc/compat.c b/ipc/compat.c index fbfd6fb0a68d..c83099a3b265 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
@@ -50,22 +50,6 @@ struct compat_semid_ds { | |||
50 | unsigned short sem_nsems; | 50 | unsigned short sem_nsems; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct compat_msqid_ds { | ||
54 | struct compat_ipc_perm msg_perm; | ||
55 | compat_uptr_t msg_first; | ||
56 | compat_uptr_t msg_last; | ||
57 | compat_time_t msg_stime; | ||
58 | compat_time_t msg_rtime; | ||
59 | compat_time_t msg_ctime; | ||
60 | compat_ulong_t msg_lcbytes; | ||
61 | compat_ulong_t msg_lqbytes; | ||
62 | unsigned short msg_cbytes; | ||
63 | unsigned short msg_qnum; | ||
64 | unsigned short msg_qbytes; | ||
65 | compat_ipc_pid_t msg_lspid; | ||
66 | compat_ipc_pid_t msg_lrpid; | ||
67 | }; | ||
68 | |||
69 | struct compat_ipc_kludge { | 53 | struct compat_ipc_kludge { |
70 | compat_uptr_t msgp; | 54 | compat_uptr_t msgp; |
71 | compat_long_t msgtyp; | 55 | compat_long_t msgtyp; |
@@ -391,122 +375,6 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | |||
391 | msgflg, compat_do_msg_fill); | 375 | msgflg, compat_do_msg_fill); |
392 | } | 376 | } |
393 | 377 | ||
394 | static inline int get_compat_msqid64(struct msqid64_ds *m64, | ||
395 | struct compat_msqid64_ds __user *up64) | ||
396 | { | ||
397 | int err; | ||
398 | |||
399 | if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) | ||
400 | return -EFAULT; | ||
401 | err = __get_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); | ||
402 | err |= __get_user(m64->msg_qbytes, &up64->msg_qbytes); | ||
403 | return err; | ||
404 | } | ||
405 | |||
406 | static inline int get_compat_msqid(struct msqid64_ds *m, | ||
407 | struct compat_msqid_ds __user *up) | ||
408 | { | ||
409 | int err; | ||
410 | |||
411 | if (!access_ok(VERIFY_READ, up, sizeof(*up))) | ||
412 | return -EFAULT; | ||
413 | err = __get_compat_ipc_perm(&m->msg_perm, &up->msg_perm); | ||
414 | err |= __get_user(m->msg_qbytes, &up->msg_qbytes); | ||
415 | return err; | ||
416 | } | ||
417 | |||
418 | static inline int put_compat_msqid64_ds(struct msqid64_ds *m64, | ||
419 | struct compat_msqid64_ds __user *up64) | ||
420 | { | ||
421 | int err; | ||
422 | |||
423 | if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) | ||
424 | return -EFAULT; | ||
425 | err = __put_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); | ||
426 | err |= __put_user(m64->msg_stime, &up64->msg_stime); | ||
427 | err |= __put_user(m64->msg_rtime, &up64->msg_rtime); | ||
428 | err |= __put_user(m64->msg_ctime, &up64->msg_ctime); | ||
429 | err |= __put_user(m64->msg_cbytes, &up64->msg_cbytes); | ||
430 | err |= __put_user(m64->msg_qnum, &up64->msg_qnum); | ||
431 | err |= __put_user(m64->msg_qbytes, &up64->msg_qbytes); | ||
432 | err |= __put_user(m64->msg_lspid, &up64->msg_lspid); | ||
433 | err |= __put_user(m64->msg_lrpid, &up64->msg_lrpid); | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | static inline int put_compat_msqid_ds(struct msqid64_ds *m, | ||
438 | struct compat_msqid_ds __user *up) | ||
439 | { | ||
440 | int err; | ||
441 | |||
442 | if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) | ||
443 | return -EFAULT; | ||
444 | err = __put_compat_ipc_perm(&m->msg_perm, &up->msg_perm); | ||
445 | err |= __put_user(m->msg_stime, &up->msg_stime); | ||
446 | err |= __put_user(m->msg_rtime, &up->msg_rtime); | ||
447 | err |= __put_user(m->msg_ctime, &up->msg_ctime); | ||
448 | err |= __put_user(m->msg_cbytes, &up->msg_cbytes); | ||
449 | err |= __put_user(m->msg_qnum, &up->msg_qnum); | ||
450 | err |= __put_user(m->msg_qbytes, &up->msg_qbytes); | ||
451 | err |= __put_user(m->msg_lspid, &up->msg_lspid); | ||
452 | err |= __put_user(m->msg_lrpid, &up->msg_lrpid); | ||
453 | return err; | ||
454 | } | ||
455 | |||
456 | COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr) | ||
457 | { | ||
458 | int err, err2; | ||
459 | struct msqid64_ds m64; | ||
460 | int version = __compat_ipc_parse_version(&second); | ||
461 | void __user *p; | ||
462 | |||
463 | memset(&m64, 0, sizeof(m64)); | ||
464 | |||
465 | switch (second & (~IPC_64)) { | ||
466 | case IPC_INFO: | ||
467 | case IPC_RMID: | ||
468 | case MSG_INFO: | ||
469 | err = sys_msgctl(first, second, uptr); | ||
470 | break; | ||
471 | |||
472 | case IPC_SET: | ||
473 | if (version == IPC_64) | ||
474 | err = get_compat_msqid64(&m64, uptr); | ||
475 | else | ||
476 | err = get_compat_msqid(&m64, uptr); | ||
477 | |||
478 | if (err) | ||
479 | break; | ||
480 | p = compat_alloc_user_space(sizeof(m64)); | ||
481 | if (copy_to_user(p, &m64, sizeof(m64))) | ||
482 | err = -EFAULT; | ||
483 | else | ||
484 | err = sys_msgctl(first, second, p); | ||
485 | break; | ||
486 | |||
487 | case IPC_STAT: | ||
488 | case MSG_STAT: | ||
489 | p = compat_alloc_user_space(sizeof(m64)); | ||
490 | err = sys_msgctl(first, second, p); | ||
491 | if (err < 0) | ||
492 | break; | ||
493 | if (copy_from_user(&m64, p, sizeof(m64))) | ||
494 | err2 = -EFAULT; | ||
495 | else if (version == IPC_64) | ||
496 | err2 = put_compat_msqid64_ds(&m64, uptr); | ||
497 | else | ||
498 | err2 = put_compat_msqid_ds(&m64, uptr); | ||
499 | if (err2) | ||
500 | err = -EFAULT; | ||
501 | break; | ||
502 | |||
503 | default: | ||
504 | err = -EINVAL; | ||
505 | break; | ||
506 | } | ||
507 | return err; | ||
508 | } | ||
509 | |||
510 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) | 378 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) |
511 | { | 379 | { |
512 | unsigned long ret; | 380 | unsigned long ret; |
@@ -567,6 +567,139 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) | |||
567 | } | 567 | } |
568 | } | 568 | } |
569 | 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 | struct compat_ipc64_perm v; | ||
595 | if (copy_from_user(&v, &p->msg_perm, sizeof(v))) | ||
596 | return -EFAULT; | ||
597 | out->msg_perm.uid = v.uid; | ||
598 | out->msg_perm.gid = v.gid; | ||
599 | out->msg_perm.mode = v.mode; | ||
600 | if (get_user(out->msg_qbytes, &p->msg_qbytes)) | ||
601 | return -EFAULT; | ||
602 | } else { | ||
603 | struct compat_msqid_ds *p = buf; | ||
604 | struct compat_ipc_perm v; | ||
605 | if (copy_from_user(&v, &p->msg_perm, sizeof(v))) | ||
606 | return -EFAULT; | ||
607 | out->msg_perm.uid = v.uid; | ||
608 | out->msg_perm.gid = v.gid; | ||
609 | out->msg_perm.mode = v.mode; | ||
610 | if (get_user(out->msg_qbytes, &p->msg_qbytes)) | ||
611 | return -EFAULT; | ||
612 | } | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in, | ||
617 | int version) | ||
618 | { | ||
619 | if (version == IPC_64) { | ||
620 | struct compat_msqid64_ds v; | ||
621 | memset(&v, 0, sizeof(v)); | ||
622 | v.msg_perm.key = in->msg_perm.key; | ||
623 | v.msg_perm.uid = in->msg_perm.uid; | ||
624 | v.msg_perm.gid = in->msg_perm.gid; | ||
625 | v.msg_perm.cuid = in->msg_perm.cuid; | ||
626 | v.msg_perm.cgid = in->msg_perm.cgid; | ||
627 | v.msg_perm.mode = in->msg_perm.mode; | ||
628 | v.msg_perm.seq = in->msg_perm.seq; | ||
629 | v.msg_stime = in->msg_stime; | ||
630 | v.msg_rtime = in->msg_rtime; | ||
631 | v.msg_ctime = in->msg_ctime; | ||
632 | v.msg_cbytes = in->msg_cbytes; | ||
633 | v.msg_qnum = in->msg_qnum; | ||
634 | v.msg_qbytes = in->msg_qbytes; | ||
635 | v.msg_lspid = in->msg_lspid; | ||
636 | v.msg_lrpid = in->msg_lrpid; | ||
637 | return copy_to_user(buf, &v, sizeof(v)); | ||
638 | } else { | ||
639 | struct compat_msqid_ds v; | ||
640 | memset(&v, 0, sizeof(v)); | ||
641 | v.msg_perm.key = in->msg_perm.key; | ||
642 | SET_UID(v.msg_perm.uid, in->msg_perm.uid); | ||
643 | SET_GID(v.msg_perm.gid, in->msg_perm.gid); | ||
644 | SET_UID(v.msg_perm.cuid, in->msg_perm.cuid); | ||
645 | SET_GID(v.msg_perm.cgid, in->msg_perm.cgid); | ||
646 | v.msg_perm.mode = in->msg_perm.mode; | ||
647 | v.msg_perm.seq = in->msg_perm.seq; | ||
648 | v.msg_stime = in->msg_stime; | ||
649 | v.msg_rtime = in->msg_rtime; | ||
650 | v.msg_ctime = in->msg_ctime; | ||
651 | v.msg_cbytes = in->msg_cbytes; | ||
652 | v.msg_qnum = in->msg_qnum; | ||
653 | v.msg_qbytes = in->msg_qbytes; | ||
654 | v.msg_lspid = in->msg_lspid; | ||
655 | v.msg_lrpid = in->msg_lrpid; | ||
656 | return copy_to_user(buf, &v, sizeof(v)); | ||
657 | } | ||
658 | } | ||
659 | |||
660 | COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) | ||
661 | { | ||
662 | struct ipc_namespace *ns; | ||
663 | int err; | ||
664 | struct msqid64_ds msqid64; | ||
665 | int version = compat_ipc_parse_version(&cmd); | ||
666 | |||
667 | ns = current->nsproxy->ipc_ns; | ||
668 | |||
669 | if (msqid < 0 || cmd < 0) | ||
670 | return -EINVAL; | ||
671 | |||
672 | switch (cmd & (~IPC_64)) { | ||
673 | case IPC_INFO: | ||
674 | case MSG_INFO: { | ||
675 | struct msginfo msginfo; | ||
676 | err = msgctl_info(ns, msqid, cmd, &msginfo); | ||
677 | if (err < 0) | ||
678 | return err; | ||
679 | if (copy_to_user(uptr, &msginfo, sizeof(struct msginfo))) | ||
680 | err = -EFAULT; | ||
681 | return err; | ||
682 | } | ||
683 | case IPC_STAT: | ||
684 | case MSG_STAT: | ||
685 | err = msgctl_stat(ns, msqid, cmd, &msqid64); | ||
686 | if (err < 0) | ||
687 | return err; | ||
688 | if (copy_compat_msqid_to_user(uptr, &msqid64, version)) | ||
689 | err = -EFAULT; | ||
690 | return err; | ||
691 | case IPC_SET: | ||
692 | if (copy_compat_msqid_from_user(&msqid64, uptr, version)) | ||
693 | return -EFAULT; | ||
694 | /* fallthru */ | ||
695 | case IPC_RMID: | ||
696 | return msgctl_down(ns, msqid, cmd, &msqid64); | ||
697 | default: | ||
698 | return -EINVAL; | ||
699 | } | ||
700 | } | ||
701 | #endif | ||
702 | |||
570 | static int testmsg(struct msg_msg *msg, long type, int mode) | 703 | static int testmsg(struct msg_msg *msg, long type, int mode) |
571 | { | 704 | { |
572 | switch (mode) { | 705 | switch (mode) { |