Bug 31798 - pidfd_getpid.c is miscompiled by GCC 6.4
Summary: pidfd_getpid.c is miscompiled by GCC 6.4
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.40
: P2 normal
Target Milestone: 2.40
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-05-25 11:03 UTC by H.J. Lu
Modified: 2024-05-27 14:42 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2024-05-25 11:03:53 UTC
On i686, pidfd_getpid.c in glibc 2.40 master branch is miscompiled by GCC 6.4:

FAIL: misc/tst-pidfd
FAIL: misc/tst-pidfd_getpid

../sysdeps/unix/sysv/linux/tst-pidfd.c:128: numeric comparison failure
   left: 3063298 (0x2ebe02); from: pidfork
  right: -1 (0xffffffff); from: pid
../sysdeps/unix/sysv/linux/tst-pidfd.c:141: numeric comparison failure
   left: 9 (0x9); from: errno
  right: 3 (0x3); from: ESRCH
../sysdeps/unix/sysv/linux/tst-pidfd.c:165: numeric comparison failure
   left: -1 (0xffffffff); from: querypid
  right: 3063299 (0x2ebe03); from: pid
error: 3 test failures

GCC 7.4 is OK.
Comment 1 H.J. Lu 2024-05-25 12:00:06 UTC
It is a bug in sysdeps/unix/sysv/linux/pidfd_getpid.c:

      /* Ignore invalid large values.  */
      if (INT_MULTIPLY_WRAPV (10, n, &n) 
          || INT_ADD_WRAPV (n, *l++ - '0', &n))
        return -1; 

For GCC older than GCC 7, _GL_HAS_BUILTIN_ADD_OVERFLOW is 0:

#if _GL_HAS_BUILTIN_ADD_OVERFLOW
# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r)
# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r)
#else
# define INT_ADD_WRAPV(a, b, r) \
   _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
# define INT_SUBTRACT_WRAPV(a, b, r) \
   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
#endif

*l++ - '0' is evaluated twice.
Comment 2 Sourceware Commits 2024-05-27 13:53:26 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f981bf6b9db87e0732b46bfe92fdad4d363225e8

commit f981bf6b9db87e0732b46bfe92fdad4d363225e8
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat May 25 05:13:41 2024 -0700

    parse_fdinfo: Don't advance pointer twice [BZ #31798]
    
    pidfd_getpid.c has
    
          /* Ignore invalid large values.  */
          if (INT_MULTIPLY_WRAPV (10, n, &n)
              || INT_ADD_WRAPV (n, *l++ - '0', &n))
            return -1;
    
    For GCC older than GCC 7, INT_ADD_WRAPV(a, b, r) is defined as
    
       _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
    
    and *l++ - '0' is evaluated twice.  Fix BZ #31798 by moving "l++" out of
    the if statement.  Tested with GCC 6.4 and GCC 14.1.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Comment 3 Sourceware Commits 2024-05-27 14:42:06 UTC
The release/2.39/master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9f2b100d6705b9bbb25206b53e80d7759644e06e

commit 9f2b100d6705b9bbb25206b53e80d7759644e06e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat May 25 05:13:41 2024 -0700

    parse_fdinfo: Don't advance pointer twice [BZ #31798]
    
    pidfd_getpid.c has
    
          /* Ignore invalid large values.  */
          if (INT_MULTIPLY_WRAPV (10, n, &n)
              || INT_ADD_WRAPV (n, *l++ - '0', &n))
            return -1;
    
    For GCC older than GCC 7, INT_ADD_WRAPV(a, b, r) is defined as
    
       _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
    
    and *l++ - '0' is evaluated twice.  Fix BZ #31798 by moving "l++" out of
    the if statement.  Tested with GCC 6.4 and GCC 14.1.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
    (cherry picked from commit f981bf6b9db87e0732b46bfe92fdad4d363225e8)
Comment 4 H.J. Lu 2024-05-27 14:42:54 UTC
Fixed for 2.40 and 2.39 branch.