diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-14 16:04:22 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-14 16:04:22 +0200 |
commit | e9fddbaad81de8afbffe3f8ff626a18a551619df (patch) | |
tree | 2f047b88024befb58d0864c8aa4756c799c9da06 /sys/src/9/port/segment.c | |
parent | ce54a5d6634ab4493504001f9c27568a429ae811 (diff) |
kernel: fix segattach() rounding of va+len (thanks kenji arisawa)
from segattach(2):
Va and len specify the position of the segment in the
process's address space. Va is rounded down to the nearest
page boundary and va+len is rounded up. The system does not
permit segments to overlap. If va is zero, the system will
choose a suitable address.
just rounding up len isnt enougth. we have to round up va+len
instead of just len so that the span [va, va+len) is covered
even if va is not page aligned.
kenjis example:
print("%p\n",ap); // 206cb0
ap = segattach(0, "shared", ap, 1024);
print("%p\n",ap); // 206000
term% cat /proc/612768/segment
Stack defff000 dffff000 1
Text R 1000 6000 1
Data 6000 7000 1
Bss 7000 7000 1
Shared 206000 207000 1
term%
note that 0x206cb0 + 0x400 > 0x20700.
Diffstat (limited to 'sys/src/9/port/segment.c')
-rw-r--r-- | sys/src/9/port/segment.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c index 17efff622..2b45af88d 100644 --- a/sys/src/9/port/segment.c +++ b/sys/src/9/port/segment.c @@ -610,7 +610,10 @@ segattach(Proc *p, ulong attr, char *name, uintptr va, uintptr len) } } + /* round up va+len */ + len += va & (BY2PG-1); len = PGROUND(len); + if(len == 0) error(Ebadarg); |