Esempio n. 1
3
/*
 * Nfs server psuedo system call for the nfsd's
 * Based on the flag value it either:
 * - adds a socket to the selection list
 * - remains in the kernel as an nfsd
 * - remains in the kernel as an nfsiod
 * For INET6 we suppose that nfsd provides only IN6P_IPV6_V6ONLY sockets
 * and that mountd provides
 *  - sockaddr with no IPv4-mapped addresses
 *  - mask for both INET and INET6 families if there is IPv4-mapped overlap
 */
int
nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap)
{
	struct file *fp;
	struct nfsd_addsock_args addsockarg;
	struct nfsd_nfsd_args nfsdarg;
	int error;

	if (uap->flag & NFSSVC_ADDSOCK) {
		error = copyin(uap->argp, (caddr_t)&addsockarg,
		    sizeof(addsockarg));
		if (error)
			return (error);
		if ((error = fget(td, addsockarg.sock, CAP_SOCK_ALL, &fp)) != 0)
			return (error);
		if (fp->f_type != DTYPE_SOCKET) {
			fdrop(fp, td);
			return (error);	/* XXXRW: Should be EINVAL? */
		}
		error = nfssvc_addsock(fp, td);
		fdrop(fp, td);
	} else if (uap->flag & NFSSVC_OLDNFSD)
		error = nfssvc_nfsd(td, NULL);
	else if (uap->flag & NFSSVC_NFSD) {
		if (!uap->argp)
			return (EINVAL);
		error = copyin(uap->argp, (caddr_t)&nfsdarg,
		    sizeof(nfsdarg));
		if (error)
			return (error);
		error = nfssvc_nfsd(td, &nfsdarg);
	} else
		error = ENXIO;
	return (error);
}
Esempio n. 2
2
int
sys_ksem_destroy(struct thread *td, struct ksem_destroy_args *uap)
{
	struct file *fp;
	struct ksem *ks;
	int error;

	/* No capability rights required to close a semaphore. */
	error = ksem_get(td, uap->id, 0, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (!(ks->ks_flags & KS_ANONYMOUS)) {
		fdrop(fp, td);
		return (EINVAL);
	}
	mtx_lock(&sem_lock);
	if (ks->ks_waiters != 0) {
		mtx_unlock(&sem_lock);
		error = EBUSY;
		goto err;
	}
	ks->ks_flags |= KS_DEAD;
	mtx_unlock(&sem_lock);

	error = kern_close(td, uap->id);
err:
	fdrop(fp, td);
	return (error);
}
Esempio n. 3
2
int
sys_posix_openpt(struct thread *td, struct posix_openpt_args *uap)
{
	int error, fd;
	struct file *fp;

	/*
	 * POSIX states it's unspecified when other flags are passed. We
	 * don't allow this.
	 */
	if (uap->flags & ~(O_RDWR|O_NOCTTY|O_CLOEXEC))
		return (EINVAL);

	error = falloc(td, &fp, &fd, uap->flags);
	if (error)
		return (error);

	/* Allocate the actual pseudo-TTY. */
	error = pts_alloc(FFLAGS(uap->flags & O_ACCMODE), td, fp);
	if (error != 0) {
		fdclose(td, fp, fd);
		fdrop(fp, td);
		return (error);
	}

	/* Pass it back to userspace. */
	td->td_retval[0] = fd;
	fdrop(fp, td);

	return (0);
}
Esempio n. 4
1
int
sys_ksem_getvalue(struct thread *td, struct ksem_getvalue_args *uap)
{
	struct file *fp;
	struct ksem *ks;
	int error, val;

	error = ksem_get(td, uap->id, CAP_SEM_GETVALUE, &fp);
	if (error)
		return (error);
	ks = fp->f_data;

	mtx_lock(&sem_lock);
#ifdef MAC
	error = mac_posixsem_check_getvalue(td->td_ucred, fp->f_cred, ks);
	if (error) {
		mtx_unlock(&sem_lock);
		fdrop(fp, td);
		return (error);
	}
#endif
	val = ks->ks_value;
	vfs_timestamp(&ks->ks_atime);
	mtx_unlock(&sem_lock);
	fdrop(fp, td);
	error = copyout(&val, uap->val, sizeof(val));
	return (error);
}
Esempio n. 5
0
int
freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap)
{
	struct ioctl_args ap /*{
		int	fd;
		u_long	com;
		caddr_t	data;
	}*/ ;
	struct file *fp;
	cap_rights_t rights;
	int error;

	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
	if (error != 0)
		return (error);
	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
		fdrop(fp, td);
		return (EBADF);
	}

	switch (uap->com) {
	case MDIOCATTACH_32:	/* FALLTHROUGH */
	case MDIOCDETACH_32:	/* FALLTHROUGH */
	case MDIOCQUERY_32:	/* FALLTHROUGH */
	case MDIOCLIST_32:
		error = freebsd32_ioctl_md(td, uap, fp);
		break;

	case CDIOREADTOCENTRYS_32:
		error = freebsd32_ioctl_ioc_read_toc(td, uap, fp);
		break;

	case FIODGNAME_32:
		error = freebsd32_ioctl_fiodgname(td, uap, fp);
		break;

	case MEMRANGE_GET32:	/* FALLTHROUGH */
	case MEMRANGE_SET32:
		error = freebsd32_ioctl_memrange(td, uap, fp);
		break;

	case PCIOCGETCONF_32:
		error = freebsd32_ioctl_pciocgetconf(td, uap, fp);
		break;

	case SG_IO_32:
		error = freebsd32_ioctl_sg(td, uap, fp);
		break;

	default:
		fdrop(fp, td);
		ap.fd = uap->fd;
		ap.com = uap->com;
		PTRIN_CP(*uap, ap, data);
		return sys_ioctl(td, &ap);
	}

	fdrop(fp, td);
	return error;
}
Esempio n. 6
0
/*
 * File descriptors can be passed into an AF_NETGRAPH socket.
 * Note, that file descriptors cannot be passed OUT.
 * Only character device descriptors are accepted.
 * Character devices are useful to connect a graph to a device,
 * which after all is the purpose of this whole system.
 */
