sysv_msg.c (220388) | sysv_msg.c (220398) |
---|---|
1/*- 2 * Implementation of SVID messages 3 * 4 * Author: Daniel Boulet 5 * 6 * Copyright 1993 Daniel Boulet and RTMX Inc. 7 * 8 * This system call was implemented by Daniel Boulet under contract from RTMX. --- 34 unchanged lines hidden (view full) --- 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 */ 49 50#include <sys/cdefs.h> | 1/*- 2 * Implementation of SVID messages 3 * 4 * Author: Daniel Boulet 5 * 6 * Copyright 1993 Daniel Boulet and RTMX Inc. 7 * 8 * This system call was implemented by Daniel Boulet under contract from RTMX. --- 34 unchanged lines hidden (view full) --- 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 */ 49 50#include <sys/cdefs.h> |
51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 220388 2011-04-06 16:59:54Z trasz $"); | 51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 220398 2011-04-06 18:11:24Z trasz $"); |
52 53#include "opt_compat.h" 54#include "opt_sysvipc.h" 55 56#include <sys/param.h> 57#include <sys/systm.h> 58#include <sys/sysproto.h> 59#include <sys/kernel.h> 60#include <sys/priv.h> 61#include <sys/proc.h> 62#include <sys/lock.h> 63#include <sys/mutex.h> 64#include <sys/module.h> 65#include <sys/msg.h> | 52 53#include "opt_compat.h" 54#include "opt_sysvipc.h" 55 56#include <sys/param.h> 57#include <sys/systm.h> 58#include <sys/sysproto.h> 59#include <sys/kernel.h> 60#include <sys/priv.h> 61#include <sys/proc.h> 62#include <sys/lock.h> 63#include <sys/mutex.h> 64#include <sys/module.h> 65#include <sys/msg.h> |
66#include <sys/racct.h> |
|
66#include <sys/syscall.h> 67#include <sys/syscallsubr.h> 68#include <sys/sysent.h> 69#include <sys/sysctl.h> 70#include <sys/malloc.h> 71#include <sys/jail.h> 72 73#include <security/mac/mac_framework.h> --- 387 unchanged lines hidden (view full) --- 461 for (msghdr = msqkptr->u.msg_first; msghdr != NULL; 462 msghdr = msghdr->msg_next) { 463 error = mac_sysvmsq_check_msgrmid(td->td_ucred, msghdr); 464 if (error != 0) 465 goto done2; 466 } 467#endif 468 | 67#include <sys/syscall.h> 68#include <sys/syscallsubr.h> 69#include <sys/sysent.h> 70#include <sys/sysctl.h> 71#include <sys/malloc.h> 72#include <sys/jail.h> 73 74#include <security/mac/mac_framework.h> --- 387 unchanged lines hidden (view full) --- 462 for (msghdr = msqkptr->u.msg_first; msghdr != NULL; 463 msghdr = msghdr->msg_next) { 464 error = mac_sysvmsq_check_msgrmid(td->td_ucred, msghdr); 465 if (error != 0) 466 goto done2; 467 } 468#endif 469 |
470 racct_sub_cred(msqkptr->cred, RACCT_NMSGQ, 1); 471 racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, msqkptr->u.msg_qnum); 472 racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msqkptr->u.msg_cbytes); |
|
469 crfree(msqkptr->cred); 470 msqkptr->cred = NULL; 471 472 /* Free the message headers */ 473 msghdr = msqkptr->u.msg_first; 474 while (msghdr != NULL) { 475 struct msg *msghdr_tmp; 476 --- 134 unchanged lines hidden (view full) --- 611 (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0) 612 break; 613 } 614 if (msqid == msginfo.msgmni) { 615 DPRINTF(("no more msqid_ds's available\n")); 616 error = ENOSPC; 617 goto done2; 618 } | 473 crfree(msqkptr->cred); 474 msqkptr->cred = NULL; 475 476 /* Free the message headers */ 477 msghdr = msqkptr->u.msg_first; 478 while (msghdr != NULL) { 479 struct msg *msghdr_tmp; 480 --- 134 unchanged lines hidden (view full) --- 615 (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0) 616 break; 617 } 618 if (msqid == msginfo.msgmni) { 619 DPRINTF(("no more msqid_ds's available\n")); 620 error = ENOSPC; 621 goto done2; 622 } |
623 PROC_LOCK(td->td_proc); 624 error = racct_add(td->td_proc, RACCT_NMSGQ, 1); 625 PROC_UNLOCK(td->td_proc); 626 if (error != 0) { 627 error = ENOSPC; 628 goto done2; 629 } |
|
619 DPRINTF(("msqid %d is available\n", msqid)); 620 msqkptr->u.msg_perm.key = key; 621 msqkptr->u.msg_perm.cuid = cred->cr_uid; 622 msqkptr->u.msg_perm.uid = cred->cr_uid; 623 msqkptr->u.msg_perm.cgid = cred->cr_gid; 624 msqkptr->u.msg_perm.gid = cred->cr_gid; 625 msqkptr->u.msg_perm.mode = (msgflg & 0777); 626 crhold(cred); --- 43 unchanged lines hidden (view full) --- 670 size_t msgsz; 671 int msgflg; 672 long mtype; 673{ 674 int msqix, segs_needed, error = 0; 675 register struct msqid_kernel *msqkptr; 676 register struct msg *msghdr; 677 short next; | 630 DPRINTF(("msqid %d is available\n", msqid)); 631 msqkptr->u.msg_perm.key = key; 632 msqkptr->u.msg_perm.cuid = cred->cr_uid; 633 msqkptr->u.msg_perm.uid = cred->cr_uid; 634 msqkptr->u.msg_perm.cgid = cred->cr_gid; 635 msqkptr->u.msg_perm.gid = cred->cr_gid; 636 msqkptr->u.msg_perm.mode = (msgflg & 0777); 637 crhold(cred); --- 43 unchanged lines hidden (view full) --- 681 size_t msgsz; 682 int msgflg; 683 long mtype; 684{ 685 int msqix, segs_needed, error = 0; 686 register struct msqid_kernel *msqkptr; 687 register struct msg *msghdr; 688 short next; |
689 size_t saved_msgsz; |
|
678 679 if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) 680 return (ENOSYS); 681 682 mtx_lock(&msq_mtx); 683 msqix = IPCID_TO_IX(msqid); 684 685 if (msqix < 0 || msqix >= msginfo.msgmni) { --- 21 unchanged lines hidden (view full) --- 707 } 708 709#ifdef MAC 710 error = mac_sysvmsq_check_msqsnd(td->td_ucred, msqkptr); 711 if (error != 0) 712 goto done2; 713#endif 714 | 690 691 if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) 692 return (ENOSYS); 693 694 mtx_lock(&msq_mtx); 695 msqix = IPCID_TO_IX(msqid); 696 697 if (msqix < 0 || msqix >= msginfo.msgmni) { --- 21 unchanged lines hidden (view full) --- 719 } 720 721#ifdef MAC 722 error = mac_sysvmsq_check_msqsnd(td->td_ucred, msqkptr); 723 if (error != 0) 724 goto done2; 725#endif 726 |
727 PROC_LOCK(td->td_proc); 728 if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) { 729 PROC_UNLOCK(td->td_proc); 730 error = EAGAIN; 731 goto done2; 732 } 733 saved_msgsz = msgsz; 734 if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) { 735 racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1); 736 PROC_UNLOCK(td->td_proc); 737 error = EAGAIN; 738 goto done2; 739 } 740 PROC_UNLOCK(td->td_proc); 741 |
|
715 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; 716 DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz, 717 msginfo.msgssz, segs_needed)); 718 for (;;) { 719 int need_more_resources = 0; 720 721 /* 722 * check msgsz 723 * (inside this loop in case msg_qbytes changes while we sleep) 724 */ 725 726 if (msgsz > msqkptr->u.msg_qbytes) { 727 DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n")); 728 error = EINVAL; | 742 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; 743 DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz, 744 msginfo.msgssz, segs_needed)); 745 for (;;) { 746 int need_more_resources = 0; 747 748 /* 749 * check msgsz 750 * (inside this loop in case msg_qbytes changes while we sleep) 751 */ 752 753 if (msgsz > msqkptr->u.msg_qbytes) { 754 DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n")); 755 error = EINVAL; |
729 goto done2; | 756 goto done3; |
730 } 731 732 if (msqkptr->u.msg_perm.mode & MSG_LOCKED) { 733 DPRINTF(("msqid is locked\n")); 734 need_more_resources = 1; 735 } 736 if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) { 737 DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n")); --- 10 unchanged lines hidden (view full) --- 748 749 if (need_more_resources) { 750 int we_own_it; 751 752 if ((msgflg & IPC_NOWAIT) != 0) { 753 DPRINTF(("need more resources but caller " 754 "doesn't want to wait\n")); 755 error = EAGAIN; | 757 } 758 759 if (msqkptr->u.msg_perm.mode & MSG_LOCKED) { 760 DPRINTF(("msqid is locked\n")); 761 need_more_resources = 1; 762 } 763 if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) { 764 DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n")); --- 10 unchanged lines hidden (view full) --- 775 776 if (need_more_resources) { 777 int we_own_it; 778 779 if ((msgflg & IPC_NOWAIT) != 0) { 780 DPRINTF(("need more resources but caller " 781 "doesn't want to wait\n")); 782 error = EAGAIN; |
756 goto done2; | 783 goto done3; |
757 } 758 759 if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) { 760 DPRINTF(("we don't own the msqid_ds\n")); 761 we_own_it = 0; 762 } else { 763 /* Force later arrivals to wait for our 764 request */ --- 9 unchanged lines hidden (view full) --- 774 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 775 if (error == EWOULDBLOCK) { 776 DPRINTF(("msgsnd: timed out\n")); 777 continue; 778 } 779 if (error != 0) { 780 DPRINTF(("msgsnd: interrupted system call\n")); 781 error = EINTR; | 784 } 785 786 if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) { 787 DPRINTF(("we don't own the msqid_ds\n")); 788 we_own_it = 0; 789 } else { 790 /* Force later arrivals to wait for our 791 request */ --- 9 unchanged lines hidden (view full) --- 801 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 802 if (error == EWOULDBLOCK) { 803 DPRINTF(("msgsnd: timed out\n")); 804 continue; 805 } 806 if (error != 0) { 807 DPRINTF(("msgsnd: interrupted system call\n")); 808 error = EINTR; |
782 goto done2; | 809 goto done3; |
783 } 784 785 /* 786 * Make sure that the msq queue still exists 787 */ 788 789 if (msqkptr->u.msg_qbytes == 0) { 790 DPRINTF(("msqid deleted\n")); 791 error = EIDRM; | 810 } 811 812 /* 813 * Make sure that the msq queue still exists 814 */ 815 816 if (msqkptr->u.msg_qbytes == 0) { 817 DPRINTF(("msqid deleted\n")); 818 error = EIDRM; |
792 goto done2; | 819 goto done3; |
793 } 794 795 } else { 796 DPRINTF(("got all the resources that we need\n")); 797 break; 798 } 799 } 800 --- 65 unchanged lines hidden (view full) --- 866 */ 867 868 if (msghdr->msg_type < 1) { 869 msg_freehdr(msghdr); 870 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 871 wakeup(msqkptr); 872 DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type)); 873 error = EINVAL; | 820 } 821 822 } else { 823 DPRINTF(("got all the resources that we need\n")); 824 break; 825 } 826 } 827 --- 65 unchanged lines hidden (view full) --- 893 */ 894 895 if (msghdr->msg_type < 1) { 896 msg_freehdr(msghdr); 897 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 898 wakeup(msqkptr); 899 DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type)); 900 error = EINVAL; |
874 goto done2; | 901 goto done3; |
875 } 876 877 /* 878 * Copy in the message body 879 */ 880 881 next = msghdr->msg_spot; 882 while (msgsz > 0) { --- 10 unchanged lines hidden (view full) --- 893 if ((error = copyin(msgp, &msgpool[next * msginfo.msgssz], 894 tlen)) != 0) { 895 mtx_lock(&msq_mtx); 896 DPRINTF(("error %d copying in message segment\n", 897 error)); 898 msg_freehdr(msghdr); 899 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 900 wakeup(msqkptr); | 902 } 903 904 /* 905 * Copy in the message body 906 */ 907 908 next = msghdr->msg_spot; 909 while (msgsz > 0) { --- 10 unchanged lines hidden (view full) --- 920 if ((error = copyin(msgp, &msgpool[next * msginfo.msgssz], 921 tlen)) != 0) { 922 mtx_lock(&msq_mtx); 923 DPRINTF(("error %d copying in message segment\n", 924 error)); 925 msg_freehdr(msghdr); 926 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED; 927 wakeup(msqkptr); |
901 goto done2; | 928 goto done3; |
902 } 903 mtx_lock(&msq_mtx); 904 msgsz -= tlen; 905 msgp = (const char *)msgp + tlen; 906 next = msgmaps[next].next; 907 } 908 if (next != -1) 909 panic("didn't use all the msg segments"); --- 7 unchanged lines hidden (view full) --- 917 /* 918 * Make sure that the msqid_ds is still allocated. 919 */ 920 921 if (msqkptr->u.msg_qbytes == 0) { 922 msg_freehdr(msghdr); 923 wakeup(msqkptr); 924 error = EIDRM; | 929 } 930 mtx_lock(&msq_mtx); 931 msgsz -= tlen; 932 msgp = (const char *)msgp + tlen; 933 next = msgmaps[next].next; 934 } 935 if (next != -1) 936 panic("didn't use all the msg segments"); --- 7 unchanged lines hidden (view full) --- 944 /* 945 * Make sure that the msqid_ds is still allocated. 946 */ 947 948 if (msqkptr->u.msg_qbytes == 0) { 949 msg_freehdr(msghdr); 950 wakeup(msqkptr); 951 error = EIDRM; |
925 goto done2; | 952 goto done3; |
926 } 927 928#ifdef MAC 929 /* 930 * Note: Since the task/thread allocates the msghdr and usually 931 * primes it with its own MAC label, for a majority of policies, it 932 * won't be necessary to check whether the msghdr has access 933 * permissions to the msgq. The mac_sysvmsq_check_msqsnd check would 934 * suffice in that case. However, this hook may be required where 935 * individual policies derive a non-identical label for the msghdr 936 * from the current thread label and may want to check the msghdr 937 * enqueue permissions, along with read/write permissions to the 938 * msgq. 939 */ 940 error = mac_sysvmsq_check_msgmsq(td->td_ucred, msghdr, msqkptr); 941 if (error != 0) { 942 msg_freehdr(msghdr); 943 wakeup(msqkptr); | 953 } 954 955#ifdef MAC 956 /* 957 * Note: Since the task/thread allocates the msghdr and usually 958 * primes it with its own MAC label, for a majority of policies, it 959 * won't be necessary to check whether the msghdr has access 960 * permissions to the msgq. The mac_sysvmsq_check_msqsnd check would 961 * suffice in that case. However, this hook may be required where 962 * individual policies derive a non-identical label for the msghdr 963 * from the current thread label and may want to check the msghdr 964 * enqueue permissions, along with read/write permissions to the 965 * msgq. 966 */ 967 error = mac_sysvmsq_check_msgmsq(td->td_ucred, msghdr, msqkptr); 968 if (error != 0) { 969 msg_freehdr(msghdr); 970 wakeup(msqkptr); |
944 goto done2; | 971 goto done3; |
945 } 946#endif 947 948 /* 949 * Put the message into the queue 950 */ 951 if (msqkptr->u.msg_first == NULL) { 952 msqkptr->u.msg_first = msghdr; --- 6 unchanged lines hidden (view full) --- 959 960 msqkptr->u.msg_cbytes += msghdr->msg_ts; 961 msqkptr->u.msg_qnum++; 962 msqkptr->u.msg_lspid = td->td_proc->p_pid; 963 msqkptr->u.msg_stime = time_second; 964 965 wakeup(msqkptr); 966 td->td_retval[0] = 0; | 972 } 973#endif 974 975 /* 976 * Put the message into the queue 977 */ 978 if (msqkptr->u.msg_first == NULL) { 979 msqkptr->u.msg_first = msghdr; --- 6 unchanged lines hidden (view full) --- 986 987 msqkptr->u.msg_cbytes += msghdr->msg_ts; 988 msqkptr->u.msg_qnum++; 989 msqkptr->u.msg_lspid = td->td_proc->p_pid; 990 msqkptr->u.msg_stime = time_second; 991 992 wakeup(msqkptr); 993 td->td_retval[0] = 0; |
994done3: 995 if (error != 0) { 996 PROC_LOCK(td->td_proc); 997 racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1); 998 racct_sub(td->td_proc, RACCT_MSGQSIZE, saved_msgsz); 999 PROC_UNLOCK(td->td_proc); 1000 } |
|
967done2: 968 mtx_unlock(&msq_mtx); 969 return (error); 970} 971 972int 973msgsnd(td, uap) 974 struct thread *td; --- 217 unchanged lines hidden (view full) --- 1192 * First, do the bookkeeping (before we risk being interrupted). 1193 */ 1194 1195 msqkptr->u.msg_cbytes -= msghdr->msg_ts; 1196 msqkptr->u.msg_qnum--; 1197 msqkptr->u.msg_lrpid = td->td_proc->p_pid; 1198 msqkptr->u.msg_rtime = time_second; 1199 | 1001done2: 1002 mtx_unlock(&msq_mtx); 1003 return (error); 1004} 1005 1006int 1007msgsnd(td, uap) 1008 struct thread *td; --- 217 unchanged lines hidden (view full) --- 1226 * First, do the bookkeeping (before we risk being interrupted). 1227 */ 1228 1229 msqkptr->u.msg_cbytes -= msghdr->msg_ts; 1230 msqkptr->u.msg_qnum--; 1231 msqkptr->u.msg_lrpid = td->td_proc->p_pid; 1232 msqkptr->u.msg_rtime = time_second; 1233 |
1234 racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, 1); 1235 racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msghdr->msg_ts); 1236 |
|
1200 /* 1201 * Make msgsz the actual amount that we'll be returning. 1202 * Note that this effectively truncates the message if it is too long 1203 * (since msgsz is never increased). 1204 */ 1205 1206 DPRINTF(("found a message, msgsz=%zu, msg_ts=%hu\n", msgsz, 1207 msghdr->msg_ts)); --- 339 unchanged lines hidden --- | 1237 /* 1238 * Make msgsz the actual amount that we'll be returning. 1239 * Note that this effectively truncates the message if it is too long 1240 * (since msgsz is never increased). 1241 */ 1242 1243 DPRINTF(("found a message, msgsz=%zu, msg_ts=%hu\n", msgsz, 1244 msghdr->msg_ts)); --- 339 unchanged lines hidden --- |