On Tue, Nov 12, 2019 at 11:32:56AM +0100, Jakub Jelinek wrote:
> On Tue, Nov 12, 2019 at 10:56:21AM +0100, Andreas Schwab wrote:
> > On Nov 11 2019, Jim Wilson wrote:
> > 
> > > ../../../../gcc-git/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:1136:1:
> > > note: in expansion of macro ‘CHECK_SIZE_AND_OFFSET’
> > >  1136 | CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
> > >       | ^~~~~~~~~~~~~~~~~~~~~
> > 
> > Looks like you are using an unreleased version of glibc.  This works
> > correctly with glibc 2.30.
> > 
> > As you have noticed, this will need to be corrected for all
> > architectures where the ipc_perm structure has been changed in commit
> > 2f959dfe84, once glibc 2.31 has been released.  Care to file an llvm
> > issue about that?
> 
> We actually have a change cherry-picked from upstream for the
> https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=2f959dfe849e0646e27403f2e4091536496ac0f0
> glibc change - 
> https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01554.html
> , but only for arm, while it apparently broke either all or many other
> architectures (at least x86_64 and riscv64 are now reported).

From the linux targets supported by GCC libsanitizer, I think affected
are sparc 32-bit, s390 31-bit (this one is even an ABI change, as mode
not only changed size, but on big endian didn't change offset and
unfortunately libsanitizer intercepts shmctl), arm (again, on big endian
an ABI change which libsanitizer interception will not cope with, as it uses
dlsym rather than dlvsym and is not symbol versioned), x86_64, i?86,
riscv64.
So, either we go for something like untested:
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp   
2019-11-07 17:56:23.551835239 +0100
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp   
2019-11-12 12:14:24.216763190 +0100
@@ -1129,10 +1129,12 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
 #if (!defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)) && \
-    !defined(__arm__)
+    (!SANITIZER_LINUX || !__GLIBC_PREREQ (2, 30) || \
+     defined(__powerpc__) || (defined(__sparc__) && defined(__arch64__)) \
+     defined(__mips__) || defined(__aarch64__) || defined(__s390x__))
 /* On aarch64 glibc 2.20 and earlier provided incorrect mode field.  */
-/* On Arm newer glibc provide a different mode field, it's hard to detect
-   so just disable the check.  */
+/* glibc 2.30 and earlier provided 16-bit mode field instead of 32-bit
+   on most architectures.  */
 CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
 #endif
 
or perhaps better change sanitizer_platform_limits_posix.h to match the
glibc 2.31 definition and similarly to aarch64 don't check mode for
!__GLIBC_PREREQ (2, 31), that would be something like untested:
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h     
2019-11-07 17:56:23.530835549 +0100
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h     
2019-11-12 12:22:26.314511706 +0100
@@ -207,26 +207,13 @@ struct __sanitizer_ipc_perm {
   u64 __unused1;
   u64 __unused2;
 #elif defined(__sparc__)
-#if defined(__arch64__)
   unsigned mode;
-  unsigned short __pad1;
-#else
-  unsigned short __pad1;
-  unsigned short mode;
   unsigned short __pad2;
-#endif
   unsigned short __seq;
   unsigned long long __unused1;
   unsigned long long __unused2;
-#elif defined(__mips__) || defined(__aarch64__) || defined(__s390x__)
-  unsigned int mode;
-  unsigned short __seq;
-  unsigned short __pad1;
-  unsigned long __unused1;
-  unsigned long __unused2;
 #else
-  unsigned short mode;
-  unsigned short __pad1;
+  unsigned int mode;
   unsigned short __seq;
   unsigned short __pad2;
 #if defined(__x86_64__) && !defined(_LP64)
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp   
2019-11-07 17:56:23.551835239 +0100
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp   
2019-11-12 12:23:42.959358844 +0100
@@ -1128,11 +1128,9 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
-#if (!defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)) && \
-    !defined(__arm__)
-/* On aarch64 glibc 2.20 and earlier provided incorrect mode field.  */
-/* On Arm newer glibc provide a different mode field, it's hard to detect
-   so just disable the check.  */
+#if !SANITIZER_LINUX || __GLIBC_PREREQ (2, 31)
+/* glibc 2.30 and earlier provided 16-bit mode field instead of 32-bit
+   on most architectures.  */
 CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
 #endif
 
But I'm afraid I don't really have the cycles to test this on all targets,
nor does it fix the arm be or s390 31-bit problem with shmctl.

        Jakub

Reply via email to