static int
ng_internalize(struct mbuf *control, struct thread *td)
{
	const struct cmsghdr *cm = mtod(control, const struct cmsghdr *);
	struct file *fp;
	struct vnode *vn;
	int oldfds;
	int fd;

	if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
	    cm->cmsg_len != control->m_len) {
		TRAP_ERROR;
		return (EINVAL);
	}

	/* Check there is only one FD. XXX what would more than one signify? */
	oldfds = ((caddr_t)cm + cm->cmsg_len - (caddr_t)data) / sizeof (int);
	if (oldfds != 1) {
		TRAP_ERROR;
		return (EINVAL);
	}

	/* Check that the FD given is legit. and change it to a pointer to a
	 * struct file. */
	fd = CMSG_DATA(cm);
	if ((error = fget(td, fd, &fp)) != 0)
		return (error);

	/* Depending on what kind of resource it is, act differently. For
	 * devices, we treat it as a file. For an AF_NETGRAPH socket,
	 * shortcut straight to the node. */
	switch (fp->f_type) {
	case DTYPE_VNODE:
		vn = fp->f_data;
		if (vn && (vn->v_type == VCHR)) {
			/* for a VCHR, actually reference the FILE */
			fhold(fp);
			/* XXX then what :) */
			/* how to pass on to other modules? */
		} else {
			fdrop(fp, td);
			TRAP_ERROR;
			return (EINVAL);
		}
		break;
	default:
		fdrop(fp, td);
		TRAP_ERROR;
		return (EINVAL);
	}
	fdrop(fp, td);
	return (0);
}
Esempio n. 7
0
static int
kttcp_recv(struct thread *td, struct kttcp_io_args *kio)
{
	struct file *fp;
	int error;
	struct timeval t0, t1;
	unsigned long long len = 0;
	struct uio auio;
	struct iovec aiov;

	bzero(&aiov, sizeof(aiov));
	bzero(&auio, sizeof(auio));
	auio.uio_iov = &aiov;
	auio.uio_segflg = UIO_NOCOPY;

	error = fget(td, kio->kio_socket, &fp);
	if (error != 0)
		return error;

	if ((fp->f_flag & FWRITE) == 0) {
		fdrop(fp, td);
		return EBADF;
	}
	if (fp->f_type == DTYPE_SOCKET) {
		len = kio->kio_totalsize;
		microtime(&t0);
		do {
			nbyte =  MIN(len, (unsigned long long)nbyte);
			aiov.iov_len = nbyte;
			auio.uio_resid = nbyte;
			auio.uio_offset = 0;
			error = soreceive((struct socket *)fp->f_data,
					  NULL, &auio, NULL, NULL, NULL);
			len -= auio.uio_offset;
		} while (error == 0 && len > 0 && auio.uio_offset != 0);
		microtime(&t1);
		if (error == EPIPE)
			error = 0;
	} else
		error = EFTYPE;
	fdrop(fp, td);
	if (error != 0)
		return error;
	timersub(&t1, &t0, &kio->kio_elapsed);

	kio->kio_bytesdone = kio->kio_totalsize - len;

	return 0;
}
Esempio n. 8
0
/*
 * Works similarly to nlookup_done() when nd initialized with
 * nlookup_init_at().
 */
