Page MenuHomeFreeBSD

D21392.diff
No OneTemporary

D21392.diff

Index: head/sys/compat/cloudabi/cloudabi_fd.c
===================================================================
--- head/sys/compat/cloudabi/cloudabi_fd.c
+++ head/sys/compat/cloudabi/cloudabi_fd.c
@@ -28,6 +28,7 @@
#include <sys/param.h>
#include <sys/capsicum.h>
+#include <sys/fcntl.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/mman.h>
@@ -95,7 +96,7 @@
cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_FTRUNCATE,
CAP_MMAP_RWX);
return (kern_shm_open(td, SHM_ANON, O_RDWR | O_CLOEXEC, 0,
- &fcaps));
+ &fcaps, F_SEAL_SEAL));
default:
return (EINVAL);
}
Index: head/sys/kern/uipc_shm.c
===================================================================
--- head/sys/kern/uipc_shm.c
+++ head/sys/kern/uipc_shm.c
@@ -701,13 +701,14 @@
int
kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode,
- struct filecaps *fcaps)
+ struct filecaps *fcaps, int initial_seals)
{
struct filedesc *fdp;
struct shmfd *shmfd;
struct file *fp;
char *path;
const char *pr_path;
+ void *rl_cookie;
size_t pr_pathlen;
Fnv32_t fnv;
mode_t cmode;
@@ -730,6 +731,17 @@
if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
return (EINVAL);
+ /*
+ * Currently only F_SEAL_SEAL may be set when creating or opening shmfd.
+ * If the decision is made later to allow additional seals, care must be
+ * taken below to ensure that the seals are properly set if the shmfd
+ * already existed -- this currently assumes that only F_SEAL_SEAL can
+ * be set and doesn't take further precautions to ensure the validity of
+ * the seals being added with respect to current mappings.
+ */
+ if ((initial_seals & ~F_SEAL_SEAL) != 0)
+ return (EINVAL);
+
fdp = td->td_proc->p_fd;
cmode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
@@ -753,6 +765,7 @@
return (EINVAL);
}
shmfd = shm_alloc(td->td_ucred, cmode);
+ shmfd->shm_seals = initial_seals;
} else {
path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK);
pr_path = td->td_ucred->cr_prison->pr_path;
@@ -789,6 +802,7 @@
if (error == 0) {
#endif
shmfd = shm_alloc(td->td_ucred, cmode);
+ shmfd->shm_seals = initial_seals;
shm_insert(path, fnv, shmfd);
#ifdef MAC
}
@@ -798,12 +812,39 @@
error = ENOENT;
}
} else {
+ rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
+ &shmfd->shm_mtx);
+
/*
+ * kern_shm_open() likely shouldn't ever error out on
+ * trying to set a seal that already exists, unlike
+ * F_ADD_SEALS. This would break terribly as
+ * shm_open(2) actually sets F_SEAL_SEAL to maintain
+ * historical behavior where the underlying file could
+ * not be sealed.
+ */
+ initial_seals &= ~shmfd->shm_seals;
+
+ /*
* Object already exists, obtain a new
* reference if requested and permitted.
*/
free(path, M_SHMFD);
- if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+
+ /*
+ * initial_seals can't set additional seals if we've
+ * already been set F_SEAL_SEAL. If F_SEAL_SEAL is set,
+ * then we've already removed that one from
+ * initial_seals. This is currently redundant as we
+ * only allow setting F_SEAL_SEAL at creation time, but
+ * it's cheap to check and decreases the effort required
+ * to allow additional seals.
+ */
+ if ((shmfd->shm_seals & F_SEAL_SEAL) != 0 &&
+ initial_seals != 0)
+ error = EPERM;
+ else if ((flags & (O_CREAT | O_EXCL)) ==
+ (O_CREAT | O_EXCL))
error = EEXIST;
else {
#ifdef MAC
@@ -823,15 +864,27 @@
if (error == 0 &&
(flags & (O_ACCMODE | O_TRUNC)) ==
(O_RDWR | O_TRUNC)) {
+ VM_OBJECT_WLOCK(shmfd->shm_object);
#ifdef MAC
error = mac_posixshm_check_truncate(
td->td_ucred, fp->f_cred, shmfd);
if (error == 0)
#endif
- shm_dotruncate(shmfd, 0);
+ error = shm_dotruncate_locked(shmfd, 0,
+ rl_cookie);
+ VM_OBJECT_WUNLOCK(shmfd->shm_object);
}
- if (error == 0)
+ if (error == 0) {
+ /*
+ * Currently we only allow F_SEAL_SEAL to be
+ * set initially. As noted above, this would
+ * need to be reworked should that change.
+ */
+ shmfd->shm_seals |= initial_seals;
shm_hold(shmfd);
+ }
+ rangelock_unlock(&shmfd->shm_rl, rl_cookie,
+ &shmfd->shm_mtx);
}
sx_xunlock(&shm_dict_lock);
@@ -856,7 +909,7 @@
{
return (kern_shm_open(td, uap->path, uap->flags | O_CLOEXEC, uap->mode,
- NULL));
+ NULL, F_SEAL_SEAL));
}
int
Index: head/sys/sys/syscallsubr.h
===================================================================
--- head/sys/sys/syscallsubr.h
+++ head/sys/sys/syscallsubr.h
@@ -250,7 +250,7 @@
int kern_settimeofday(struct thread *td, struct timeval *tv,
struct timezone *tzp);
int kern_shm_open(struct thread *td, const char *userpath, int flags,
- mode_t mode, struct filecaps *fcaps);
+ mode_t mode, struct filecaps *fcaps, int initial_seals);
int kern_shmat(struct thread *td, int shmid, const void *shmaddr,
int shmflg);
int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf,

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 10, 1:41 PM (3 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25095480
Default Alt Text
D21392.diff (5 KB)

Event Timeline