summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonathan <jonathan@FreeBSD.org>2011-07-15 18:26:19 +0000
committerjonathan <jonathan@FreeBSD.org>2011-07-15 18:26:19 +0000
commit4ec3aaddb5d1848253bf9cb9b4dfccc67a058d4d (patch)
tree240261c2ac1f0d6c197b3869fcd42bcffeab635f
parent22fe1722a8552b76089b0bbb9265e6d9586a56a0 (diff)
downloadFreeBSD-src-4ec3aaddb5d1848253bf9cb9b4dfccc67a058d4d.zip
FreeBSD-src-4ec3aaddb5d1848253bf9cb9b4dfccc67a058d4d.tar.gz
Add cap_new() and cap_getrights() system calls.
Implement two previously-reserved Capsicum system calls: - cap_new() creates a capability to wrap an existing file descriptor - cap_getrights() queries the rights mask of a capability. Approved by: mentor (rwatson), re (Capsicum blanket) Sponsored by: Google Inc
-rw-r--r--sys/compat/freebsd32/syscalls.master5
-rw-r--r--sys/kern/sys_capability.c67
-rw-r--r--sys/kern/syscalls.master5
-rw-r--r--sys/sys/capability.h12
4 files changed, 85 insertions, 4 deletions
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 3e19298..d4b67ae 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -957,8 +957,9 @@
512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32 *buf); }
513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); }
-514 AUE_CAP_NEW UNIMPL cap_new
-515 AUE_CAP_GETRIGHTS UNIMPL cap_getrights
+514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, u_int64_t rights); }
+515 AUE_CAP_GETRIGHTS NOPROTO { int cap_getrights(int fd, \
+ u_int64_t *rightsp); }
516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); }
517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); }
518 AUE_PDFORK UNIMPL pdfork
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
index 9cbe462..04f98d8 100644
--- a/sys/kern/sys_capability.c
+++ b/sys/kern/sys_capability.c
@@ -212,6 +212,59 @@ cap_rights(struct file *fp_cap)
}
/*
+ * System call to create a new capability reference to either an existing
+ * file object or an an existing capability.
+ */
+int
+cap_new(struct thread *td, struct cap_new_args *uap)
+{
+ int error, capfd;
+ int fd = uap->fd;
+ struct file *fp, *fcapp;
+ cap_rights_t rights = uap->rights;
+
+ AUDIT_ARG_FD(fd);
+#ifdef notyet /* capability auditing will follow in a few commits */
+ AUDIT_ARG_RIGHTS(rights);
+#endif
+ error = fget(td, fd, &fp);
+ if (error)
+ return (error);
+ AUDIT_ARG_FILE(td->td_proc, fp);
+ error = kern_capwrap(td, fp, rights, &fcapp, &capfd);
+ if (error)
+ return (error);
+
+ /*
+ * Release our reference to the file (kern_capwrap has held a reference
+ * for the filedesc array).
+ */
+ fdrop(fp, td);
+ td->td_retval[0] = capfd;
+ return (0);
+}
+
+/*
+ * System call to query the rights mask associated with a capability.
+ */
+int
+cap_getrights(struct thread *td, struct cap_getrights_args *uap)
+{
+ struct capability *cp;
+ struct file *fp;
+ int error;
+
+ AUDIT_ARG_FD(uap->fd);
+ error = fgetcap(td, uap->fd, &fp);
+ if (error)
+ return (error);
+ cp = fp->f_data;
+ error = copyout(&cp->cap_rights, uap->rightsp, sizeof(*uap->rightsp));
+ fdrop(fp, td);
+ return (error);
+}
+
+/*
* Create a capability to wrap around an existing file.
*/
int
@@ -423,6 +476,20 @@ capability_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
* into the kernel.
*/
int
+cap_new(struct thread *td, struct cap_new_args *uap)
+{
+
+ return (ENOSYS);
+}
+
+int
+cap_getrights(struct thread *td, struct cap_getrights_args *uap)
+{
+
+ return (ENOSYS);
+}
+
+int
cap_funwrap(struct file *fp_cap, cap_rights_t rights, struct file **fpp)
{
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index af958c9..0b249a5 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -914,8 +914,9 @@
512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
struct shmid_ds *buf); }
513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); }
-514 AUE_CAP_NEW UNIMPL cap_new
-515 AUE_CAP_GETRIGHTS UNIMPL cap_getrights
+514 AUE_CAP_NEW STD { int cap_new(int fd, u_int64_t rights); }
+515 AUE_CAP_GETRIGHTS STD { int cap_getrights(int fd, \
+ u_int64_t *rightsp); }
516 AUE_CAP_ENTER STD { int cap_enter(void); }
517 AUE_CAP_GETMODE STD { int cap_getmode(u_int *modep); }
518 AUE_PDFORK UNIMPL pdfork
diff --git a/sys/sys/capability.h b/sys/sys/capability.h
index 5f5c35e..dee2e7a 100644
--- a/sys/sys/capability.h
+++ b/sys/sys/capability.h
@@ -110,6 +110,18 @@ int cap_enter(void);
*/
int cap_getmode(u_int* modep);
+/*
+ * cap_new(): Create a new capability derived from an existing file
+ * descriptor with the specified rights. If the existing file descriptor is
+ * a capability, then the new rights must be a subset of the existing rights.
+ */
+int cap_new(int fd, cap_rights_t rights);
+
+/*
+ * cap_getrights(): Query the rights on a capability.
+ */
+int cap_getrights(int fd, cap_rights_t *rightsp);
+
__END_DECLS
#endif /* !_KERNEL */
OpenPOWER on IntegriCloud