void
nlookup_done_at(struct nlookupdata *nd, struct file *fp)
{
	nlookup_done(nd);
	if (fp != NULL)
		fdrop(fp);
}
Esempio n. 9
0
/*
 * fp_open:
 *
 *	Open a file as specified.  Use O_* flags for flags.
 *
 *	vn_open() asserts that the cred must match the process's cred.
 *
 *	NOTE! when fp_open() is called from a pure thread, root creds are
 *	used.
 */
int
fp_open(const char *path, int flags, int mode, file_t *fpp)
{
    struct nlookupdata nd;
    struct thread *td;
    struct file *fp;
    int error;

    if ((error = falloc(NULL, fpp, NULL)) != 0)
	return (error);
    fp = *fpp;
    td = curthread;
    if (td->td_proc)
	fsetcred(fp, td->td_proc->p_ucred);
    error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_LOCKVP);
    flags = FFLAGS(flags);
    if (error == 0)
	error = vn_open(&nd, fp, flags, mode);
    nlookup_done(&nd);
    if (error) {
	fdrop(fp);
	*fpp = NULL;
    }
    return(error);
}
Esempio n. 10
0
/*
 * The close() system call uses it's own audit call to capture the path/vnode
 * information because those pieces are not easily obtained within the system
 * call itself.
 */
void
audit_sysclose(struct thread *td, int fd)
{
	struct kaudit_record *ar;
	struct vnode *vp;
	struct file *fp;
	int vfslocked;

	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));

	ar = currecord();
	if (ar == NULL)
		return;

	audit_arg_fd(fd);

	if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
		return;

	vp = fp->f_vnode;
	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
	vn_lock(vp, LK_SHARED | LK_RETRY);
	audit_arg_vnode1(vp);
	VOP_UNLOCK(vp, 0);
	VFS_UNLOCK_GIANT(vfslocked);
	fdrop(fp, td);
}
Esempio n. 11
0
int
kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
{
	struct socket *so;
	struct file *fp;
	cap_rights_t rights;
	int error;

	AUDIT_ARG_FD(fd);
	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
	    &fp, NULL, NULL);
	if (error != 0)
		return (error);
	so = fp->f_data;
#ifdef KTRACE
	if (KTRPOINT(td, KTR_STRUCT))
		ktrsockaddr(sa);
#endif
#ifdef MAC
	error = mac_socket_check_bind(td->td_ucred, so, sa);
	if (error == 0) {
#endif
		if (dirfd == AT_FDCWD)
			error = sobind(so, sa, td);
		else
			error = sobindat(dirfd, so, sa, td);
#ifdef MAC
	}
#endif
	fdrop(fp, td);
	return (error);
}
Esempio n. 12
0
static void
filemon_dtr(void *data)
{
	struct filemon *filemon = data;

	if (filemon != NULL) {
		struct file *fp = filemon->fp;

		/* Get exclusive write access. */
		filemon_lock_write();

		/* Remove from the in-use list. */
		TAILQ_REMOVE(&filemons_inuse, filemon, link);

		filemon->fp = NULL;
		filemon->pid = -1;

		/* Add to the free list. */
		TAILQ_INSERT_TAIL(&filemons_free, filemon, link);

		/* Give up write access. */
		filemon_unlock_write();

		if (fp != NULL)
			fdrop(fp, curthread);
	}
}
Esempio n. 13
0
int
sys_ksem_post(struct thread *td, struct ksem_post_args *uap)
{
	struct file *fp;
	struct ksem *ks;
	int error;

	error = ksem_get(td, uap->id, CAP_SEM_POST, &fp);
	if (error)
		return (error);
	ks = fp->f_data;

	mtx_lock(&sem_lock);
#ifdef MAC
	error = mac_posixsem_check_post(td->td_ucred, fp->f_cred, ks);
	if (error)
		goto err;
#endif
	if (ks->ks_value == SEM_VALUE_MAX) {
		error = EOVERFLOW;
		goto err;
	}
	++ks->ks_value;
	if (ks->ks_waiters > 0)
		cv_signal(&ks->ks_cv);
	error = 0;
	vfs_timestamp(&ks->ks_ctime);
err:
	mtx_unlock(&sem_lock);
	fdrop(fp, td);
	return (error);
}
Esempio n. 14
0
/*
 * Close out the log.
 */
static void
filemon_close_log(struct filemon *filemon)
{
	struct file *fp;
	struct timeval now;
	size_t len;

	sx_assert(&filemon->lock, SA_XLOCKED);
	if (filemon->fp == NULL)
		return;

	getmicrotime(&now);

	len = snprintf(filemon->msgbufr,
	    sizeof(filemon->msgbufr),
	    "# Stop %ju.%06ju\n# Bye bye\n",
	    (uintmax_t)now.tv_sec, (uintmax_t)now.tv_usec);

	filemon_output(filemon, filemon->msgbufr, len);
	fp = filemon->fp;
	filemon->fp = NULL;

	sx_xunlock(&filemon->lock);
	fdrop(fp, curthread);
	sx_xlock(&filemon->lock);
}
Esempio n. 15
0
static void
translate_fd_major_minor(struct thread *td, int fd, struct stat *buf)
{
	struct file *fp;
	struct vnode *vp;
	int major, minor;

	/*
	 * No capability rights required here.
	 */
	if ((!S_ISCHR(buf->st_mode) && !S_ISBLK(buf->st_mode)) ||
	    fget(td, fd, 0, &fp) != 0)
		return;
	vp = fp->f_vnode;
	if (vp != NULL && vp->v_rdev != NULL &&
	    linux_driver_get_major_minor(devtoname(vp->v_rdev),
					 &major, &minor) == 0) {
		buf->st_rdev = (major << 8 | minor);
	} else if (fp->f_type == DTYPE_PTS) {
		struct tty *tp = fp->f_data;

		/* Convert the numbers for the slave device. */
		if (linux_driver_get_major_minor(devtoname(tp->t_dev),
					 &major, &minor) == 0) {
			buf->st_rdev = (major << 8 | minor);
		}
	}
	fdrop(fp, td);
}
Esempio n. 16
0
int
cloudabi_sys_fd_stat_get(struct thread *td,
    struct cloudabi_sys_fd_stat_get_args *uap)
{
	cloudabi_fdstat_t fsb = {};
	struct file *fp;
	cap_rights_t rights;
	struct filecaps fcaps;
	int error, oflags;

	/* Obtain file descriptor properties. */
	error = fget_cap(td, uap->fd, cap_rights_init(&rights), &fp,
	    &fcaps);
	if (error != 0)
		return (error);
	oflags = OFLAGS(fp->f_flag);
	fsb.fs_filetype = cloudabi_convert_filetype(fp);
	fdrop(fp, td);

	/* Convert file descriptor flags. */
	if (oflags & O_APPEND)
		fsb.fs_flags |= CLOUDABI_FDFLAG_APPEND;
	if (oflags & O_NONBLOCK)
		fsb.fs_flags |= CLOUDABI_FDFLAG_NONBLOCK;
	if (oflags & O_SYNC)
		fsb.fs_flags |= CLOUDABI_FDFLAG_SYNC;

	/* Convert capabilities to CloudABI rights. */
	convert_capabilities(&fcaps.fc_rights, fsb.fs_filetype,
	    &fsb.fs_rights_base, &fsb.fs_rights_inheriting);
	filecaps_free(&fcaps);
	return (copyout(&fsb, (void *)uap->buf, sizeof(fsb)));
}
Esempio n. 17
0
static int
aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
{
	struct file *fp;
#if __FreeBSD_version >= 900000
	cap_rights_t rights;
#endif
	u_long cmd;
	int error;

	if ((error = fget(td, args->fd,
#if __FreeBSD_version >= 900000
	    cap_rights_init(&rights, CAP_IOCTL),
#endif
	    &fp)) != 0) {
		return (error);
	}
	cmd = args->cmd;

	/*
	 * Pass the ioctl off to our standard handler.
	 */
	error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td->td_ucred, td));
	fdrop(fp, td);
	return (error);
}
Esempio n. 18
0
static int
ipmi_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
{
	cap_rights_t rights;
	struct file *fp;
	u_long cmd;
	int error;

	error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
	if (error != 0)
		return (error);
	cmd = args->cmd;

	switch(cmd) {
	case L_IPMICTL_GET_MY_ADDRESS_CMD:
		cmd = IPMICTL_GET_MY_ADDRESS_CMD;
		break;
	case L_IPMICTL_GET_MY_LUN_CMD:
		cmd = IPMICTL_GET_MY_LUN_CMD;
		break;
	}
	/*
	 * Pass the ioctl off to our standard handler.
	 */
	error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td->td_ucred, td));
	fdrop(fp, td);
	return (error);
}
Esempio n. 19
0
int
cloudabi_sys_fd_stat_get(struct thread *td,
    struct cloudabi_sys_fd_stat_get_args *uap)
{
	cloudabi_fdstat_t fsb = {};
	struct filedesc *fdp;
	struct file *fp;
	seq_t seq;
	cap_rights_t rights;
	int error, oflags;
	bool modified;

	/* Obtain file descriptor properties. */
	fdp = td->td_proc->p_fd;
	do {
		error = fget_unlocked(fdp, uap->fd, cap_rights_init(&rights),
		    &fp, &seq);
		if (error != 0)
			return (error);
		if (fp->f_ops == &badfileops) {
			fdrop(fp, td);
			return (EBADF);
		}

		rights = *cap_rights(fdp, uap->fd);
		oflags = OFLAGS(fp->f_flag);
		fsb.fs_filetype = cloudabi_convert_filetype(fp);

		modified = fd_modified(fdp, uap->fd, seq);
		fdrop(fp, td);
	} while (modified);

	/* Convert file descriptor flags. */
	if (oflags & O_APPEND)
		fsb.fs_flags |= CLOUDABI_FDFLAG_APPEND;
	if (oflags & O_NONBLOCK)
		fsb.fs_flags |= CLOUDABI_FDFLAG_NONBLOCK;
	if (oflags & O_SYNC)
		fsb.fs_flags |= CLOUDABI_FDFLAG_SYNC;

