https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111382

            Bug ID: 111382
           Summary: Sanitizer says that the right address calculated in
                    parentheses is misaligned.
           Product: gcc
           Version: 9.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: aamelnikov at inbox dot ru
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Created attachment 55883
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55883&action=edit
small program that reproduces the bug

Hello!

Found that sanitizer swears at the correct address if it was calculated in
parentheses. Please see the details below and small program santst to reproduce
this.

GCC versions:
postgres@anton-nb:~$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
or
postgres@anton-nb:~$ gcc-11 --version
gcc-11 (Ubuntu 11.4.0-2ubuntu1~20.04) 11.4.0

Both gcc 9.4.0 and 11.4.0 show the same behavior.

OS version:
postgres@anton-nb:~$ uname -a
Linux anton-nb 5.15.0-83-generic #92~20.04.1-Ubuntu SMP Mon Aug 21 14:00:49 UTC
2023 x86_64 x86_64 x86_64 GNU/Linux

Compile options:
export CPPFLAGS="-ggdb -O0 -g3 -fno-omit-frame-pointer -Wall -Wextra
-save-temps -fsanitize=undefined -fno-sanitize-recover=all"
export LDFLAGS='-fsanitize=undefined -static-libubsan'
export ASAN_OPTIONS=abort_on_error=1
gcc $CPPFLAGS santst.c -o santst $LDFLAGS

Programm output:
postgres@anton-nb:~$ ./santst
 Upper bound = 0x7ffe35c9fb90
Test address = 0x7ffe35c9fb94
santst.c:16:9: runtime error: load of misaligned address 0x7ffe35c9fb94 for
type 'int64_t', which requires 8 byte alignment
0x7ffe35c9fb94: note: pointer points here
  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  a0 fc c9 35 fe 7f 00 00  00
27 92 80 6b 8f 4f b0
              ^

It is clear in disasm that alignment check at <main+142> will be done on
test_addr before
adding a 4 and lead to __ubsan_handle_type_mismatch_v1_abort call.

│   0x55555555896f <main+134>       je     0x55555555897c <main+147>           
                                                                               
                             │
│  >0x555555558971 <main+136>       mov    %rax,%rdx                           
                                                                               
                             │
│   0x555555558974 <main+139>       and    $0x7,%edx                           
                                                                               
                             │
│   0x555555558977 <main+142>       test   %rdx,%rdx                           
                                                                               
                             │
│   0x55555555897a <main+145>       je     0x55555555898e <main+165>           
                                                                               
                             │
│   0x55555555897c <main+147>       mov    %rax,%rsi                           
                                                                               
                             │
│   0x55555555897f <main+150>       lea    0x4a69a(%rip),%rax        #
0x5555555a3020                                                                 
                                      │
│   0x555555558986 <main+157>       mov    %rax,%rdi                           
                                                                               
                             │
│   0x555555558989 <main+160>       call   0x55555555cdc0
<__ubsan_handle_type_mismatch_v1_abort>                                        
                                                   │
│   0x55555555898e <main+165>       mov    -0x30(%rbp),%rax                    
                                                                               
                             │
│   0x555555558992 <main+169>       lea    0x4(%rax),%rdx                      
                                                                               
                             │
│   0x555555558996 <main+173>       cmp    $0xfffffffffffffffc,%rax            
                                                                               
                             │
│   0x55555555899a <main+177>       jb     0x5555555589b2 <main+201>           
                                                                               
                             │
│   0x55555555899c <main+179>       mov    -0x30(%rbp),%rax                    
                                                                               
                             │
│   0x5555555589a0 <main+183>       mov    %rax,%rsi                           
                                                                               
                             │
│   0x5555555589a3 <main+186>       lea    0x4a696(%rip),%rax        #
0x5555555a3040                                                                 
                                      │
│   0x5555555589aa <main+193>       mov    %rax,%rdi                           
                                                                               
                             │
│   0x5555555589ad <main+196>       call   0x55555555d5c0
<__ubsan_handle_pointer_overflow_abort>                                        
                                                   │
│   0x5555555589b2 <main+201>       mov    -0x30(%rbp),%rax                    
                                                                               
                             │
│   0x5555555589b6 <main+205>       mov    0x4(%rax),%rax

(gdb) p test_addr
$1 = 0x7fffffffdd54 ""
(gdb) p/x $rax
$2 = 0x7fffffffdd54
(gdb) c
Continuing.
santst.c:16:9: runtime error: load of misaligned address 0x7fffffffdd54 for
type 'int64_t', which requires 8 byte alignment
(gdb) ffffdd54: note: pointer points here
  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  60 de ff ff ff 7f 00 00  00
0a af 9a 82 f8 02 c3
              ^
[Inferior 1 (process 27496) exited with code 01]

If i perform the addition of four before cast like that:
--- a/santst.c
+++ b/santst.c
@@ -13,7 +13,8 @@ int main()
     printf(" Upper bound = %p\n", ch);
     printf("Test address = %p\n", test_addr);

-    i64 = *((int64_t *)(test_addr + 4));
+    test_addr +=4;
+    i64 = *((int64_t *)(test_addr));

everything will be fine:

postgres@anton-nb:~$ ./santst
 Upper bound = 0x7ffe18853610
Test address = 0x7ffe18853614
If you see it, all ok! t=0

Kind regards!

--
Anton A. Melnikov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

Reply via email to