teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame rpm-4.9.90-header-datalength.patch

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) {