Ticket #13104: 04-fmt-exit-status-arith-undef.patch

File 04-fmt-exit-status-arith-undef.patch, 2.4 KB (added by teor, 5 years ago)

Avoid an overflow on negation in format_helper_exit_status

  • src/common/util.c

    diff --git a/src/common/util.c b/src/common/util.c
    index 75dd6ed..ff1a371 100644
    a b format_helper_exit_status(unsigned char child_state, int saved_errno, 
    35773588
    35783589  /* Convert errno to be unsigned for hex conversion */
    35793590  if (saved_errno < 0) {
    3580     unsigned_errno = (unsigned int) -saved_errno;
     3591    // Avoid overflow on the cast to unsigned int when result is INT_MIN
     3592    // by adding 1 to the signed int negative value,
     3593    // then, after it has been negated and cast to unsigned,
     3594    // adding the original 1 back (the double-addition is intentional).
     3595    // Otherwise, the cast to signed could cause a temporary int
     3596    // to equal INT_MAX + 1, which is undefined.
     3597    unsigned_errno = ((unsigned int) -(saved_errno + 1)) + 1;
    35813598  } else {
    35823599    unsigned_errno = (unsigned int) saved_errno;
    35833600  }
  • src/test/test_util.c

    diff --git a/src/test/test_util.c b/src/test/test_util.c
    index 1b7c936..9d66dbd 100644
    a b test_util_exit_status(void *ptr) 
    24842625  int n;
    24852626
    24862627  (void)ptr;
     2628 
     2629  clear_hex_errno(hex_errno);
     2630  test_streq("", hex_errno);
    24872631
    24882632  clear_hex_errno(hex_errno);
    24892633  n = format_helper_exit_status(0, 0, hex_errno);
    24902634  test_streq("0/0\n", hex_errno);
    24912635  test_eq(n, strlen(hex_errno));
    24922636
     2637#if SIZEOF_INT == 4
     2638 
    24932639  clear_hex_errno(hex_errno);
    24942640  n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
    24952641  test_streq("0/7FFFFFFF\n", hex_errno);
    test_util_exit_status(void *ptr) 
    25002646  test_streq("FF/-80000000\n", hex_errno);
    25012647  test_eq(n, strlen(hex_errno));
    25022648  test_eq(n, HEX_ERRNO_SIZE);
     2649 
     2650#elif SIZEOF_INT == 8
     2651 
     2652  clear_hex_errno(hex_errno);
     2653  n = format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno);
     2654  test_streq("0/7FFFFFFFFFFFFFFF\n", hex_errno);
     2655  test_eq(n, strlen(hex_errno));
     2656 
     2657  clear_hex_errno(hex_errno);
     2658  n = format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno);
     2659  test_streq("FF/-8000000000000000\n", hex_errno);
     2660  test_eq(n, strlen(hex_errno));
     2661  test_eq(n, HEX_ERRNO_SIZE);
     2662 
     2663#endif
    25032664
    25042665  clear_hex_errno(hex_errno);
    25052666  n = format_helper_exit_status(0x7F, 0, hex_errno);
    test_util_exit_status(void *ptr) 
    25102671  n = format_helper_exit_status(0x08, -0x242, hex_errno);
    25112672  test_streq("8/-242\n", hex_errno);
    25122673  test_eq(n, strlen(hex_errno));
     2674 
     2675  clear_hex_errno(hex_errno);
     2676  test_streq("", hex_errno);
    25132677
    25142678 done:
    25152679  ;