	/* Convert capabilities to CloudABI rights. */
	convert_capabilities(&rights, fsb.fs_filetype,
	    &fsb.fs_rights_base, &fsb.fs_rights_inheriting);
	return (copyout(&fsb, (void *)uap->buf, sizeof(fsb)));
}
Esempio n. 20
0
int
ksem_close(struct thread *td, struct ksem_close_args *uap)
{
	struct ksem *ks;
	struct file *fp;
	int error;

	error = ksem_get(td, uap->id, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (ks->ks_flags & KS_ANONYMOUS) {
		fdrop(fp, td);
		return (EINVAL);
	}
	error = kern_close(td, uap->id);
	fdrop(fp, td);
	return (error);
}
Esempio n. 21
0
static int
linux_getdents_error(struct thread *td, int fd, int err)
{
	struct vnode *vp;
	struct file *fp;
	int error;

	/* Linux return ENOTDIR in case when fd is not a directory. */
	error = getvnode(td, fd, &cap_read_rights, &fp);
	if (error != 0)
		return (error);
	vp = fp->f_vnode;
	if (vp->v_type != VDIR) {
		fdrop(fp, td);
		return (ENOTDIR);
	}
	fdrop(fp, td);
	return (err);
}
Esempio n. 22
0
int
pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd)
{
	struct proc *p;
	cap_rights_t rights;
	int error;

	sx_assert(&pmc_sx, SA_XLOCKED);
	PMCDBG2(LOG,CFG,1, "config po=%p logfd=%d", po, logfd);

	p = po->po_owner;

	/* return EBUSY if a log file was already present */
	if (po->po_flags & PMC_PO_OWNS_LOGFILE)
		return (EBUSY);

	KASSERT(po->po_file == NULL,
	    ("[pmclog,%d] po=%p file (%p) already present", __LINE__, po,
		po->po_file));

	/* get a reference to the file state */
	error = fget_write(curthread, logfd,
	    cap_rights_init(&rights, CAP_WRITE), &po->po_file);
	if (error)
		goto error;

	/* mark process as owning a log file */
	po->po_flags |= PMC_PO_OWNS_LOGFILE;

	/* mark process as using HWPMCs */
	PROC_LOCK(p);
	p->p_flag |= P_HWPMC;
	PROC_UNLOCK(p);

	/* create a log initialization entry */
	PMCLOG_RESERVE_WITH_ERROR(po, INITIALIZE,
	    sizeof(struct pmclog_initialize));
	PMCLOG_EMIT32(PMC_VERSION);
	PMCLOG_EMIT32(md->pmd_cputype);
	PMCLOG_DESPATCH(po);

	return (0);

 error:
	KASSERT(po->po_kthread == NULL, ("[pmclog,%d] po=%p kthread not "
	    "stopped", __LINE__, po));

	if (po->po_file)
		(void) fdrop(po->po_file, curthread);
	po->po_file  = NULL;	/* clear file and error state */
	po->po_error = 0;
	po->po_flags &= ~PMC_PO_OWNS_LOGFILE;

	return (error);
}
Esempio n. 23
0
static int
sysvipc_install_fd(struct proc *p_from, struct proc *p_to, int fd)
{
	struct filedesc *fdp_from = p_from->p_fd;
	struct filedesc *fdp_to = p_to->p_fd;
	
	struct file *fp;
	int error, newfd;
	int flags;

	/*
	 * Get the file corresponding to fd from the process p_from.
	 */
	spin_lock(&fdp_from->fd_spin);
	if ((unsigned)fd >= fdp_from->fd_nfiles || fdp_from->fd_files[fd].fp == NULL) {
		spin_unlock(&fdp_from->fd_spin);
		return (EBADF);
	}

	fp = fdp_from->fd_files[fd].fp;
	flags = fdp_from->fd_files[fd].fileflags;
	fhold(fp);	/* MPSAFE - can be called with a spinlock held */
	spin_unlock(&fdp_from->fd_spin);

	/*
	 * Reserve a fd in the process p_to.
	 */
	error = fdalloc(p_to, 1, &newfd);
	if (error) {
		fdrop(fp);
		return (error);
	}

	/*
	 * Set fd for the fp file.
	 */
	fsetfd(fdp_to, fp, newfd);
	fdp_to->fd_files[newfd].fileflags = flags;
	fdrop(fp);

	return (newfd);
}
Esempio n. 24
0
int
sys_ksem_close(struct thread *td, struct ksem_close_args *uap)
{
	struct ksem *ks;
	struct file *fp;
	int error;

	/* No capability rights required to close a semaphore. */
	error = ksem_get(td, uap->id, 0, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (ks->ks_flags & KS_ANONYMOUS) {
		fdrop(fp, td);
		return (EINVAL);
	}
	error = kern_close(td, uap->id);
	fdrop(fp, td);
	return (error);
}
Esempio n. 25
0
static int
fdesc_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
    struct vnode **rvp)
{
	struct fdesc_get_ino_args *a;
	int error;

	a = arg;
	error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp);
	fdrop(a->fp, a->td);
	return (error);
}
Esempio n. 26
0
static int
ksem_get(struct thread *td, semid_t id, cap_rights_t rights, struct file **fpp)
{
	struct ksem *ks;
	struct file *fp;
	int error;

	error = fget(td, id, rights, &fp);
	if (error)
		return (EINVAL);
	if (fp->f_type != DTYPE_SEM) {
		fdrop(fp, td);
		return (EINVAL);
	}
	ks = fp->f_data;
	if (ks->ks_flags & KS_DEAD) {
		fdrop(fp, td);
		return (EINVAL);
	}
	*fpp = fp;
	return (0);
}
Esempio n. 27
0
static int
amr_linux_ioctl(struct thread *p, struct linux_ioctl_args *args)
{
	cap_rights_t rights;
	struct file *fp;
	int error;

	error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
	if (error != 0)
		return (error);
	error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p);
	fdrop(fp, p);
	return (error);
}
Esempio n. 28
0
int
pmclog_deconfigure_log(struct pmc_owner *po)
{
	int error;
	struct pmclog_buffer *lb;

	PMCDBG1(LOG,CFG,1, "de-config po=%p", po);

	if ((po->po_flags & PMC_PO_OWNS_LOGFILE) == 0)
		return (EINVAL);

	KASSERT(po->po_sscount == 0,
	    ("[pmclog,%d] po=%p still owning SS PMCs", __LINE__, po));
	KASSERT(po->po_file != NULL,
	    ("[pmclog,%d] po=%p no log file", __LINE__, po));

	/* stop the kthread, this will reset the 'OWNS_LOGFILE' flag */
	pmclog_stop_kthread(po);

	KASSERT(po->po_kthread == NULL,
	    ("[pmclog,%d] po=%p kthread not stopped", __LINE__, po));

	/* return all queued log buffers to the global pool */
	while ((lb = TAILQ_FIRST(&po->po_logbuffers)) != NULL) {
		TAILQ_REMOVE(&po->po_logbuffers, lb, plb_next);
		PMCLOG_INIT_BUFFER_DESCRIPTOR(lb);
		mtx_lock_spin(&pmc_bufferlist_mtx);
		TAILQ_INSERT_HEAD(&pmc_bufferlist, lb, plb_next);
		mtx_unlock_spin(&pmc_bufferlist_mtx);
	}

	/* return the 'current' buffer to the global pool */
	if ((lb = po->po_curbuf) != NULL) {
		PMCLOG_INIT_BUFFER_DESCRIPTOR(lb);
		mtx_lock_spin(&pmc_bufferlist_mtx);
		TAILQ_INSERT_HEAD(&pmc_bufferlist, lb, plb_next);
		mtx_unlock_spin(&pmc_bufferlist_mtx);
	}

	/* drop a reference to the fd */
	if (po->po_file != NULL) {
		error = fdrop(po->po_file, curthread);
		po->po_file = NULL;
	} else
		error = 0;
	po->po_error = 0;

	return (error);
}
Esempio n. 29
0
static int
fdesc_setattr(struct vop_setattr_args *ap)
{
	struct vattr *vap = ap->a_vap;
	struct vnode *vp;
	struct mount *mp;
	struct file *fp;
	struct thread *td = curthread;
	cap_rights_t rights;
	unsigned fd;
	int error;

	/*
	 * Can't mess with the root vnode
	 */
	if (VTOFDESC(ap->a_vp)->fd_type == Froot)
		return (EACCES);

	fd = VTOFDESC(ap->a_vp)->fd_fd;

	/*
	 * Allow setattr where there is an underlying vnode.
	 */
	error = getvnode(td, fd,
	    cap_rights_init(&rights, CAP_EXTATTR_SET), &fp);
	if (error) {
		/*
		 * getvnode() returns EINVAL if the file descriptor is not
		 * backed by a vnode.  Silently drop all changes except
		 * chflags(2) in this case.
		 */
		if (error == EINVAL) {
			if (vap->va_flags != VNOVAL)
				error = EOPNOTSUPP;
			else
				error = 0;
		}
		return (error);
	}
	vp = fp->f_vnode;
	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) == 0) {
		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
		error = VOP_SETATTR(vp, ap->a_vap, ap->a_cred);
		VOP_UNLOCK(vp, 0);
		vn_finished_write(mp);
	}
	fdrop(fp, td);
	return (error);
}
Esempio n. 30
0
int
smb_dev2share(int fd, int mode, struct smb_cred *scred,
	struct smb_share **sspp)
{
	struct file *fp;
	struct vnode *vp;
	struct smb_dev *sdp;
	struct smb_share *ssp;
	struct cdev *dev;
	int error;

	fp = nsmb_getfp(scred->scr_td->td_proc->p_fd, fd, FREAD | FWRITE);
	if (fp == NULL)
		return EBADF;
	vp = fp->f_vnode;
	if (vp == NULL) {
		fdrop(fp, curthread);
		return EBADF;
	}
	if (vp->v_type != VCHR) {
		fdrop(fp, curthread);
		return EBADF;
	}
	dev = vp->v_rdev;
	SMB_CHECKMINOR(dev);
	ssp = sdp->sd_share;
	if (ssp == NULL) {
		fdrop(fp, curthread);
		return ENOTCONN;
	}
	error = smb_share_get(ssp, LK_EXCLUSIVE, scred);
	if (error == 0) 
		*sspp = ssp;
	fdrop(fp, curthread);
	return error;
}