msgctl(): move compat to native

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 46939168 156d9ed1

+133 -132
-132
ipc/compat.c
··· 50 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 53 struct compat_ipc_kludge { 70 54 compat_uptr_t msgp; 71 55 compat_long_t msgtyp; ··· 373 389 { 374 390 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, 375 391 msgflg, compat_do_msg_fill); 376 - } 377 - 378 - static inline int get_compat_msqid64(struct msqid64_ds *m64, 379 - struct compat_msqid64_ds __user *up64) 380 - { 381 - int err; 382 - 383 - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) 384 - return -EFAULT; 385 - err = __get_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); 386 - err |= __get_user(m64->msg_qbytes, &up64->msg_qbytes); 387 - return err; 388 - } 389 - 390 - static inline int get_compat_msqid(struct msqid64_ds *m, 391 - struct compat_msqid_ds __user *up) 392 - { 393 - int err; 394 - 395 - if (!access_ok(VERIFY_READ, up, sizeof(*up))) 396 - return -EFAULT; 397 - err = __get_compat_ipc_perm(&m->msg_perm, &up->msg_perm); 398 - err |= __get_user(m->msg_qbytes, &up->msg_qbytes); 399 - return err; 400 - } 401 - 402 - static inline int put_compat_msqid64_ds(struct msqid64_ds *m64, 403 - struct compat_msqid64_ds __user *up64) 404 - { 405 - int err; 406 - 407 - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) 408 - return -EFAULT; 409 - err = __put_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); 410 - err |= __put_user(m64->msg_stime, &up64->msg_stime); 411 - err |= __put_user(m64->msg_rtime, &up64->msg_rtime); 412 - err |= __put_user(m64->msg_ctime, &up64->msg_ctime); 413 - err |= __put_user(m64->msg_cbytes, &up64->msg_cbytes); 414 - err |= __put_user(m64->msg_qnum, &up64->msg_qnum); 415 - err |= __put_user(m64->msg_qbytes, &up64->msg_qbytes); 416 - err |= __put_user(m64->msg_lspid, &up64->msg_lspid); 417 - err |= __put_user(m64->msg_lrpid, &up64->msg_lrpid); 418 - return err; 419 - } 420 - 421 - static inline int put_compat_msqid_ds(struct msqid64_ds *m, 422 - struct compat_msqid_ds __user *up) 423 - { 424 - int err; 425 - 426 - if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) 427 - return -EFAULT; 428 - err = __put_compat_ipc_perm(&m->msg_perm, &up->msg_perm); 429 - err |= __put_user(m->msg_stime, &up->msg_stime); 430 - err |= __put_user(m->msg_rtime, &up->msg_rtime); 431 - err |= __put_user(m->msg_ctime, &up->msg_ctime); 432 - err |= __put_user(m->msg_cbytes, &up->msg_cbytes); 433 - err |= __put_user(m->msg_qnum, &up->msg_qnum); 434 - err |= __put_user(m->msg_qbytes, &up->msg_qbytes); 435 - err |= __put_user(m->msg_lspid, &up->msg_lspid); 436 - err |= __put_user(m->msg_lrpid, &up->msg_lrpid); 437 - return err; 438 - } 439 - 440 - COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr) 441 - { 442 - int err, err2; 443 - struct msqid64_ds m64; 444 - int version = __compat_ipc_parse_version(&second); 445 - void __user *p; 446 - 447 - memset(&m64, 0, sizeof(m64)); 448 - 449 - switch (second & (~IPC_64)) { 450 - case IPC_INFO: 451 - case IPC_RMID: 452 - case MSG_INFO: 453 - err = sys_msgctl(first, second, uptr); 454 - break; 455 - 456 - case IPC_SET: 457 - if (version == IPC_64) 458 - err = get_compat_msqid64(&m64, uptr); 459 - else 460 - err = get_compat_msqid(&m64, uptr); 461 - 462 - if (err) 463 - break; 464 - p = compat_alloc_user_space(sizeof(m64)); 465 - if (copy_to_user(p, &m64, sizeof(m64))) 466 - err = -EFAULT; 467 - else 468 - err = sys_msgctl(first, second, p); 469 - break; 470 - 471 - case IPC_STAT: 472 - case MSG_STAT: 473 - p = compat_alloc_user_space(sizeof(m64)); 474 - err = sys_msgctl(first, second, p); 475 - if (err < 0) 476 - break; 477 - if (copy_from_user(&m64, p, sizeof(m64))) 478 - err2 = -EFAULT; 479 - else if (version == IPC_64) 480 - err2 = put_compat_msqid64_ds(&m64, uptr); 481 - else 482 - err2 = put_compat_msqid_ds(&m64, uptr); 483 - if (err2) 484 - err = -EFAULT; 485 - break; 486 - 487 - default: 488 - err = -EINVAL; 489 - break; 490 - } 491 - return err; 492 392 } 493 393 494 394 COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
+133
ipc/msg.c
··· 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 703 static int testmsg(struct msg_msg *msg, long type, int mode) 571 704 { 572 705 switch (mode) {