summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-08-27 06:16:20 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-08-27 06:16:20 +0200
commitd9fec3c70aebe9e9139429235b881bf5b32dbe41 (patch)
tree1c5aadcecee46f50968a4fb1ada922886dca46d2
parentd25ca13ed8acdf609329055ef9c36d0f3fae9503 (diff)
kernel: prohibit changing cache attributes (SG_CACHED|SG_DEVICE) in segattach(), set SG_RONLY in data2txt()
the user should not be able to change the cache attributes for a segment in segattach() as this can cause the same memory to be mapped with conflicting attributes in the cache. SG_TEXT should always be mapped with SG_RONLY attribute. so fix data2txt() to follow the rules.
-rw-r--r--sys/src/9/port/segment.c15
-rw-r--r--sys/src/9/port/sysproc.c2
2 files changed, 10 insertions, 7 deletions
diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c
index eedbb7b14..b9f3236b2 100644
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -177,8 +177,8 @@ dupseg(Segment **seg, int segno, int share)
case SG_DATA: /* Copy on write plus demand load info */
if(segno == TSEG){
n = data2txt(s);
- poperror();
qunlock(s);
+ poperror();
return n;
}
@@ -200,14 +200,14 @@ dupseg(Segment **seg, int segno, int share)
n->flushme = s->flushme;
if(s->ref > 1)
procflushseg(s);
- poperror();
qunlock(s);
+ poperror();
return n;
sameseg:
incref(s);
- poperror();
qunlock(s);
+ poperror();
return s;
}
@@ -680,8 +680,11 @@ segattach(int attr, char *name, uintptr va, uintptr len)
if(len > ps->size)
error(Enovmem);
- attr &= ~SG_TYPE; /* Turn off what is not allowed */
- attr |= ps->attr; /* Copy in defaults */
+ /* Turn off what is not allowed */
+ attr &= ~(SG_TYPE | SG_CACHED | SG_DEVICE);
+
+ /* Copy in defaults */
+ attr |= ps->attr;
s = newseg(attr, va, len/BY2PG);
s->pseg = ps;
@@ -788,7 +791,7 @@ data2txt(Segment *s)
{
Segment *ps;
- ps = newseg(SG_TEXT, s->base, s->size);
+ ps = newseg(SG_TEXT | SG_RONLY, s->base, s->size);
ps->image = s->image;
incref(ps->image);
ps->fstart = s->fstart;
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c
index 259b2d891..5361429c4 100644
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -512,7 +512,7 @@ sysexec(va_list list)
/* Text. Shared. Attaches to cache image if possible */
/* attachimage returns a locked cache image */
- img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT);
+ img = attachimage(SG_TEXT | SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT);
ts = img->s;
up->seg[TSEG] = ts;
ts->flushme = 1;