コード例 #1
0
/*
 * For backward compatibility.
 */
int
sys_cap_new(struct thread *td, struct cap_new_args *uap)
{
	struct filedesc *fdp;
	cap_rights_t rights;
	register_t newfd;
	int error, fd;

	fd = uap->fd;
	rights = uap->rights;

	AUDIT_ARG_FD(fd);
	AUDIT_ARG_RIGHTS(rights);

	if ((rights & ~CAP_ALL) != 0)
		return (EINVAL);

	fdp = td->td_proc->p_fd;
	FILEDESC_SLOCK(fdp);
	if (fget_locked(fdp, fd) == NULL) {
		FILEDESC_SUNLOCK(fdp);
		return (EBADF);
	}
	error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
	FILEDESC_SUNLOCK(fdp);
	if (error != 0)
		return (error);

	error = do_dup(td, 0, fd, 0, &newfd);
	if (error != 0)
		return (error);

	FILEDESC_XLOCK(fdp);
	/*
	 * We don't really care about the race between checking capability
	 * rights for the source descriptor and now. If capability rights
	 * were ok at that earlier point, the process had this descriptor
	 * with those rights, so we don't increase them in security sense,
	 * the process might have done the cap_new(2) a bit earlier to get
	 * the same effect.
	 */
	fdp->fd_ofiles[newfd].fde_rights = rights;
	if ((rights & CAP_IOCTL) == 0) {
		free(fdp->fd_ofiles[newfd].fde_ioctls, M_TEMP);
		fdp->fd_ofiles[newfd].fde_ioctls = NULL;
		fdp->fd_ofiles[newfd].fde_nioctls = 0;
	}
	if ((rights & CAP_FCNTL) == 0)
		fdp->fd_ofiles[newfd].fde_fcntls = 0;
	FILEDESC_XUNLOCK(fdp);

	td->td_retval[0] = newfd;

	return (0);
}
コード例 #2
0
ファイル: sys_capability.c プロジェクト: 2trill2spill/freebsd
/*
 * System call to limit rights of the given capability.
 */
int
sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
{
	cap_rights_t rights;
	int error, version;

	cap_rights_init(&rights);

	error = copyin(uap->rightsp, &rights, sizeof(rights.cr_rights[0]));
	if (error != 0)
		return (error);
	version = CAPVER(&rights);
	if (version != CAP_RIGHTS_VERSION_00)
		return (EINVAL);

	error = copyin(uap->rightsp, &rights,
	    sizeof(rights.cr_rights[0]) * CAPARSIZE(&rights));
	if (error != 0)
		return (error);
	/* Check for race. */
	if (CAPVER(&rights) != version)
		return (EINVAL);

	if (!cap_rights_is_valid(&rights))
		return (EINVAL);

	if (version != CAP_RIGHTS_VERSION) {
		rights.cr_rights[0] &= ~(0x3ULL << 62);
		rights.cr_rights[0] |= ((uint64_t)CAP_RIGHTS_VERSION << 62);
	}
#ifdef KTRACE
	if (KTRPOINT(td, KTR_STRUCT))
		ktrcaprights(&rights);
#endif

	AUDIT_ARG_FD(uap->fd);
	AUDIT_ARG_RIGHTS(&rights);
	return (kern_cap_rights_limit(td, uap->fd, &rights));
}
コード例 #3
0
/*
 * System call to limit rights of the given capability.
 */
int
sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
{
	struct filedesc *fdp;
	cap_rights_t rights;
	int error, fd;

	fd = uap->fd;
	rights = uap->rights;

	AUDIT_ARG_FD(fd);
	AUDIT_ARG_RIGHTS(rights);

	if ((rights & ~CAP_ALL) != 0)
		return (EINVAL);

	fdp = td->td_proc->p_fd;
	FILEDESC_XLOCK(fdp);
	if (fget_locked(fdp, fd) == NULL) {
		FILEDESC_XUNLOCK(fdp);
		return (EBADF);
	}
	error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
	if (error == 0) {
		fdp->fd_ofiles[fd].fde_rights = rights;
		if ((rights & CAP_IOCTL) == 0) {
			free(fdp->fd_ofiles[fd].fde_ioctls, M_TEMP);
			fdp->fd_ofiles[fd].fde_ioctls = NULL;
			fdp->fd_ofiles[fd].fde_nioctls = 0;
		}
		if ((rights & CAP_FCNTL) == 0)
			fdp->fd_ofiles[fd].fde_fcntls = 0;
	}
	FILEDESC_XUNLOCK(fdp);
	return (error);
}
コード例 #4
0
ファイル: sys_capability.c プロジェクト: ChaosJohn/freebsd
/*
 * System call to limit rights of the given capability.
 */
int
sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap)
{
	struct filedesc *fdp;
	cap_rights_t rights;
	int error, fd, version;

	cap_rights_init(&rights);

	error = copyin(uap->rightsp, &rights, sizeof(rights.cr_rights[0]));
	if (error != 0)
		return (error);
	version = CAPVER(&rights);
	if (version != CAP_RIGHTS_VERSION_00)
		return (EINVAL);

	error = copyin(uap->rightsp, &rights,
	    sizeof(rights.cr_rights[0]) * CAPARSIZE(&rights));
	if (error != 0)
		return (error);
	/* Check for race. */
	if (CAPVER(&rights) != version)
		return (EINVAL);

	if (!cap_rights_is_valid(&rights))
		return (EINVAL);

	if (version != CAP_RIGHTS_VERSION) {
		rights.cr_rights[0] &= ~(0x3ULL << 62);
		rights.cr_rights[0] |= ((uint64_t)CAP_RIGHTS_VERSION << 62);
	}
#ifdef KTRACE
	if (KTRPOINT(td, KTR_STRUCT))
		ktrcaprights(&rights);
#endif

	fd = uap->fd;

	AUDIT_ARG_FD(fd);
	AUDIT_ARG_RIGHTS(&rights);

	fdp = td->td_proc->p_fd;
	FILEDESC_XLOCK(fdp);
	if (fget_locked(fdp, fd) == NULL) {
		FILEDESC_XUNLOCK(fdp);
		return (EBADF);
	}
	error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE);
	if (error == 0) {
		fdp->fd_ofiles[fd].fde_rights = rights;
		if (!cap_rights_is_set(&rights, CAP_IOCTL)) {
			free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS);
			fdp->fd_ofiles[fd].fde_ioctls = NULL;
			fdp->fd_ofiles[fd].fde_nioctls = 0;
		}
		if (!cap_rights_is_set(&rights, CAP_FCNTL))
			fdp->fd_ofiles[fd].fde_fcntls = 0;
	}
	FILEDESC_XUNLOCK(fdp);
	return (error);
}