Exemplo n.º 1
0
/* Converts FreeBSD's Capsicum rights to CloudABI's set of rights. */
static void
convert_capabilities(const cap_rights_t *capabilities,
    cloudabi_filetype_t filetype, cloudabi_rights_t *base,
    cloudabi_rights_t *inheriting)
{
	cloudabi_rights_t rights;

	/* Convert FreeBSD bits to CloudABI bits. */
	rights = 0;
#define MAPPING(cloudabi, ...) do {				\
	if (cap_rights_is_set(capabilities, ##__VA_ARGS__))	\
		rights |= (cloudabi);				\
} while (0);
	RIGHTS_MAPPINGS
#undef MAPPING

	*base = rights;
	*inheriting = rights;
	cloudabi_remove_conflicting_rights(filetype, base, inheriting);
}
Exemplo n.º 2
0
int
cloudabi_sys_fd_seek(struct thread *td, struct cloudabi_sys_fd_seek_args *uap)
{
	struct lseek_args lseek_args = {
		.fd	= uap->fd,
		.offset	= uap->offset
	};

	switch (uap->whence) {
	case CLOUDABI_WHENCE_CUR:
		lseek_args.whence = SEEK_CUR;
		break;
	case CLOUDABI_WHENCE_END:
		lseek_args.whence = SEEK_END;
		break;
	case CLOUDABI_WHENCE_SET:
		lseek_args.whence = SEEK_SET;
		break;
	default:
		return (EINVAL);
	}

	return (sys_lseek(td, &lseek_args));
}

/* Converts a file descriptor to a CloudABI file descriptor type. */
cloudabi_filetype_t
cloudabi_convert_filetype(const struct file *fp)
{
	struct socket *so;
	struct vnode *vp;

	switch (fp->f_type) {
	case DTYPE_FIFO:
		return (CLOUDABI_FILETYPE_FIFO);
	case DTYPE_KQUEUE:
		return (CLOUDABI_FILETYPE_POLL);
	case DTYPE_PIPE:
		return (CLOUDABI_FILETYPE_FIFO);
	case DTYPE_PROCDESC:
		return (CLOUDABI_FILETYPE_PROCESS);
	case DTYPE_SHM:
		return (CLOUDABI_FILETYPE_SHARED_MEMORY);
	case DTYPE_SOCKET:
		so = fp->f_data;
		switch (so->so_type) {
		case SOCK_DGRAM:
			return (CLOUDABI_FILETYPE_SOCKET_DGRAM);
		case SOCK_SEQPACKET:
			return (CLOUDABI_FILETYPE_SOCKET_SEQPACKET);
		case SOCK_STREAM:
			return (CLOUDABI_FILETYPE_SOCKET_STREAM);
		default:
			return (CLOUDABI_FILETYPE_UNKNOWN);
		}
	case DTYPE_VNODE:
		vp = fp->f_vnode;
		switch (vp->v_type) {
		case VBLK:
			return (CLOUDABI_FILETYPE_BLOCK_DEVICE);
		case VCHR:
			return (CLOUDABI_FILETYPE_CHARACTER_DEVICE);
		case VDIR:
			return (CLOUDABI_FILETYPE_DIRECTORY);
		case VFIFO:
			return (CLOUDABI_FILETYPE_FIFO);
		case VLNK:
			return (CLOUDABI_FILETYPE_SYMBOLIC_LINK);
		case VREG:
			return (CLOUDABI_FILETYPE_REGULAR_FILE);
		case VSOCK:
			return (CLOUDABI_FILETYPE_SOCKET_STREAM);
		default:
			return (CLOUDABI_FILETYPE_UNKNOWN);
		}
	default:
		return (CLOUDABI_FILETYPE_UNKNOWN);
	}
}

/* Removes rights that conflict with the file descriptor type. */
void
cloudabi_remove_conflicting_rights(cloudabi_filetype_t filetype,
    cloudabi_rights_t *base, cloudabi_rights_t *inheriting)
{

	/*
	 * CloudABI has a small number of additional rights bits to
	 * disambiguate between multiple purposes. Remove the bits that
	 * don't apply to the type of the file descriptor.
	 *
	 * As file descriptor access modes (O_ACCMODE) has been fully
	 * replaced by rights bits, CloudABI distinguishes between
	 * rights that apply to the file descriptor itself (base) versus
	 * rights of new file descriptors derived from them
	 * (inheriting). The code below approximates the pair by
	 * decomposing depending on the file descriptor type.
	 *
	 * We need to be somewhat accurate about which actions can
	 * actually be performed on the file descriptor, as functions
	 * like fcntl(fd, F_GETFL) are emulated on top of this.
	 */
	switch (filetype) {
	case CLOUDABI_FILETYPE_DIRECTORY:
		*base &= CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC | CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY |
		    CLOUDABI_RIGHT_FILE_CREATE_FILE |
		    CLOUDABI_RIGHT_FILE_CREATE_FIFO |
		    CLOUDABI_RIGHT_FILE_LINK_SOURCE |
		    CLOUDABI_RIGHT_FILE_LINK_TARGET |
		    CLOUDABI_RIGHT_FILE_OPEN |
		    CLOUDABI_RIGHT_FILE_READDIR |
		    CLOUDABI_RIGHT_FILE_READLINK |
		    CLOUDABI_RIGHT_FILE_RENAME_SOURCE |
		    CLOUDABI_RIGHT_FILE_RENAME_TARGET |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_FILE_STAT_GET |
		    CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES |
		    CLOUDABI_RIGHT_FILE_SYMLINK |
		    CLOUDABI_RIGHT_FILE_UNLINK |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY |
		    CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY;
		*inheriting &= CLOUDABI_RIGHT_FD_DATASYNC |
		    CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY |
		    CLOUDABI_RIGHT_FILE_CREATE_FILE |
		    CLOUDABI_RIGHT_FILE_CREATE_FIFO |
		    CLOUDABI_RIGHT_FILE_LINK_SOURCE |
		    CLOUDABI_RIGHT_FILE_LINK_TARGET |
		    CLOUDABI_RIGHT_FILE_OPEN |
		    CLOUDABI_RIGHT_FILE_READDIR |
		    CLOUDABI_RIGHT_FILE_READLINK |
		    CLOUDABI_RIGHT_FILE_RENAME_SOURCE |
		    CLOUDABI_RIGHT_FILE_RENAME_TARGET |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_FILE_STAT_GET |
		    CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES |
		    CLOUDABI_RIGHT_FILE_SYMLINK |
		    CLOUDABI_RIGHT_FILE_UNLINK |
		    CLOUDABI_RIGHT_MEM_MAP |
		    CLOUDABI_RIGHT_MEM_MAP_EXEC |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_PROC_EXEC |
		    CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY |
		    CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY;
		break;
	case CLOUDABI_FILETYPE_FIFO:
		*base &= CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_POLL:
		*base &= ~CLOUDABI_RIGHT_FILE_ADVISE;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_PROCESS:
		*base &= ~(CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE);
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_REGULAR_FILE:
		*base &= CLOUDABI_RIGHT_FD_DATASYNC |
		    CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_SYNC |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE |
		    CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES |
		    CLOUDABI_RIGHT_MEM_MAP |
		    CLOUDABI_RIGHT_MEM_MAP_EXEC |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_PROC_EXEC;
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_SHARED_MEMORY:
		*base &= ~(CLOUDABI_RIGHT_FD_SEEK |
		    CLOUDABI_RIGHT_FD_TELL |
		    CLOUDABI_RIGHT_FILE_ADVISE |
		    CLOUDABI_RIGHT_FILE_ALLOCATE |
		    CLOUDABI_RIGHT_FILE_READDIR);
		*inheriting = 0;
		break;
	case CLOUDABI_FILETYPE_SOCKET_DGRAM:
	case CLOUDABI_FILETYPE_SOCKET_SEQPACKET:
	case CLOUDABI_FILETYPE_SOCKET_STREAM:
		*base &= CLOUDABI_RIGHT_FD_READ |
		    CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS |
		    CLOUDABI_RIGHT_FD_WRITE |
		    CLOUDABI_RIGHT_FILE_STAT_FGET |
		    CLOUDABI_RIGHT_POLL_FD_READWRITE |
		    CLOUDABI_RIGHT_SOCK_ACCEPT |
		    CLOUDABI_RIGHT_SOCK_BIND_SOCKET |
		    CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET |
		    CLOUDABI_RIGHT_SOCK_LISTEN |
		    CLOUDABI_RIGHT_SOCK_SHUTDOWN |
		    CLOUDABI_RIGHT_SOCK_STAT_GET;
		break;
	default:
		*inheriting = 0;
		break;
	}
}

/* Converts FreeBSD's Capsicum rights to CloudABI's set of rights. */
static void
convert_capabilities(const cap_rights_t *capabilities,
    cloudabi_filetype_t filetype, cloudabi_rights_t *base,
    cloudabi_rights_t *inheriting)
{
	cloudabi_rights_t rights;

	/* Convert FreeBSD bits to CloudABI bits. */
	rights = 0;
#define MAPPING(cloudabi, ...) do {				\
	if (cap_rights_is_set(capabilities, ##__VA_ARGS__))	\
		rights |= (cloudabi);				\
} while (0);
	RIGHTS_MAPPINGS
#undef MAPPING

	*base = rights;
	*inheriting = rights;
	cloudabi_remove_conflicting_rights(filetype, base, inheriting);
}