ref: 8f63d48a00251d74b67e7244c908e436cb540d2c
parent: addcf037ca4dc1060318cfbd044f473ea594afe6
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Mon Sep 23 21:52:20 EDT 2013
syssem*: eleminate redundant validaddr() checks validaddr looks up the segments for an address range and checks the flags and if the address range lies within bounds on the segments. as we'r going to lookup the segment in the syssem* syscalls anyway, we can do the checks ourselfs avoiding the double segment array lookups. the implication of this tho is that now a semaphore cannot span multiple segments. but this would be highly unusual given that segments are page aligned.
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -1109,13 +1109,15 @@
long *addr;
Segment *s;
- validaddr(arg[0], sizeof(long), 1);
evenaddr(arg[0]);
addr = (long*)arg[0];
block = arg[1];
-
- if((s = seg(up, (ulong)addr, 0)) == nil)
+
+ s = seg(up, (ulong)addr, 0);
+ if(s == nil || (s->type&SG_RONLY) != 0 || (ulong)addr+sizeof(long) > s->top){+ validaddr((ulong)addr, sizeof(long), 1);
error(Ebadarg);
+ }
if(*addr < 0)
error(Ebadarg);
return semacquire(s, addr, block);
@@ -1128,13 +1130,15 @@
ulong ms;
Segment *s;
- validaddr(arg[0], sizeof(long), 1);
evenaddr(arg[0]);
addr = (long*)arg[0];
ms = arg[1];
- if((s = seg(up, (ulong)addr, 0)) == nil)
+ s = seg(up, (ulong)addr, 0);
+ if(s == nil || (s->type&SG_RONLY) != 0 || (ulong)addr+sizeof(long) > s->top){+ validaddr((ulong)addr, sizeof(long), 1);
error(Ebadarg);
+ }
if(*addr < 0)
error(Ebadarg);
return tsemacquire(s, addr, ms);
@@ -1146,13 +1150,15 @@
long *addr, delta;
Segment *s;
- validaddr(arg[0], sizeof(long), 1);
evenaddr(arg[0]);
addr = (long*)arg[0];
delta = arg[1];
- if((s = seg(up, (ulong)addr, 0)) == nil)
+ s = seg(up, (ulong)addr, 0);
+ if(s == nil || (s->type&SG_RONLY) != 0 || (ulong)addr+sizeof(long) > s->top){+ validaddr((ulong)addr, sizeof(long), 1);
error(Ebadarg);
+ }
/* delta == 0 is a no-op, not a release */
if(delta < 0 || *addr < 0)
error(Ebadarg);
--
⑨