Skip to content

ASAN interceptors for strncat, wcsncat need to be adjusted for N3322 #113063

@bhaible

Description

@bhaible

According to https://sourceware.org/pipermail/libc-alpha/2024-October/160375.html, N3322 has been accepted for inclusion in ISO C.

The instrumentation of the following functions therefore should NOT crash anymore:

  strncat
  wcsncat

How to reproduce regarding strncat:
Save this as n3322-2.c:

/* This program exercises functionality allowed by
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf */

#include <assert.h>
#include <string.h>

int main ()
{
  assert (strncat (NULL, "x", 0) == NULL);
}

Then

$ clang -fsanitize=undefined,address -O0 -fno-omit-frame-pointer -ggdb n3322-2.c
$ ASAN_OPTIONS="detect_leaks=0 abort_on_error=0 allocator_may_return_null=1" ./a.out
n3322-2.c:9:3: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:153:29: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior n3322-2.c:9:3 
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2746120==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5600db790040 bp 0x7ffe5ec80030 sp 0x7ffe5ec7f7b8 T0)
==2746120==The signal is caused by a READ memory access.
==2746120==Hint: address points to the zero page.
    #0 0x5600db790040 in __sanitizer::internal_strlen(char const*) /home/runner/work/llvm-project/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp:176:10
    #1 0x5600db75e360 in strncat /home/runner/work/llvm-project/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:540:22
    #2 0x5600db7b7b8f in main /home/bruno/n3322-2.c:9:3
    #3 0x7f25956fdd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #4 0x7f25956fde3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #5 0x5600db6d8344 in _start (/home/bruno/a.out+0x2c344)

==2746120==Register values:
rax = 0xffffffffffffffff  rbx = 0x3ffffffffffffff8  rcx = 0x0000000000000000  rdx = 0x0000000000000000  
rdi = 0x0000000000000000  rsi = 0x0000000000000000  rbp = 0x00007ffe5ec80030  rsp = 0x00007ffe5ec7f7b8  
 r8 = 0x000000000000007c   r9 = 0x0000000000000000  r10 = 0xafffff00000fffff  r11 = 0x0000000000000246  
r12 = 0x0000000000000000  r13 = 0x00005600db7b7b48  r14 = 0x00005600db7cbda0  r15 = 0x0000000000000000  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/bruno/n3322-2.c:9:3 in main
==2746120==ABORTING

How to reproduce regarding wcsncat:
Save this as n3322-3.c:

/* This program exercises functionality allowed by
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf */

#include <assert.h>
#include <wchar.h>

int main ()
{
  assert (wcsncat (NULL, L"x", 0) == NULL);
}

Then

$ clang -fsanitize=undefined,address -O0 -fno-omit-frame-pointer -ggdb n3322-3.c
$ ASAN_OPTIONS="detect_leaks=0 abort_on_error=0 allocator_may_return_null=1" ./a.out
/usr/include/wchar.h:103:14: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior n3322-3.c:9:3 in 
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2746126==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55b35dec2380 bp 0x7ffcce19c370 sp 0x7ffcce19bb18 T0)
==2746126==The signal is caused by a READ memory access.
==2746126==Hint: address points to the zero page.
    #0 0x55b35dec2380 in __sanitizer::internal_wcslen(wchar_t const*) (/home/bruno/a.out+0xb9380) (BuildId: 2d266e59e14ccfb7d922a334d47753baf7376303)
    #1 0x55b35de80b51 in wcsncat (/home/bruno/a.out+0x77b51) (BuildId: 2d266e59e14ccfb7d922a334d47753baf7376303)
    #2 0x55b35dee4f02 in main /home/bruno/n3322-3.c:9:3
    #3 0x7f5ac0ad9d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #4 0x7f5ac0ad9e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #5 0x55b35de27314 in _start (/home/bruno/a.out+0x1e314) (BuildId: 2d266e59e14ccfb7d922a334d47753baf7376303)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/bruno/a.out+0xb9380) (BuildId: 2d266e59e14ccfb7d922a334d47753baf7376303) in __sanitizer::internal_wcslen(wchar_t const*)
==2746126==ABORTING

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler-rt:asanAddress sanitizerinvalidResolved as invalid, i.e. not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions