Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Sep 2016 22:46:20 +0000 (UTC)
From:      Mariusz Zaborski <oshogbo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305756 - in head/sys: kern sys
Message-ID:  <201609122246.u8CMkKoI044443@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oshogbo
Date: Mon Sep 12 22:46:19 2016
New Revision: 305756
URL: https://svnweb.freebsd.org/changeset/base/305756

Log:
  fd: add fget_cap and fget_cap_locked primitives
  
  They can be used to obtain capabilities along with a referenced fp.
  
  Reviewed by:	mjg@

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/sys/filedesc.h

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Mon Sep 12 22:07:35 2016	(r305755)
+++ head/sys/kern/kern_descrip.c	Mon Sep 12 22:46:19 2016	(r305756)
@@ -2446,6 +2446,77 @@ finit(struct file *fp, u_int flag, short
 }
 
 int
+fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+    struct file **fpp, struct filecaps *havecapsp)
+{
+	struct filedescent *fde;
+	int error;
+
+	FILEDESC_LOCK_ASSERT(fdp);
+
+	fde = fdeget_locked(fdp, fd);
+	if (fde == NULL) {
+		error = EBADF;
+		goto out;
+	}
+
+#ifdef CAPABILITIES
+	error = cap_check(cap_rights_fde(fde), needrightsp);
+	if (error != 0)
+		goto out;
+#endif
+
+	if (havecapsp != NULL)
+		filecaps_copy(&fde->fde_caps, havecapsp, true);
+
+	fhold(fde->fde_file);
+	*fpp = fde->fde_file;
+
+	error = 0;
+out:
+	return (error);
+}
+
+int
+fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+    struct file **fpp, struct filecaps *havecapsp)
+{
+	struct filedesc *fdp;
+	struct file *fp;
+	int error;
+	seq_t seq;
+
+	fdp = td->td_proc->p_fd;
+	for (;;) {
+		error = fget_unlocked(fdp, fd, needrightsp, &fp, &seq);
+		if (error != 0)
+			return (error);
+
+		if (havecapsp != NULL) {
+			if (!filecaps_copy(&fdp->fd_ofiles[fd].fde_caps,
+			    havecapsp, false)) {
+				fdrop(fp, td);
+				goto get_locked;
+			}
+		}
+
+		if (!fd_modified(fdp, fd, seq))
+			break;
+		fdrop(fp, td);
+	}
+
+	*fpp = fp;
+	return (0);
+
+get_locked:
+	FILEDESC_SLOCK(fdp);
+	error = fget_cap_locked(fdp, fd, needrightsp, fpp, havecapsp);
+	FILEDESC_SUNLOCK(fdp);
+
+	return (error);
+}
+
+int
 fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
     struct file **fpp, seq_t *seqp)
 {

Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h	Mon Sep 12 22:07:35 2016	(r305755)
+++ head/sys/sys/filedesc.h	Mon Sep 12 22:46:19 2016	(r305756)
@@ -190,6 +190,11 @@ int	getvnode(struct thread *td, int fd, 
 	    struct file **fpp);
 void	mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
 
+int	fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+	    struct file **fpp, struct filecaps *havecapsp);
+int	fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+	    struct file **fpp, struct filecaps *havecapsp);
+
 /* Return a referenced file from an unlocked descriptor. */
 int	fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 	    struct file **fpp, seq_t *seqp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609122246.u8CMkKoI044443>