Avoid undefined behaviour in netgroupcache
authorSiddhesh Poyarekar <siddhesh@redhat.com>
Mon, 27 Jan 2014 06:02:44 +0000 (11:32 +0530)
committerSiddhesh Poyarekar <siddhesh@redhat.com>
Mon, 27 Jan 2014 06:02:44 +0000 (11:32 +0530)
Using a buffer after it has been reallocated is undefined behaviour,
so get offsets of the triplets in the old buffer before reallocating
it.

ChangeLog
nscd/netgroupcache.c

index 1a23eba..a1f549e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-27  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+       * nscd/netgroupcache.c (addgetnetgrentX): Compute offset from
+       the old buffer before realloc.
+
 2014-01-27  Allan McRae  <allan@archlinux.org>
 
        * po/fr.po: Update French translation from translation project.
index 924567c..be01fe8 100644 (file)
@@ -241,15 +241,21 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
                                if (buflen - req->key_len - bufused < needed)
                                  {
                                    buflen += MAX (buflen, 2 * needed);
+                                   /* Save offset in the old buffer.  We don't
+                                      bother with the NULL check here since
+                                      we'll do that later anyway.  */
+                                   size_t nhostdiff = nhost - buffer;
+                                   size_t nuserdiff = nuser - buffer;
+                                   size_t ndomaindiff = ndomain - buffer;
+
                                    char *newbuf = xrealloc (buffer, buflen);
-                                   /* Adjust the pointers in the new
+                                   /* Fix up the triplet pointers into the new
                                       buffer.  */
-                                   nhost = (nhost ? newbuf + (nhost - buffer)
+                                   nhost = (nhost ? newbuf + nhostdiff
                                             : NULL);
-                                   nuser = (nuser ? newbuf + (nuser - buffer)
+                                   nuser = (nuser ? newbuf + nuserdiff
                                             : NULL);
-                                   ndomain = (ndomain
-                                              ? newbuf + (ndomain - buffer)
+                                   ndomain = (ndomain ? newbuf + ndomaindiff
                                               : NULL);
                                    buffer = newbuf;
                                  }