[tor-commits] [tor/master] Avoid an overflow on negation in format_helper_exit_status

nickm at torproject.org nickm at torproject.org
Thu Sep 11 04:15:43 UTC 2014


commit 284cc9a22405bf320944b34ac08be74c2d897fc3
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Sep 11 00:00:13 2014 -0400

    Avoid an overflow on negation in format_helper_exit_status
    
    Part of 13104; patch from teor.
---
 src/common/util.c    |    8 +++++++-
 src/test/test_util.c |   23 +++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/common/util.c b/src/common/util.c
index 297ae78..3acae1c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3555,7 +3555,13 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
 
   /* Convert errno to be unsigned for hex conversion */
   if (saved_errno < 0) {
-    unsigned_errno = (unsigned int) -saved_errno;
+    // Avoid overflow on the cast to unsigned int when result is INT_MIN
+    // by adding 1 to the signed int negative value,
+    // then, after it has been negated and cast to unsigned,
+    // adding the original 1 back (the double-addition is intentional).
+    // Otherwise, the cast to signed could cause a temporary int
+    // to equal INT_MAX + 1, which is undefined.
+    unsigned_errno = ((unsigned int) -(saved_errno + 1)) + 1;
   } else {
     unsigned_errno = (unsigned int) saved_errno;
   }
diff --git a/src/test/test_util.c b/src/test/test_util.c
index f091fc9..eed37ca 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -2561,12 +2561,17 @@ test_util_exit_status(void *ptr)
   int n;
 
   (void)ptr;
+  
+  clear_hex_errno(hex_errno);
+  test_streq("", hex_errno);
 
   clear_hex_errno(hex_errno);
   n = format_helper_exit_status(0, 0, hex_errno);
   test_streq("0/0\n", hex_errno);
   test_eq(n, strlen(hex_errno));
 
+#if SIZEOF_INT == 4
+  
   clear_hex_errno(hex_errno);
   n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
   test_streq("0/7FFFFFFF\n", hex_errno);
@@ -2577,6 +2582,21 @@ test_util_exit_status(void *ptr)
   test_streq("FF/-80000000\n", hex_errno);
   test_eq(n, strlen(hex_errno));
   test_eq(n, HEX_ERRNO_SIZE);
+  
+#elif SIZEOF_INT == 8
+  
+  clear_hex_errno(hex_errno);
+  n = format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno);
+  test_streq("0/7FFFFFFFFFFFFFFF\n", hex_errno);
+  test_eq(n, strlen(hex_errno));
+  
+  clear_hex_errno(hex_errno);
+  n = format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno);
+  test_streq("FF/-8000000000000000\n", hex_errno);
+  test_eq(n, strlen(hex_errno));
+  test_eq(n, HEX_ERRNO_SIZE);
+  
+#endif
 
   clear_hex_errno(hex_errno);
   n = format_helper_exit_status(0x7F, 0, hex_errno);
@@ -2587,6 +2607,9 @@ test_util_exit_status(void *ptr)
   n = format_helper_exit_status(0x08, -0x242, hex_errno);
   test_streq("8/-242\n", hex_errno);
   test_eq(n, strlen(hex_errno));
+  
+  clear_hex_errno(hex_errno);
+  test_streq("", hex_errno);
 
  done:
   ;





More information about the tor-commits mailing list