Skip to content

Commit

Permalink
fixup: squash PROT_READ_CAP and PROT_WRITE_CAP
Browse files Browse the repository at this point in the history
  • Loading branch information
brooksdavis committed Aug 27, 2024
1 parent f33a82e commit 31a8f5a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 120 deletions.
28 changes: 9 additions & 19 deletions bin/cheribsdtest/cheribsdtest_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ CHERIBSDTEST(vm_tag_mmap_anon,
CHERIBSDTEST(vm_tag_mmap_anon_cap,
"check tags are stored for MAP_ANON pages with explicit permissions")
{
mmap_and_check_tag_stored(-1,
PROT_READ | PROT_WRITE | PROT_READ_CAP | PROT_WRITE_CAP, MAP_ANON);
mmap_and_check_tag_stored(-1, PROT_READ | PROT_WRITE | PROT_CAP,
MAP_ANON);
cheribsdtest_success();
}

Expand All @@ -136,7 +136,7 @@ CHERIBSDTEST(vm_notag_mmap_no_cap,
int v;

cp = CHERIBSDTEST_CHECK_SYSCALL(mmap(NULL, getpagesize(),
PROT_READ | PROT_WRITE | PROT_NO_IMPLY_CAP, MAP_ANON, -1, 0));
PROT_READ | PROT_WRITE | PROT_NO_CAP, MAP_ANON, -1, 0));
cheribsdtest_set_expected_si_addr(NULL_DERIVED_VOIDP(cp));
cp_value = cheri_ptr(&v, sizeof(v));
*cp = cp_value;
Expand All @@ -158,7 +158,7 @@ CHERIBSDTEST(vm_notag_mprotect_no_cap,
cp = CHERIBSDTEST_CHECK_SYSCALL(mmap(NULL, getpagesize(),
PROT_READ | PROT_WRITE, MAP_ANON, -1, 0));
CHERIBSDTEST_CHECK_SYSCALL(mprotect(__DEVOLATILE(void *, cp),
getpagesize(), PROT_READ | PROT_WRITE | PROT_NO_IMPLY_CAP));
getpagesize(), PROT_READ | PROT_WRITE | PROT_NO_CAP));
cheribsdtest_set_expected_si_addr(NULL_DERIVED_VOIDP(cp));
cp_value = cheri_ptr(&v, sizeof(v));
*cp = cp_value;
Expand All @@ -180,23 +180,13 @@ CHERIBSDTEST(vm_mmap_diallowed_prot,
ENOTSUP);

/* Mixing implied and explict protections */
mmap_check_bad_protections(PROT_READ | PROT_READ_CAP |
PROT_MAX(PROT_READ), ENOTSUP);
mmap_check_bad_protections(PROT_READ | PROT_CAP | PROT_MAX(PROT_READ),
ENOTSUP);

/* Disallowed explicit capability protection combinations */
mmap_check_bad_protections(PROT_READ_CAP, ENOTSUP);
mmap_check_bad_protections(PROT_WRITE_CAP, ENOTSUP);
mmap_check_bad_protections(PROT_MAX(PROT_READ_CAP), ENOTSUP);
mmap_check_bad_protections(PROT_MAX(PROT_WRITE_CAP), ENOTSUP);
mmap_check_bad_protections(PROT_READ | PROT_WRITE | PROT_READ_CAP,
ENOTSUP);
mmap_check_bad_protections(PROT_READ | PROT_WRITE | PROT_WRITE_CAP,
ENOTSUP);
mmap_check_bad_protections(PROT_MAX(PROT_READ | PROT_WRITE |
PROT_READ_CAP), ENOTSUP);
mmap_check_bad_protections(PROT_MAX(PROT_READ | PROT_WRITE |
PROT_WRITE_CAP),
ENOTSUP);
mmap_check_bad_protections(PROT_CAP, ENOTSUP);
mmap_check_bad_protections(PROT_MAX(PROT_CAP), ENOTSUP);

cheribsdtest_success();
}

Expand Down
69 changes: 31 additions & 38 deletions lib/libsys/mmap.2
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ argument by
.Em or Ns 'ing
the following values:
.Pp
.Bl -tag -width PROT_NO_IMPLY_CAP -compact
.Bl -tag -width PROT_NO_CAP -compact
.It Dv PROT_NONE
Pages may not be accessed.
.It Dv PROT_READ
Expand All @@ -113,46 +113,42 @@ Pages may be read.
Pages may be written.
.It Dv PROT_EXEC
Pages may be executed.
.It Dv PROT_READ_CAP
CHERI capabilities may be read from pages.
.It Dv PROT_WRITE_CAP
CHERI capabilities may be written to pages.
.It Dv PROT_NO_IMPLY_CAP
.It Dv PROT_CAP
CHERI capabilities may be read or written as dictated by
.Dv PROT_READ
and
.Dv PROT_WRITE .
.It Dv PROT_NO_CAP
Respect the absence of
.Dv PROT_READ_CAP/PROT_WRITE_CAP .
.Dv PROT_CAP .
.El
.Pp
On CHERI platforms, compatability is retained with unmodified POSIX
programs by implying
.Dv PROT_READ_CAP
and
.Dv PROT_WRITE_CAP
based on the presence of
.Dv PROT_CAP
if either of
.Dv PROT_READ
and
.Dv PROT_WRITE
respectively, unless the underlying backing store can not safety support
is set unless the underlying backing store can not safety support
capabilities (e.g., a
.Dv MAP_SHARED
mapping of a file).
If any of
.Dv PROT_READ_CAP ,
.Dv PROT_WRITE_CAP ,
or
.Dv PROT_NO_IMPLY_CAP
If either of
.Dv PROT_NO_CAP
are set, then capability permissions will not be implied.
When
.Dv PROT_READ_CAP
or
.Dv PROT_WRITE_CAP
are passed,
.Dv PROT_CAP
is passed, at least one of
.Dv PROT_READ
and
.Dv PROT_WRITE
are required respectively.
is required.
On non-CHERI platforms the
.Dv PROT_*_CAP
bits have no effect.
.Dv PROT_CAP
and
.Dv PROT_NO_CAP
flags have no effect.
.Pp
In addition to these protection flags,
.Fx
Expand All @@ -169,6 +165,14 @@ values wrapped in the
macro into the
.Fa prot
argument.
The
.Dv PROT_MAX()
flags must be a superset of the unwrapped flags.
If one set of flags contains
.Dv PROT_CAP
or
.Dv PROT_NO_CAP
then both must.
.Pp
The
.Fa flags
Expand Down Expand Up @@ -654,22 +658,11 @@ The
argument contains protections which are not a subset of the specified
maximum protections.
.It Bq Er ENOTSUP
.Dv PROT_READ_CAP
or
.Dv PROT_WRITE_CAP
was not pared with
.Dv PROT_CAP
without
.Dv PROT_READ
or
.Dv PROT_WRITE
respectively or
.Dv PROT_READ
and
.Dv PROT_WRITE
were specified without
both
.Dv PROT_READ_CAP
and
.Dv PROT_WRITE_CAP .
.Dv PROT_WRITE .
.El
.Sh SEE ALSO
.Xr madvise 2 ,
Expand Down
7 changes: 3 additions & 4 deletions sys/sys/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@
#define PROT_READ 0x01 /* pages can be read */
#define PROT_WRITE 0x02 /* pages can be written */
#define PROT_EXEC 0x04 /* pages can be executed */
#define PROT_READ_CAP 0x08 /* capabilities can be read from pages */
#define PROT_WRITE_CAP 0x10 /* capabilities can be written to pages */
#define PROT_NO_IMPLY_CAP 0x20 /* don't imply PROT_{READ,WRITE}_CAP */
#define PROT_CAP 0x08 /* capabilities can be read/written */
#define PROT_NO_CAP 0x10 /* honor PROT_CAP absense */
#if __BSD_VISIBLE
#define _PROT_CAP (PROT_READ_CAP | PROT_WRITE_CAP | PROT_NO_IMPLY_CAP)
#define _PROT_CAP (PROT_CAP | PROT_NO_CAP)
#define _PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC | _PROT_CAP)
#define PROT_EXTRACT(prot) ((prot) & _PROT_ALL)

Expand Down
Loading

0 comments on commit 31a8f5a

Please sign in to comment.