Exemplo n.º 1
0
int
sys_msgget(struct proc *p, void *v, register_t *retval)
{
	struct sys_msgget_args /* {
		syscallarg(key_t) key;
		syscallarg(int) msgflg;
	} */ *uap = v;
	int msqid, eval;
	int key = SCARG(uap, key);
	int msgflg = SCARG(uap, msgflg);
	struct ucred *cred = p->p_ucred;
	struct msqid_kernel *msqkptr = NULL;

	DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg));

	if (key != IPC_PRIVATE) {
		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
			msqkptr = &msqids[msqid];
			if (msqkptr->u.msg_qbytes != 0 &&
			    msqkptr->u.msg_perm.key == key)
				break;
		}
		if (msqid < msginfo.msgmni) {
			DPRINTF(("found public key\n"));
			if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
				DPRINTF(("not exclusive\n"));
				return (EEXIST);
			}
			if ((eval = ipcperm(cred, &msqkptr->u.msg_perm,
			    msgflg & 0700 ))) {
				DPRINTF(("requester doesn't have 0%o access\n",
				    msgflg & 0700));
				return (eval);
			}
#ifdef MAC
			eval = mac_sysvmsq_check_msqget(cred, msqkptr);
			if (eval)
				return (eval);
#endif
			goto found;
		}
	}

	DPRINTF(("need to allocate the msqid_ds\n"));
	if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) {
		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
			/*
			 * Look for an unallocated and unlocked msqid_ds.
			 * msqid_ds's can be locked by msgsnd or msgrcv while
			 * they are copying the message in/out.  We can't
			 * re-use the entry until they release it.
			 */
			msqkptr = &msqids[msqid];
			if (msqkptr->u.msg_qbytes == 0 &&
			    (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0)
				break;
		}
		if (msqid == msginfo.msgmni) {
			DPRINTF(("no more msqid_ds's available\n"));
			return (ENOSPC);	
		}
		DPRINTF(("msqid %d is available\n", msqid));
		msqkptr->u.msg_perm.key = key;
		msqkptr->u.msg_perm.cuid = cred->cr_uid;
		msqkptr->u.msg_perm.uid = cred->cr_uid;
		msqkptr->u.msg_perm.cgid = cred->cr_gid;
		msqkptr->u.msg_perm.gid = cred->cr_gid;
		msqkptr->u.msg_perm.mode = (msgflg & 0777);
		/* Make sure that the returned msqid is unique */
		msqkptr->u.msg_perm.seq =
		    (msqkptr->u.msg_perm.seq + 1) & 0x7fff;
		msqkptr->u.msg_first = NULL;
		msqkptr->u.msg_last = NULL;
		msqkptr->u.msg_cbytes = 0;
		msqkptr->u.msg_qnum = 0;
		msqkptr->u.msg_qbytes = msginfo.msgmnb;
		msqkptr->u.msg_lspid = 0;
		msqkptr->u.msg_lrpid = 0;
		msqkptr->u.msg_stime = 0;
		msqkptr->u.msg_rtime = 0;
		msqkptr->u.msg_ctime = time_second;
#ifdef MAC
		mac_sysvmsq_create(cred, msqkptr);
#endif
	} else {
		DPRINTF(("didn't find it and wasn't asked to create it\n"));
		return (ENOENT);
	}

found:
	/* Construct the unique msqid */
	*retval = IXSEQ_TO_IPCID(msqid, msqkptr->u.msg_perm);
	return (0);
}
Exemplo n.º 2
0
int
msgget(__unused struct proc *p, struct msgget_args *uap, int32_t *retval)
{
	int msqid, eval;
	int key = uap->key;
	int msgflg = uap->msgflg;
	kauth_cred_t cred = kauth_cred_get();
	struct msqid_kernel *msqptr = NULL;

	SYSV_MSG_SUBSYS_LOCK();

	if (!msginit(0)) {
		eval =  ENOMEM;
		goto msggetout;
	}

#ifdef MSG_DEBUG_OK
	printf("msgget(0x%x, 0%o)\n", key, msgflg);
#endif

	if (key != IPC_PRIVATE) {
		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
			msqptr = &msqids[msqid];
			if (msqptr->u.msg_qbytes != 0 &&
			    msqptr->u.msg_perm._key == key)
				break;
		}
		if (msqid < msginfo.msgmni) {
#ifdef MSG_DEBUG_OK
			printf("found public key\n");
#endif
			if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
#ifdef MSG_DEBUG_OK
				printf("not exclusive\n");
#endif
				eval = EEXIST;
				goto msggetout;
			}
			if ((eval = ipcperm(cred, &msqptr->u.msg_perm, msgflg & 0700 ))) {
#ifdef MSG_DEBUG_OK
				printf("requester doesn't have 0%o access\n",
				    msgflg & 0700);
#endif
				goto msggetout;
			}
#if CONFIG_MACF
			eval = mac_sysvmsq_check_msqget(cred, msqptr);
			if (eval) 
				goto msggetout;
#endif
			goto found;
		}
	}

#ifdef MSG_DEBUG_OK
	printf("need to allocate the user_msqid_ds\n");
#endif
	if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) {
		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
			/*
			 * Look for an unallocated and unlocked user_msqid_ds.
			 * user_msqid_ds's can be locked by msgsnd or msgrcv
			 * while they are copying the message in/out.  We
			 * can't re-use the entry until they release it.
			 */
			msqptr = &msqids[msqid];
			if (msqptr->u.msg_qbytes == 0 &&
			    (msqptr->u.msg_perm.mode & MSG_LOCKED) == 0)
				break;
		}
		if (msqid == msginfo.msgmni) {
#ifdef MSG_DEBUG_OK
			printf("no more user_msqid_ds's available\n");
#endif
			eval = ENOSPC;
			goto msggetout;
		}
#ifdef MSG_DEBUG_OK
		printf("msqid %d is available\n", msqid);
#endif
		msqptr->u.msg_perm._key = key;
		msqptr->u.msg_perm.cuid = kauth_cred_getuid(cred);
		msqptr->u.msg_perm.uid = kauth_cred_getuid(cred);
		msqptr->u.msg_perm.cgid = kauth_cred_getgid(cred);
		msqptr->u.msg_perm.gid = kauth_cred_getgid(cred);
		msqptr->u.msg_perm.mode = (msgflg & 0777);
		/* Make sure that the returned msqid is unique */
		msqptr->u.msg_perm._seq++;
		msqptr->u.msg_first = NULL;
		msqptr->u.msg_last = NULL;
		msqptr->u.msg_cbytes = 0;
		msqptr->u.msg_qnum = 0;
		msqptr->u.msg_qbytes = msginfo.msgmnb;
		msqptr->u.msg_lspid = 0;
		msqptr->u.msg_lrpid = 0;
		msqptr->u.msg_stime = 0;
		msqptr->u.msg_rtime = 0;
		msqptr->u.msg_ctime = sysv_msgtime();
#if CONFIG_MACF
		mac_sysvmsq_label_associate(cred, msqptr);
#endif
	} else {
#ifdef MSG_DEBUG_OK
		printf("didn't find it and wasn't asked to create it\n");
#endif
		eval = ENOENT;
		goto msggetout;
	}

found:
	/* Construct the unique msqid */
	*retval = IXSEQ_TO_IPCID(msqid, msqptr->u.msg_perm);
	AUDIT_ARG(svipc_id, *retval);
	eval = 0;
msggetout:
	SYSV_MSG_SUBSYS_UNLOCK();
	return(eval);
}