예제 #1
0
파일: ipcs.c 프로젝트: 2asoft/freebsd
void
print_ksemptr(int i, int option, struct semid_kernel *ksemaptr)
{
	char    ctime_buf[100], otime_buf[100];

	cvt_time(ksemaptr->u.sem_otime, otime_buf);
	cvt_time(ksemaptr->u.sem_ctime, ctime_buf);

	printf("s %12d %12d %s %-8s %-8s",
	    IXSEQ_TO_IPCID(i, ksemaptr->u.sem_perm),
	    (int)ksemaptr->u.sem_perm.key,
	    fmt_perm(ksemaptr->u.sem_perm.mode),
	    user_from_uid(ksemaptr->u.sem_perm.uid, 0),
	    group_from_gid(ksemaptr->u.sem_perm.gid, 0));

	if (option & CREATOR)
		printf(" %-8s %-8s",
		    user_from_uid(ksemaptr->u.sem_perm.cuid, 0),
		    group_from_gid(ksemaptr->u.sem_perm.cgid, 0));

	if (option & BIGGEST)
		printf(" %12d",
		    ksemaptr->u.sem_nsems);

	if (option & TIME)
		printf(" %s %s",
		    otime_buf,
		    ctime_buf);

	printf("\n");
}
예제 #2
0
/* Get the id of an existing shared memory segment. */
static int
shmget_existing(struct shmget_msg *shmget_msg, int mode,
		int segnum, struct cmsgcred *cred)
{
	struct shmid_ds *shmseg;
	int error;

	shmseg = &shmsegs[segnum];
	if (shmseg->shm_perm.mode & SHMSEG_REMOVED) {
		/*
		 * This segment is in the process of being allocated.  Wait
		 * until it's done, and look the key up again (in case the
		 * allocation failed or it was freed).
		 */
		//TODO Maybe it will be necessary if the daemon is multithreading
		/*shmseg->shm_perm.mode |= SHMSEG_WANTED;
		  error = tsleep((caddr_t)shmseg, PCATCH, "shmget", 0);
		  if (error)
		  return error;
		  return EAGAIN;*/
	}
	if ((shmget_msg->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
		return (-EEXIST);
	error = ipcperm(cred, &shmseg->shm_perm, mode);
	if (error)
		return (-error);
	if (shmget_msg->size && (shmget_msg->size > shmseg->shm_segsz))
		return (-EINVAL);
	return (IXSEQ_TO_IPCID(segnum, shmseg->shm_perm));
}
static int
semrmall(void)
{
	int mib[4];
	struct sem_sysctl_info *semsi;
	size_t len;
	int32_t i;
	int result = 0;

	mib[0] = CTL_KERN;
	mib[1] = KERN_SYSVIPC;
	mib[2] = KERN_SYSVIPC_INFO;
	mib[3] = KERN_SYSVIPC_SEM_INFO;

	if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
		err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");

	if ((semsi = malloc(len)) == NULL)
		err(1, "malloc");
	if (sysctl(mib, 4, semsi, &len, NULL, 0) == -1) {
		free(semsi);
		err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");
	}

	for (i = 0; i < semsi->seminfo.semmni; i++) {
		struct semid_ds_sysctl *semptr = &semsi->semids[i];
		if ((semptr->sem_perm.mode & SEM_ALLOC) != 0)
			result -= semrm((key_t)0,
			    (int)IXSEQ_TO_IPCID(i, semptr->sem_perm));
	}
	free(semsi);
	return result;
}
static int
msgrmall(void)
{
	int mib[4];
	struct msg_sysctl_info *msgsi;
	int32_t i;
	size_t len;
	int result = 0;

	mib[0] = CTL_KERN;
	mib[1] = KERN_SYSVIPC;
	mib[2] = KERN_SYSVIPC_INFO;
	mib[3] = KERN_SYSVIPC_MSG_INFO;

	if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
		err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");

	if ((msgsi = malloc(len)) == NULL)
		err(1, "malloc");
	if (sysctl(mib, 4, msgsi, &len, NULL, 0) == -1) {
		free(msgsi);
		err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");
	}

	for (i = 0; i < msgsi->msginfo.msgmni; i++) {
		struct msgid_ds_sysctl *msgptr = &msgsi->msgids[i];
		if (msgptr->msg_qbytes != 0)
			result -= msgrm((key_t)0,
			    (int)IXSEQ_TO_IPCID(i, msgptr->msg_perm));
	}
	free(msgsi);
	return result;
}
예제 #5
0
파일: ipcs.c 프로젝트: 2asoft/freebsd
void
print_kshmptr(int i, int option, struct shmid_kernel *kshmptr)
{
	char    atime_buf[100], dtime_buf[100], ctime_buf[100];

	cvt_time(kshmptr->u.shm_atime, atime_buf);
	cvt_time(kshmptr->u.shm_dtime, dtime_buf);
	cvt_time(kshmptr->u.shm_ctime, ctime_buf);

	printf("m %12d %12d %s %-8s %-8s",
	    IXSEQ_TO_IPCID(i, kshmptr->u.shm_perm),
	    (int)kshmptr->u.shm_perm.key,
	    fmt_perm(kshmptr->u.shm_perm.mode),
	    user_from_uid(kshmptr->u.shm_perm.uid, 0),
	    group_from_gid(kshmptr->u.shm_perm.gid, 0));

	if (option & CREATOR)
		printf(" %-8s %-8s",
		    user_from_uid(kshmptr->u.shm_perm.cuid, 0),
		    group_from_gid(kshmptr->u.shm_perm.cgid, 0));

	if (option & OUTSTANDING)
		printf(" %12d",
		    kshmptr->u.shm_nattch);

	if (option & BIGGEST)
		printf(" %12zu",
		    kshmptr->u.shm_segsz);

	if (option & PID)
		printf(" %12d %12d",
		    kshmptr->u.shm_cpid,
		    kshmptr->u.shm_lpid);

	if (option & TIME)
		printf(" %s %s %s",
		    atime_buf,
		    dtime_buf,
		    ctime_buf);

	printf("\n");
}
예제 #6
0
파일: ipcs.c 프로젝트: 2asoft/freebsd
void
print_kmsqptr(int i, int option, struct msqid_kernel *kmsqptr)
{
	char    stime_buf[100], rtime_buf[100], ctime_buf[100];

	cvt_time(kmsqptr->u.msg_stime, stime_buf);
	cvt_time(kmsqptr->u.msg_rtime, rtime_buf);
	cvt_time(kmsqptr->u.msg_ctime, ctime_buf);

	printf("q %12d %12d %s %-8s %-8s",
	    IXSEQ_TO_IPCID(i, kmsqptr->u.msg_perm),
	    (int)kmsqptr->u.msg_perm.key,
	    fmt_perm(kmsqptr->u.msg_perm.mode),
	    user_from_uid(kmsqptr->u.msg_perm.uid, 0),
	    group_from_gid(kmsqptr->u.msg_perm.gid, 0));

	if (option & CREATOR)
		printf(" %-8s %-8s",
		    user_from_uid(kmsqptr->u.msg_perm.cuid, 0),
		    group_from_gid(kmsqptr->u.msg_perm.cgid, 0));

	if (option & OUTSTANDING)
		printf(" %12lu %12lu",
		    kmsqptr->u.msg_cbytes,
		    kmsqptr->u.msg_qnum);

	if (option & BIGGEST)
		printf(" %20lu", kmsqptr->u.msg_qbytes);

	if (option & PID)
		printf(" %12d %12d",
		    kmsqptr->u.msg_lspid,
		    kmsqptr->u.msg_lrpid);

	if (option & TIME)
		printf(" %s %s %s",
		    stime_buf,
		    rtime_buf,
		    ctime_buf);

	printf("\n");
}
예제 #7
0
int
semrm(key_t key, int id)
{
	union semun arg;

	if (key == -1 || id == -1) {
		struct semid_kernel *kxsema;
		size_t kxsema_len;
		int num;

		kget(X_SEMINFO, &seminfo, sizeof(seminfo));
		kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni;
		kxsema = malloc(kxsema_len);
		kget(X_SEMA, kxsema, kxsema_len);
		num = seminfo.semmni;
		while (num-- && !signaled)
			if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) {
				id = IXSEQ_TO_IPCID(num,
					kxsema[num].u.sem_perm);
				if (semctl(id, IPC_RMID, NULL) < 0) {
					if (rmverbose > 1)
						warn("semid(%d): ", id);
					errflg++;
				} else
					if (rmverbose)
						printf(
						    "Removed %s %d\n",
						    IPC_TO_STRING('S'),
						    id);
			}
		return signaled ? -1 : 0;       /* errors maybe handled above */
	}

	if (key) {
		id = semget(key, 0, 0);
		if (id == -1)
			return -1;
	}

	return semctl(id, 0, IPC_RMID, arg);
}
예제 #8
0
int
msgrm(key_t key, int id)
{

	if (key == -1 || id == -1) {
		struct msqid_kernel *kxmsqids;
		size_t kxmsqids_len;
		int num;

		kget(X_MSGINFO, &msginfo, sizeof(msginfo));
		kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni;
		kxmsqids = malloc(kxmsqids_len);
		kget(X_MSQIDS, kxmsqids, kxmsqids_len);
		num = msginfo.msgmni;
		while (num-- && !signaled)
			if (kxmsqids[num].u.msg_qbytes != 0) {
				id = IXSEQ_TO_IPCID(num,
					kxmsqids[num].u.msg_perm);
				if (msgctl(id, IPC_RMID, NULL) < 0) {
					if (rmverbose > 1)
						warn("msqid(%d): ", id);
					errflg++;
				} else
					if (rmverbose)
						printf(
						    "Removed %s %d\n",
						    IPC_TO_STRING('Q'),
						    id);
			}
		return signaled ? -1 : 0;       /* errors maybe handled above */
	}

	if (key) {
		id = msgget(key, 0);
		if (id == -1)
			return -1;
	}

	return msgctl(id, IPC_RMID, NULL);
}
예제 #9
0
int
shmrm(key_t key, int id)
{

	if (key == -1 || id == -1) {
		struct shmid_kernel *kxshmids;
		size_t kxshmids_len;
		int num;

		kget(X_SHMINFO, &shminfo, sizeof(shminfo));
		kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni;
		kxshmids = malloc(kxshmids_len);
		kget(X_SHMSEGS, kxshmids, kxshmids_len);
		num = shminfo.shmmni;
		while (num-- && !signaled)
			if (kxshmids[num].u.shm_perm.mode & 0x0800) {
				id = IXSEQ_TO_IPCID(num,
					kxshmids[num].u.shm_perm);
				if (shmctl(id, IPC_RMID, NULL) < 0) {
					if (rmverbose > 1)
						warn("shmid(%d): ", id);
					errflg++;
				} else
					if (rmverbose)
						printf(
						    "Removed %s %d\n",
						    IPC_TO_STRING('M'),
						    id);
			}
		return signaled ? -1 : 0;       /* errors maybe handled above */
	}

	if (key) {
		id = shmget(key, 0, 0);
		if (id == -1)
			return -1;
	}

	return shmctl(id, IPC_RMID, NULL);
}
예제 #10
0
int
shmget_existing(struct proc *p,
	struct sys_shmget_args /* {
		syscallarg(key_t) key;
		syscallarg(size_t) size;
		syscallarg(int) shmflg;
	} */ *uap,
	int mode, int segnum, register_t *retval)
{
	struct shmid_ds *shmseg;
	struct ucred *cred = p->p_ucred;
	int error;

	shmseg = shmsegs[segnum];	/* We assume the segnum is valid */
	if ((error = ipcperm(cred, &shmseg->shm_perm, mode)) != 0)
		return (error);
	if (SCARG(uap, size) && SCARG(uap, size) > shmseg->shm_segsz)
		return (EINVAL);
	if ((SCARG(uap, shmflg) & (IPC_CREAT | IPC_EXCL)) ==
	    (IPC_CREAT | IPC_EXCL))
		return (EEXIST);
	*retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
	return (0);
}
예제 #11
0
/*
 * MPALMOSTSAFE
 */
int
sys_msgget(struct msgget_args *uap)
{
	struct thread *td = curthread;
	int msqid, eval;
	int key = uap->key;
	int msgflg = uap->msgflg;
	struct ucred *cred = td->td_ucred;
	struct msqid_ds *msqptr = NULL;

#ifdef MSG_DEBUG_OK
	kprintf("msgget(0x%x, 0%o)\n", key, msgflg);
#endif
	if (!jail_sysvipc_allowed && cred->cr_prison != NULL)
		return (ENOSYS);

	eval = 0;
	get_mplock();

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

#ifdef MSG_DEBUG_OK
	kprintf("need to allocate the msqid_ds\n");
#endif
	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.
			 */
			msqptr = &msqids[msqid];
			if (msqptr->msg_qbytes == 0 &&
			    (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
				break;
		}
		if (msqid == msginfo.msgmni) {
#ifdef MSG_DEBUG_OK
			kprintf("no more msqid_ds's available\n");
#endif
			eval = ENOSPC;
			goto done;
		}
#ifdef MSG_DEBUG_OK
		kprintf("msqid %d is available\n", msqid);
#endif
		msqptr->msg_perm.key = key;
		msqptr->msg_perm.cuid = cred->cr_uid;
		msqptr->msg_perm.uid = cred->cr_uid;
		msqptr->msg_perm.cgid = cred->cr_gid;
		msqptr->msg_perm.gid = cred->cr_gid;
		msqptr->msg_perm.mode = (msgflg & 0777);
		/* Make sure that the returned msqid is unique */
		msqptr->msg_perm.seq = (msqptr->msg_perm.seq + 1) & 0x7fff;
		msqptr->msg_first = NULL;
		msqptr->msg_last = NULL;
		msqptr->msg_cbytes = 0;
		msqptr->msg_qnum = 0;
		msqptr->msg_qbytes = msginfo.msgmnb;
		msqptr->msg_lspid = 0;
		msqptr->msg_lrpid = 0;
		msqptr->msg_stime = 0;
		msqptr->msg_rtime = 0;
		msqptr->msg_ctime = time_second;
	} else {
#ifdef MSG_DEBUG_OK
		kprintf("didn't find it and wasn't asked to create it\n");
#endif
		eval = ENOENT;
	}

done:
	rel_mplock();
	/* Construct the unique msqid */
	if (eval == 0)
		uap->sysmsg_result = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
	return(eval);
}
예제 #12
0
int
shmget_allocate_segment(struct proc *p,
	struct sys_shmget_args /* {
		syscallarg(key_t) key;
		syscallarg(size_t) size;
		syscallarg(int) shmflg;
	} */ *uap,
	int mode, register_t *retval)
{
	size_t size;
	key_t key;
	int segnum;
	struct ucred *cred = p->p_ucred;
	struct shmid_ds *shmseg;
	struct shm_handle *shm_handle;
	int error = 0;
	
	if (SCARG(uap, size) < shminfo.shmmin ||
	    SCARG(uap, size) > shminfo.shmmax)
		return (EINVAL);
	if (shm_nused >= shminfo.shmmni) /* any shmids left? */
		return (ENOSPC);
	size = round_page(SCARG(uap, size));
	if (shm_committed + atop(size) > shminfo.shmall)
		return (ENOMEM);
	shm_nused++;
	shm_committed += atop(size);

	/*
	 * If a key has been specified and we had to wait for memory
	 * to be freed up we need to verify that no one has allocated
	 * the key we want in the meantime.  Yes, this is ugly.
	 */
	key = SCARG(uap, key);
	shmseg = pool_get(&shm_pool, key == IPC_PRIVATE ? PR_WAITOK :
	    PR_NOWAIT);
	if (shmseg == NULL) {
		shmseg = pool_get(&shm_pool, PR_WAITOK);
		if (shm_find_segment_by_key(key) != -1) {
			pool_put(&shm_pool, shmseg);
			shm_nused--;
			shm_committed -= atop(size);
			return (EAGAIN);
		}
	}

	/* XXX - hash shmids instead */
	if (shm_last_free < 0) {
		for (segnum = 0; segnum < shminfo.shmmni && shmsegs[segnum];
		    segnum++)
			;
		if (segnum == shminfo.shmmni)
			panic("shmseg free count inconsistent");
	} else {
		segnum = shm_last_free;
		if (++shm_last_free >= shminfo.shmmni || shmsegs[shm_last_free])
			shm_last_free = -1;
	}
	shmsegs[segnum] = shmseg;

	shm_handle = (struct shm_handle *)((caddr_t)shmseg + sizeof(*shmseg));
	shm_handle->shm_object = uao_create(size, 0);

	shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid;
	shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid;
	shmseg->shm_perm.mode = (mode & ACCESSPERMS);
	shmseg->shm_perm.seq = shmseqs[segnum] = (shmseqs[segnum] + 1) & 0x7fff;
	shmseg->shm_perm.key = key;
	shmseg->shm_segsz = SCARG(uap, size);
	shmseg->shm_cpid = p->p_p->ps_pid;
	shmseg->shm_lpid = shmseg->shm_nattch = 0;
	shmseg->shm_atime = shmseg->shm_dtime = 0;
	shmseg->shm_ctime = time_second;
	shmseg->shm_internal = shm_handle;

	*retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
	return (error);
}
예제 #13
0
/* Create a shared memory segment and return the id. */
static int
shmget_allocate_segment(pid_t pid, struct shmget_msg *shmget_msg,
		int mode, struct cmsgcred *cred)
{
	int i, segnum, shmid;
	size_t size;
	struct shmid_ds *shmseg;
	struct shm_handle *handle;
#if 0
	/* It is possible after a process calls exec().
	 * We don't create another segment but return the old one
	 * with all information.
	 * This segment is destroyed only when process dies.
	 * */
	if (shmget_msg->type == UNDOGET) {
		struct client *cl= _hash_lookup(clientshash, pid);
		if (cl->undoid != -1)
			return cl->undoid;
	}
#endif
	if ((long)shmget_msg->size < shminfo.shmmin)
			//|| (long)shmget_msg->size > shminfo.shmmax)
			/* There is no need to check the max limit,
			 * the operating system do this for us.
			 */
		return (-EINVAL);
	if (shm_nused >= shminfo.shmmni) /* any shmids left? */
		return (-ENOSPC);

	/* Compute the size of the segment. */
	size = round_page(shmget_msg->size);

	/* Find a free entry in the shmsegs vector. */
	if (shm_last_free < 0) {
		//	shmrealloc();	/* maybe expand the shmsegs[] array */
		for (i = 0; i < shmalloced; i++) {
			if (shmsegs[i].shm_perm.mode & SHMSEG_FREE)
				break;
		}
		if (i == shmalloced) {
			sysvd_print("i == shmalloced\n");
			return (-ENOSPC);
		}
		segnum = i;
	} else  {
		segnum = shm_last_free;
		shm_last_free = -1;
	}
	shmseg = &shmsegs[segnum];
	/*
	 * In case we sleep in malloc(), mark the segment present but deleted
	 * so that noone else tries to create the same key.
	 */
	shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
	shmseg->shm_perm.key = shmget_msg->key;
	shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff;

	/* Create the file for the shared memory segment. */
	handle = shmseg->shm_internal = malloc(sizeof(struct shm_handle));
	handle->type = shmget_msg->type;
	handle->fd = create_sysv_file(shmget_msg, size, shmseg);
	if (handle->fd == -1) {
		free(handle);
		handle = NULL;
		shmseg->shm_perm.mode = SHMSEG_FREE;
		shm_last_free = segnum;
		errno = -ENFILE;
		return (-1);
	}

	LIST_INIT(&handle->attached_list);

	if (handle->fd < 0) {
		free(shmseg->shm_internal);
		shmseg->shm_internal = NULL;
		shm_last_free = segnum;
		shmseg->shm_perm.mode = SHMSEG_FREE;
		return (-errno);
	}

	/* Get the id. */
	shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);

	shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cmcred_euid;
	shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cmcred_gid;
	shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) |
		(mode & ACCESSPERMS) | SHMSEG_ALLOCATED;

	shmseg->shm_cpid = pid;
	shmseg->shm_lpid = shmseg->shm_nattch = 0;
	shmseg->shm_atime = shmseg->shm_dtime = 0;
	shmseg->shm_ctime = time(NULL);

	shmseg->shm_segsz = shmget_msg->size;
	shm_committed += btoc(size);
	shm_nused++;

	if (shmseg->shm_perm.mode & SHMSEG_WANTED) {
		/*
		 * Somebody else wanted this key while we were asleep.  Wake
		 * them up now.
		 */
		shmseg->shm_perm.mode &= ~SHMSEG_WANTED;
		//TODO multithreading
		//wakeup((caddr_t)shmseg);
	}
	shmseg->shm_perm.mode &= ~SHMSEG_REMOVED;

	if (shmget_msg->type == UNDOGET) {
		/* The file is used by daemon when clients terminates
		 * and sem_undo resources must be cleaned.
		 */
		struct client *cl= _hash_lookup(clientshash, pid);
		cl->undoid = shmid;
	}

	return (shmid);
}
예제 #14
0
파일: sysv_msg.c 프로젝트: genua/anoubis_os
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);
}
예제 #15
0
파일: sysv_msg.c 프로젝트: onlynone/xnu
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);
}
예제 #16
0
int
sys_semget(struct lwp *l, const struct sys_semget_args *uap, register_t *retval)
{
	/* {
		syscallarg(key_t) key;
		syscallarg(int) nsems;
		syscallarg(int) semflg;
	} */
	int semid, error = 0;
	int key = SCARG(uap, key);
	int nsems = SCARG(uap, nsems);
	int semflg = SCARG(uap, semflg);
	kauth_cred_t cred = l->l_cred;

	SEM_PRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg));

	mutex_enter(&semlock);

	if (key != IPC_PRIVATE) {
		for (semid = 0; semid < seminfo.semmni; semid++) {
			if ((sema[semid].sem_perm.mode & SEM_ALLOC) &&
			    sema[semid].sem_perm._key == key)
				break;
		}
		if (semid < seminfo.semmni) {
			SEM_PRINTF(("found public key\n"));
			if ((error = ipcperm(cred, &sema[semid].sem_perm,
			    semflg & 0700)))
			    	goto out;
			if (nsems > 0 && sema[semid].sem_nsems < nsems) {
				SEM_PRINTF(("too small\n"));
				error = EINVAL;
				goto out;
			}
			if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
				SEM_PRINTF(("not exclusive\n"));
				error = EEXIST;
				goto out;
			}
			goto found;
		}
	}

	SEM_PRINTF(("need to allocate the semid_ds\n"));
	if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) {
		if (nsems <= 0 || nsems > seminfo.semmsl) {
			SEM_PRINTF(("nsems out of range (0<%d<=%d)\n", nsems,
			    seminfo.semmsl));
			error = EINVAL;
			goto out;
		}
		if (nsems > seminfo.semmns - semtot) {
			SEM_PRINTF(("not enough semaphores left "
			    "(need %d, got %d)\n",
			    nsems, seminfo.semmns - semtot));
			error = ENOSPC;
			goto out;
		}
		for (semid = 0; semid < seminfo.semmni; semid++) {
			if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0)
				break;
		}
		if (semid == seminfo.semmni) {
			SEM_PRINTF(("no more semid_ds's available\n"));
			error = ENOSPC;
			goto out;
		}
		SEM_PRINTF(("semid %d is available\n", semid));
		sema[semid].sem_perm._key = key;
		sema[semid].sem_perm.cuid = kauth_cred_geteuid(cred);
		sema[semid].sem_perm.uid = kauth_cred_geteuid(cred);
		sema[semid].sem_perm.cgid = kauth_cred_getegid(cred);
		sema[semid].sem_perm.gid = kauth_cred_getegid(cred);
		sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC;
		sema[semid].sem_perm._seq =
		    (sema[semid].sem_perm._seq + 1) & 0x7fff;
		sema[semid].sem_nsems = nsems;
		sema[semid].sem_otime = 0;
		sema[semid].sem_ctime = time_second;
		sema[semid]._sem_base = &sem[semtot];
		semtot += nsems;
		memset(sema[semid]._sem_base, 0,
		    sizeof(sema[semid]._sem_base[0]) * nsems);
		SEM_PRINTF(("sembase = %p, next = %p\n", sema[semid]._sem_base,
		    &sem[semtot]));
	} else {
		SEM_PRINTF(("didn't find it and wasn't asked to create it\n"));
		error = ENOENT;
		goto out;
	}

 found:
	*retval = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm);
 out:
	mutex_exit(&semlock);
	return (error);
}
예제 #17
0
int
sys_msgget(struct lwp *l, const struct sys_msgget_args *uap, register_t *retval)
{
	/* {
		syscallarg(key_t) key;
		syscallarg(int) msgflg;
	} */
	int msqid, error = 0;
	int key = SCARG(uap, key);
	int msgflg = SCARG(uap, msgflg);
	kauth_cred_t cred = l->l_cred;
	struct msqid_ds *msqptr = NULL;
	kmsq_t *msq;

	mutex_enter(&msgmutex);

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

	if (key != IPC_PRIVATE) {
		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
			msq = &msqs[msqid];
			msqptr = &msq->msq_u;
			if (msqptr->msg_qbytes != 0 &&
			    msqptr->msg_perm._key == key)
				break;
		}
		if (msqid < msginfo.msgmni) {
			MSG_PRINTF(("found public key\n"));
			if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
				MSG_PRINTF(("not exclusive\n"));
				error = EEXIST;
				goto unlock;
			}
			if ((error = ipcperm(cred, &msqptr->msg_perm,
			    msgflg & 0700 ))) {
				MSG_PRINTF(("requester doesn't have 0%o access\n",
				    msgflg & 0700));
				goto unlock;
			}
			goto found;
		}
	}

	MSG_PRINTF(("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.
			 */
			msq = &msqs[msqid];
			msqptr = &msq->msq_u;
			if (msqptr->msg_qbytes == 0 &&
			    (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
				break;
		}
		if (msqid == msginfo.msgmni) {
			MSG_PRINTF(("no more msqid_ds's available\n"));
			error = ENOSPC;
			goto unlock;
		}
		MSG_PRINTF(("msqid %d is available\n", msqid));
		msqptr->msg_perm._key = key;
		msqptr->msg_perm.cuid = kauth_cred_geteuid(cred);
		msqptr->msg_perm.uid = kauth_cred_geteuid(cred);
		msqptr->msg_perm.cgid = kauth_cred_getegid(cred);
		msqptr->msg_perm.gid = kauth_cred_getegid(cred);
		msqptr->msg_perm.mode = (msgflg & 0777);
		/* Make sure that the returned msqid is unique */
		msqptr->msg_perm._seq++;
		msqptr->_msg_first = NULL;
		msqptr->_msg_last = NULL;
		msqptr->_msg_cbytes = 0;
		msqptr->msg_qnum = 0;
		msqptr->msg_qbytes = msginfo.msgmnb;
		msqptr->msg_lspid = 0;
		msqptr->msg_lrpid = 0;
		msqptr->msg_stime = 0;
		msqptr->msg_rtime = 0;
		msqptr->msg_ctime = time_second;
	} else {
		MSG_PRINTF(("didn't find it and wasn't asked to create it\n"));
		error = ENOENT;
		goto unlock;
	}

found:
	/* Construct the unique msqid */
	*retval = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);

unlock:
	mutex_exit(&msgmutex);
	return (error);
}