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
This commit is contained in:
Jonathan Anderson 2011-07-15 18:26:19 +00:00
parent ba4579a7b9
commit cfb9df5541
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224066
4 changed files with 85 additions and 4 deletions

View File

@ -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

View File

@ -211,6 +211,59 @@ cap_rights(struct file *fp_cap)
return (c->cap_rights);
}
/*
* 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.
*/
@ -422,6 +475,20 @@ capability_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
* Stub Capability functions for when options CAPABILITIES isn't compiled
* 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)
{

View File

@ -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

View File

@ -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 */