9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Bounds checking bug in fcall(2) functions
@ 2007-11-09 22:20 Erik Dalén
  2007-11-09 22:42 ` Charles Forsyth
  0 siblings, 1 reply; 8+ messages in thread
From: Erik Dalén @ 2007-11-09 22:20 UTC (permalink / raw)
  To: 9fans

Hi

I discovered that there's a off by one bug in the bounds checking in
statcheck(), convM2D(), convD2M() and convM2S().

For example in convM2D() it sets ebuf as:
ebuf = buf + nbuf;

and then checks if reads will go past ebuf. But ebuf will point to the
first byte after the buffer, so past ebuf will include the byte after
the buffer. So it can potentially try to read of write to one byte
past the buffer in all these functions.

-- 
Erik Dalén
dalen@socialisterna.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug in fcall(2) functions
  2007-11-09 22:20 [9fans] Bounds checking bug in fcall(2) functions Erik Dalén
@ 2007-11-09 22:42 ` Charles Forsyth
  2007-11-09 23:01   ` Erik Dalén
  0 siblings, 1 reply; 8+ messages in thread
From: Charles Forsyth @ 2007-11-09 22:42 UTC (permalink / raw)
  To: 9fans

> For example in convM2D() it sets ebuf as:
> ebuf = buf + nbuf;
> 
> and then checks if reads will go past ebuf. But ebuf will point to the
> first byte after the buffer, so past ebuf will include the byte after
> the buffer. So it can potentially try to read of write to one byte
> past the buffer in all these functions.

it would if it tries to access that byte but it doesn't in convM2D.c or convD2M.c
it's checking that the resulting pointer after accessing the bytes will still be <= ebuf,
which (i think) is correct.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug in fcall(2) functions
  2007-11-09 22:42 ` Charles Forsyth
@ 2007-11-09 23:01   ` Erik Dalén
  2007-11-09 23:41     ` Charles Forsyth
                       ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Erik Dalén @ 2007-11-09 23:01 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On 11/9/07, Charles Forsyth <forsyth@terzarima.net> wrote:
> > For example in convM2D() it sets ebuf as:
> > ebuf = buf + nbuf;
> >
> > and then checks if reads will go past ebuf. But ebuf will point to the
> > first byte after the buffer, so past ebuf will include the byte after
> > the buffer. So it can potentially try to read of write to one byte
> > past the buffer in all these functions.
>
> it would if it tries to access that byte but it doesn't in convM2D.c or convD2M.c
> it's checking that the resulting pointer after accessing the bytes will still be <= ebuf,
> which (i think) is correct.
>

On second thought I think you are correct. At the end of the function
the pointer might be one byte past the buffer size, but then it won't
do any reads or writes (But it could be a problem if the buffer is
right at the end of the virtual memory space :). Sorry about the buggy
bug report.

-- 
Erik Dalén
dalen@socialisterna.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug in fcall(2) functions
  2007-11-09 23:01   ` Erik Dalén
@ 2007-11-09 23:41     ` Charles Forsyth
  2007-11-10 17:55     ` Russ Cox
  2007-11-16 10:18     ` [9fans] Bounds checking bug ifcall(2) functions Douglas A. Gwyn
  2 siblings, 0 replies; 8+ messages in thread
From: Charles Forsyth @ 2007-11-09 23:41 UTC (permalink / raw)
  To: 9fans

> (But it could be a problem if the buffer is
> right at the end of the virtual memory space :). Sorry about the buggy ...

