svn commit: r305756 - in head/sys: kern sys
Mariusz Zaborski
oshogbo at FreeBSD.org
Mon Sep 12 22:46:21 UTC 2016
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);
More information about the svn-src-all
mailing list