|
Panu Matilainen |
e56f27 |
commit 0b8c3218027c99a6d92c2ca53fe7f42cf87f30a4
|
|
Panu Matilainen |
e56f27 |
Author: Panu Matilainen <pmatilai@redhat.com>
|
|
Panu Matilainen |
e56f27 |
Date: Fri Mar 23 14:17:47 2012 +0200
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
Eliminate broken data end calculation in dataLength()
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
- If the caller doesn't know the end pointer, we dont have a whole lot
|
|
Panu Matilainen |
e56f27 |
of chance to come up with a reasonable one either. Just assume
|
|
Panu Matilainen |
e56f27 |
the terminating \0's are there when end boundary is not specified:
|
|
Panu Matilainen |
e56f27 |
when this happens we're dealing with relatively "trusted" data
|
|
Panu Matilainen |
e56f27 |
anyway, the more critical case of reading in unknown headers does
|
|
Panu Matilainen |
e56f27 |
always pass end pointers.
|
|
Panu Matilainen |
e56f27 |
- While capping the end pointer to HEADER_DATA_MAX seems like a
|
|
Panu Matilainen |
e56f27 |
reasonable thing to do (as was done in commit
|
|
Panu Matilainen |
e56f27 |
f79909d04e43cbfbbcdc588530a8c8033c5e0a7c), it doesn't really help
|
|
Panu Matilainen |
e56f27 |
(bad data would likely run past bounds anyway), and it's not right
|
|
Panu Matilainen |
e56f27 |
either: the pointer can be to a stack address, and the stack can be
|
|
Panu Matilainen |
e56f27 |
near the top of addressable range, and ptr + HEADER_DATA_MAX can
|
|
Panu Matilainen |
e56f27 |
cause pointer wraparound. Notably that's exactly what happens
|
|
Panu Matilainen |
e56f27 |
when running 32bit personality process on 64bit system on Linux,
|
|
Panu Matilainen |
e56f27 |
at least in case of i386 process on x86_64, causing all sorts of
|
|
Panu Matilainen |
e56f27 |
breakage..
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
diff --git a/lib/header.c b/lib/header.c
|
|
Panu Matilainen |
e56f27 |
index d741552..023c6e3 100644
|
|
Panu Matilainen |
e56f27 |
--- a/lib/header.c
|
|
Panu Matilainen |
e56f27 |
+++ b/lib/header.c
|
|
Panu Matilainen |
e56f27 |
@@ -301,16 +301,27 @@ unsigned headerSizeof(Header h, int magicp)
|
|
Panu Matilainen |
e56f27 |
return size;
|
|
Panu Matilainen |
e56f27 |
}
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
-/* Bounded header string (array) size calculation, return -1 on error */
|
|
Panu Matilainen |
e56f27 |
+/*
|
|
Panu Matilainen |
e56f27 |
+ * Header string (array) size calculation, bounded if end is non-NULL.
|
|
Panu Matilainen |
e56f27 |
+ * Return length (including \0 termination) on success, -1 on error.
|
|
Panu Matilainen |
e56f27 |
+ */
|
|
Panu Matilainen |
e56f27 |
static inline int strtaglen(const char *str, rpm_count_t c, const char *end)
|
|
Panu Matilainen |
e56f27 |
{
|
|
Panu Matilainen |
e56f27 |
const char *start = str;
|
|
Panu Matilainen |
e56f27 |
const char *s;
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
- while ((s = memchr(start, '\0', end-start))) {
|
|
Panu Matilainen |
e56f27 |
- if (--c == 0 || s > end)
|
|
Panu Matilainen |
e56f27 |
- break;
|
|
Panu Matilainen |
e56f27 |
- start = s + 1;
|
|
Panu Matilainen |
e56f27 |
+ if (end) {
|
|
Panu Matilainen |
e56f27 |
+ while ((s = memchr(start, '\0', end-start))) {
|
|
Panu Matilainen |
e56f27 |
+ if (--c == 0 || s > end)
|
|
Panu Matilainen |
e56f27 |
+ break;
|
|
Panu Matilainen |
e56f27 |
+ start = s + 1;
|
|
Panu Matilainen |
e56f27 |
+ }
|
|
Panu Matilainen |
e56f27 |
+ } else {
|
|
Panu Matilainen |
e56f27 |
+ while ((s = strchr(start, '\0'))) {
|
|
Panu Matilainen |
e56f27 |
+ if (--c == 0)
|
|
Panu Matilainen |
e56f27 |
+ break;
|
|
Panu Matilainen |
e56f27 |
+ start = s + 1;
|
|
Panu Matilainen |
e56f27 |
+ }
|
|
Panu Matilainen |
e56f27 |
}
|
|
Panu Matilainen |
e56f27 |
return (c > 0) ? -1 : (s - str + 1);
|
|
Panu Matilainen |
e56f27 |
}
|
|
Panu Matilainen |
e56f27 |
@@ -328,8 +339,7 @@ static int dataLength(rpm_tagtype_t type, rpm_constdata_t p, rpm_count_t count,
|
|
Panu Matilainen |
e56f27 |
int onDisk, rpm_constdata_t pend)
|
|
Panu Matilainen |
e56f27 |
{
|
|
Panu Matilainen |
e56f27 |
const char * s = p;
|
|
Panu Matilainen |
e56f27 |
- /* Not all callers supply data end, avoid falling over edge of the world */
|
|
Panu Matilainen |
e56f27 |
- const char * se = pend ? pend : s + HEADER_DATA_MAX;
|
|
Panu Matilainen |
e56f27 |
+ const char * se = pend;
|
|
Panu Matilainen |
e56f27 |
int length = 0;
|
|
Panu Matilainen |
e56f27 |
|
|
Panu Matilainen |
e56f27 |
switch (type) {
|