that will be a problem if the hardware is sloppy, but it would be true regardless how
you wrote the test (because it's the resulting prefetch addresses that then matter).
i think hardware designers now know about this problem (since it's fairly old)
but that probably hasn't stopped a few from not including it in the processor manual
but slipping it instead into the errata.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug in fcall(2) functions
  2007-11-09 23:01   ` Erik Dalén
  2007-11-09 23:41     ` Charles Forsyth
@ 2007-11-10 17:55     ` Russ Cox
  2007-11-16 10:18     ` [9fans] Bounds checking bug ifcall(2) functions Douglas A. Gwyn
  2 siblings, 0 replies; 8+ messages in thread
From: Russ Cox @ 2007-11-10 17:55 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

> On second thought I think you are correct. At the end of the function
> the pointer might be one byte past the buffer size, but then it won't
> do any reads or writes (But it could be a problem if the buffer is
> right at the end of the virtual memory space :). Sorry about the buggy
> bug report.

The buffer can't be right at the end of the virtual memory space.

The C standard guarantees (or rather, requires) that whenever
you've got an allocated buffer, computing the pointer just past
(some would say at) the end of the buffer can be done without
address overflow, precisely because that kind of bounds check
is such a common idiom.

Russ


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug ifcall(2) functions
  2007-11-09 23:01   ` Erik Dalén
  2007-11-09 23:41     ` Charles Forsyth
  2007-11-10 17:55     ` Russ Cox
@ 2007-11-16 10:18     ` Douglas A. Gwyn
  2007-11-16 10:38       ` erik quanstrom
  2 siblings, 1 reply; 8+ messages in thread
From: Douglas A. Gwyn @ 2007-11-16 10:18 UTC (permalink / raw)
  To: 9fans

Erik Dalén wrote:
> On second thought I think you are correct. At the end of the function
> the pointer might be one byte past the buffer size, but then it won't
> do any reads or writes (But it could be a problem if the buffer is
> right at the end of the virtual memory space :).

The C standard requires that pointer arithmetic work properly
for one-past-the-end pointers.  On some architectures that may
mean that each data segment has to have an extra (unused) byte
allocated, but on most architectures nothing special has to be
done.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug ifcall(2) functions
  2007-11-16 10:18     ` [9fans] Bounds checking bug ifcall(2) functions Douglas A. Gwyn
@ 2007-11-16 10:38       ` erik quanstrom
  2007-11-19 10:14         ` Douglas A. Gwyn
  0 siblings, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2007-11-16 10:38 UTC (permalink / raw)
  To: 9fans

> Erik Dalén wrote:
> > On second thought I think you are correct. At the end of the function
> > the pointer might be one byte past the buffer size, but then it won't
> > do any reads or writes (But it could be a problem if the buffer is
> > right at the end of the virtual memory space :).
> 
> The C standard requires that pointer arithmetic work properly
> for one-past-the-end pointers.  On some architectures that may
> mean that each data segment has to have an extra (unused) byte
> allocated, but on most architectures nothing special has to be
> done.

i think what he's saying is that for machines with unsigned ptr
arithmetic, on a 16-bit machine, ~0 (0xffff) is not a legal address;
on a 32-bit machine ~0 (0xffffff) is not a legal address; &c.  on a
machine with page-based vm, i think this means the highest page 
isn't kosher.  (if signed, the problem is at 0x7f(ff)*.)  this is because
for all addresses a except ~0 a < a+1.  i suppose you could hand
out all but the last 2 bytes of the final page.

i don't think it means you have to allocate an extra byte. there's
no requirement that you may indirect the "one-past the end" address.

- erik


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] Bounds checking bug ifcall(2) functions
  2007-11-16 10:38       ` erik quanstrom
@ 2007-11-19 10:14         ` Douglas A. Gwyn
  0 siblings, 0 replies; 8+ messages in thread
From: Douglas A. Gwyn @ 2007-11-19 10:14 UTC (permalink / raw)
  To: 9fans

erik quanstrom wrote:
> i don't think it means you have to allocate an extra byte. there's
> no requirement that you may indirect the "one-past the end" address.

No, but (a) the arithmetic has to work properly, including
relations like "p < q", and on some architectures merely
loading a past-the-segment-end address into an address
register can cause an invalid-address trap.  Thus, the C
implementation when it lays out the data objects in
segments may have to make sure that the segment contains
an extra unused byte at the end, just so its address will
be valid.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-11-19 10:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-09 22:20 [9fans] Bounds checking bug in fcall(2) functions Erik Dalén
2007-11-09 22:42 ` Charles Forsyth
2007-11-09 23:01   ` Erik Dalén
2007-11-09 23:41     ` Charles Forsyth
2007-11-10 17:55     ` Russ Cox
2007-11-16 10:18     ` [9fans] Bounds checking bug ifcall(2) functions Douglas A. Gwyn
2007-11-16 10:38       ` erik quanstrom
2007-11-19 10:14         ` Douglas A. Gwyn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).