Date: Thu, 7 Sep 1995 11:13:46 +1000 From: Bruce Evans <bde@zeta.org.au> To: pst@shockwave.com, security@freebsd.org Subject: Re: diffs for syslog.c Message-ID: <199509070113.LAA10056@godzilla.zeta.org.au>
index | next in thread | raw e-mail
>+/*
>+ * Some rather anal checks to make sure we don't overflow our stack.
>+ * We want to make sure no one can attack either the program stack or
>+ * syslogd's stack. All writes are limited by SPACELEFT, and an additional
>+ * overflow check is performed to insure that the travelling pointer has
ensure [too English?]
>+ * not exceeded the bounds of the buffer (the return value from snprintf
>+ * is the number of characters it expected to write, not the number of
>+ * characters is did write if the limit was reached).
it
>+ *
>+ * The overflow check could be eliminated if we changed v/snprintf or
>+ * made "safe" versions of those routines.
>+ */
>+
>+#define SPACELEFT(buffer, current) (sizeof (buffer) - \
>+ ((char *)(current) - (char *)(buffer)))
This is wrong if size_t is larger than ptrdiff_t. Then the result is
unsigned and large if `current' is after the end of the buffer, as it
may be the `fmt' conversion (the overflow check doesn't get done early
enough to help). Also, the pointer difference is undefined ig
`current' isn't in the buffer.
>+#define OVERFLOW(buffer, current) ((current) > \
>+ (char *)(buffer) + sizeof (buffer))
^
Anal code should check for overflow here. In fact, the check can't be
written like this in Standard C. `fooptr + offset' is undefined if the
offset isn't a valid array index (or maybe one larger). The correct
test is something like
int nwritten;
ssize_t spaceleft;
...
spaceleft = SPACELEFT(...);
assert(spaceleft >= 0);
nwritten = vsnprintf(..., spaceleft, ...);
assert(nwritten >= 0);
if (nwritten > spaceleft)
goto overflow;
Bruce
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509070113.LAA10056>
