aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/cloudabi
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2016-02-23 09:22:00 +0000
committerEd Schouten <ed@FreeBSD.org>2016-02-23 09:22:00 +0000
commit70907712becde750d06bc4eb34e85535596141e5 (patch)
tree9d9432b6e1a219b117bd05894e14502cb1fcf240 /sys/compat/cloudabi
parenta0a3cf18ecfc770be4b67b2a3377e6eb8f397079 (diff)
downloadsrc-70907712becde750d06bc4eb34e85535596141e5.tar.gz
src-70907712becde750d06bc4eb34e85535596141e5.zip
Make handling of mmap()'s prot argument more strict.
- Make the system call fail if prot contains bits other than read, write and exec. - Similar to OpenBSD's W^X, don't allow write and exec to be set at the same time. I'd like to see for now what happens if we enforce this policy unconditionally. If it turns out that this is far too strict, we'll loosen this requirement.
Notes
Notes: svn path=/head/; revision=295917
Diffstat (limited to 'sys/compat/cloudabi')
-rw-r--r--sys/compat/cloudabi/cloudabi_mem.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/sys/compat/cloudabi/cloudabi_mem.c b/sys/compat/cloudabi/cloudabi_mem.c
index 5bc5a19adc68..9d82673ae741 100644
--- a/sys/compat/cloudabi/cloudabi_mem.c
+++ b/sys/compat/cloudabi/cloudabi_mem.c
@@ -35,18 +35,26 @@ __FBSDID("$FreeBSD$");
/* Converts CloudABI's memory protection flags to FreeBSD's. */
static int
-convert_mprot(cloudabi_mprot_t in)
+convert_mprot(cloudabi_mprot_t in, int *out)
{
- int out;
- out = 0;
+ /* Unknown protection flags. */
+ if ((in & ~(CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE |
+ CLOUDABI_PROT_READ)) != 0)
+ return (ENOTSUP);
+ /* W^X: Write and exec cannot be enabled at the same time. */
+ if ((in & (CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE)) ==
+ (CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE))
+ return (ENOTSUP);
+
+ *out = 0;
if (in & CLOUDABI_PROT_EXEC)
- out |= PROT_EXEC;
+ *out |= PROT_EXEC;
if (in & CLOUDABI_PROT_WRITE)
- out |= PROT_WRITE;
+ *out |= PROT_WRITE;
if (in & CLOUDABI_PROT_READ)
- out |= PROT_READ;
- return (out);
+ *out |= PROT_READ;
+ return (0);
}
int
@@ -98,10 +106,10 @@ cloudabi_sys_mem_map(struct thread *td, struct cloudabi_sys_mem_map_args *uap)
struct mmap_args mmap_args = {
.addr = uap->addr,
.len = uap->len,
- .prot = convert_mprot(uap->prot),
.fd = uap->fd,
.pos = uap->off
};
+ int error;
/* Translate flags. */
if (uap->flags & CLOUDABI_MAP_ANON)
@@ -113,6 +121,11 @@ cloudabi_sys_mem_map(struct thread *td, struct cloudabi_sys_mem_map_args *uap)
if (uap->flags & CLOUDABI_MAP_SHARED)
mmap_args.flags |= MAP_SHARED;
+ /* Translate protection. */
+ error = convert_mprot(uap->prot, &mmap_args.prot);
+ if (error != 0)
+ return (error);
+
return (sys_mmap(td, &mmap_args));
}
@@ -123,8 +136,13 @@ cloudabi_sys_mem_protect(struct thread *td,
struct mprotect_args mprotect_args = {
.addr = uap->addr,
.len = uap->len,
- .prot = convert_mprot(uap->prot),
};
+ int error;
+
+ /* Translate protection. */
+ error = convert_mprot(uap->prot, &mprotect_args.prot);
+ if (error != 0)
+ return (error);
return (sys_mprotect(td, &mprotect_args));
}