summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2015-08-01 07:21:14 +0000
committered <ed@FreeBSD.org>2015-08-01 07:21:14 +0000
commit385a6dbe103dd390121f82f61ea3eea820e4efe8 (patch)
tree6aa7dc7a074eaff90d2fd464e02ca54be0aa85b9 /sys/kern
parentf8fda3f34a999b7111674a9a0a006a57bab057bd (diff)
downloadFreeBSD-src-385a6dbe103dd390121f82f61ea3eea820e4efe8.zip
FreeBSD-src-385a6dbe103dd390121f82f61ea3eea820e4efe8.tar.gz
Add kern_shm_open().
This allows you to specify the capabilities that the new file descriptor should have. This allows us to create shared memory objects that only have the rights we're interested in. The idea behind restricting the rights is that it makes it a lot easier for CloudABI to get consistent behaviour across different operating systems. We only need to make sure that a shared memory implementation consistently implements the operations that are whitelisted. Approved by: kib Obtained from: https://github.com/NuxiNL/freebsd
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_shm.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index fb84330..21cbe49 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
#include <sys/stat.h>
+#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
@@ -683,9 +684,9 @@ shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
return (ENOENT);
}
-/* System calls. */
int
-sys_shm_open(struct thread *td, struct shm_open_args *uap)
+kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode,
+ struct filecaps *fcaps)
{
struct filedesc *fdp;
struct shmfd *shmfd;
@@ -699,28 +700,27 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
/*
* shm_open(2) is only allowed for anonymous objects.
*/
- if (IN_CAPABILITY_MODE(td) && (uap->path != SHM_ANON))
+ if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON))
return (ECAPMODE);
#endif
- if ((uap->flags & O_ACCMODE) != O_RDONLY &&
- (uap->flags & O_ACCMODE) != O_RDWR)
+ if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR)
return (EINVAL);
- if ((uap->flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
+ if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
return (EINVAL);
fdp = td->td_proc->p_fd;
- cmode = (uap->mode & ~fdp->fd_cmask) & ACCESSPERMS;
+ cmode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
- error = falloc(td, &fp, &fd, O_CLOEXEC);
+ error = falloc_caps(td, &fp, &fd, O_CLOEXEC, fcaps);
if (error)
return (error);
/* A SHM_ANON path pointer creates an anonymous object. */
- if (uap->path == SHM_ANON) {
+ if (userpath == SHM_ANON) {
/* A read-only anonymous object is pointless. */
- if ((uap->flags & O_ACCMODE) == O_RDONLY) {
+ if ((flags & O_ACCMODE) == O_RDONLY) {
fdclose(td, fp, fd);
fdrop(fp, td);
return (EINVAL);
@@ -728,7 +728,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
shmfd = shm_alloc(td->td_ucred, cmode);
} else {
path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK);
- error = copyinstr(uap->path, path, MAXPATHLEN, NULL);
+ error = copyinstr(userpath, path, MAXPATHLEN, NULL);
#ifdef KTRACE
if (error == 0 && KTRPOINT(curthread, KTR_NAMEI))
ktrnamei(path);
@@ -748,7 +748,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
shmfd = shm_lookup(path, fnv);
if (shmfd == NULL) {
/* Object does not yet exist, create it if requested. */
- if (uap->flags & O_CREAT) {
+ if (flags & O_CREAT) {
#ifdef MAC
error = mac_posixshm_check_create(td->td_ucred,
path);
@@ -769,17 +769,16 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
* reference if requested and permitted.
*/
free(path, M_SHMFD);
- if ((uap->flags & (O_CREAT | O_EXCL)) ==
- (O_CREAT | O_EXCL))
+ if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
error = EEXIST;
else {
#ifdef MAC
error = mac_posixshm_check_open(td->td_ucred,
- shmfd, FFLAGS(uap->flags & O_ACCMODE));
+ shmfd, FFLAGS(flags & O_ACCMODE));
if (error == 0)
#endif
error = shm_access(shmfd, td->td_ucred,
- FFLAGS(uap->flags & O_ACCMODE));
+ FFLAGS(flags & O_ACCMODE));
}
/*
@@ -788,7 +787,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
* opened with read/write.
*/
if (error == 0 &&
- (uap->flags & (O_ACCMODE | O_TRUNC)) ==
+ (flags & (O_ACCMODE | O_TRUNC)) ==
(O_RDWR | O_TRUNC)) {
#ifdef MAC
error = mac_posixshm_check_truncate(
@@ -809,7 +808,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
}
}
- finit(fp, FFLAGS(uap->flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);
+ finit(fp, FFLAGS(flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);
td->td_retval[0] = fd;
fdrop(fp, td);
@@ -817,6 +816,14 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap)
return (0);
}
+/* System calls. */
+int
+sys_shm_open(struct thread *td, struct shm_open_args *uap)
+{
+
+ return (kern_shm_open(td, uap->path, uap->flags, uap->mode, NULL));
+}
+
int
sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap)
{
OpenPOWER on IntegriCloud