This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] use uptr to store the result of internal_strlen/internal_strnlen in printf_common
ClosedPublic

Authored by Enna1 on Aug 7 2023, 2:46 AM.

Details

Summary

The return type of internal_strlen() is 'uptr', but in printf_common() we store the result of internal_strlen() into an 'int' type variable.
When the result value of internal_strlen() is larger than the largest possible value of 'int' type, the implicit conversion from 'uptr' to 'int' will change the result value to a negative value.

Without this change, asan reports a false positive negative-size-param in the added testcase.

Diff Detail

Event Timeline

Enna1 created this revision.Aug 7 2023, 2:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 7 2023, 2:46 AM
Enna1 updated this revision to Diff 547717.Aug 7 2023, 4:35 AM

Fix Wsign-compare

Enna1 published this revision for review.Aug 7 2023, 7:15 AM
Enna1 added reviewers: vitalybuka, eugenis.
Enna1 added a subscriber: MTC.
Herald added a project: Restricted Project. · View Herald TranscriptAug 7 2023, 7:16 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
fmayer added a subscriber: fmayer.Aug 7 2023, 11:05 AM
fmayer added inline comments.
compiler-rt/test/asan/TestCases/vsnprintf.cpp
5 ↗(On Diff #547717)

can we just do {{.*windows}}? that would match the comment

fmayer added inline comments.Aug 7 2023, 11:07 AM
compiler-rt/test/asan/TestCases/vsnprintf.cpp
5 ↗(On Diff #547717)

{{.windows.*}}, of course.

Enna1 updated this revision to Diff 548093.Aug 8 2023, 1:00 AM

update from @fmayer comment

Enna1 marked 2 inline comments as done.Aug 8 2023, 1:05 AM
Enna1 added inline comments.
compiler-rt/test/asan/TestCases/vsnprintf.cpp
5 ↗(On Diff #547717)

Thanks!
This line was copied from test/asan/printf-2.c
updated to {{.*windows.*}}

vitalybuka added inline comments.Aug 15 2023, 1:47 PM
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
569

COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, 0);

compiler-rt/test/asan/TestCases/vsnprintf.cpp
20 ↗(On Diff #548093)

does this pass on 32bit platforms?

vitalybuka added inline comments.Aug 15 2023, 1:50 PM
compiler-rt/test/asan/TestCases/vsnprintf.cpp
2 ↗(On Diff #548093)

the patch is for sanitizer_common/
so the test should be test/sanitizer_common/

vitalybuka added inline comments.Aug 15 2023, 2:05 PM
compiler-rt/test/asan/TestCases/vsnprintf.cpp
20 ↗(On Diff #548093)
******************** TEST 'AddressSanitizer-i386-linux-dynamic :: TestCases/vsnprintf.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';      out/./bin/clang  --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only  -m32  -shared-libasan -O2 llvm-project/compiler-rt/test/asan/TestCases/vsnprintf.cpp -o out/projects/compiler-rt/test/asan/I386LinuxDynamicConfig/TestCases/Output/vsnprintf.cpp.tmp
: 'RUN: at line 2';   env ASAN_OPTIONS=check_printf=1  out/projects/compiler-rt/test/asan/I386LinuxDynamicConfig/TestCases/Output/vsnprintf.cpp.tmp 2>&1
--
Exit Code: 134

Command Output (stdout):
--
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

--
Command Output (stderr):
--
out/projects/compiler-rt/test/asan/I386LinuxDynamicConfig/TestCases/Output/vsnprintf.cpp.script: line 2: 2820733 Aborted                 env ASAN_OPTIONS=check_printf=1 out/projects/compiler-rt/test/asan/I386LinuxDynamicConfig/TestCases/Output/vsnprintf.cpp.tmp 2>&1

--

********************
********************
Failed Tests (2):
  AddressSanitizer-i386-linux :: TestCases/vsnprintf.cpp
  AddressSanitizer-i386-linux-dynamic :: TestCases/vsnprintf.cpp
Enna1 updated this revision to Diff 551452.Aug 18 2023, 3:22 AM
Enna1 marked an inline comment as done.

Thanks for testing.

I see in compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp, for 64-bit kMaxAllowedMallocSize is 1ULL<<40, for 32-bit kMaxAllowedMallocSize is 3UL << 30.
So I update this test, use malloc(1UL<<31) instead of std::string, I think this can pass on 32-bit platforms.
But I don't know how to test build and test 32-bit sanitizer, so I'm not sure about it.

Could you please describe how to build and test 32-bit sanitizer? Thanks!

vitalybuka added a comment.EditedAug 18 2023, 11:44 AM

Thanks for testing.

I see in compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp, for 64-bit kMaxAllowedMallocSize is 1ULL<<40, for 32-bit kMaxAllowedMallocSize is 3UL << 30.
So I update this test, use malloc(1UL<<31) instead of std::string, I think this can pass on 32-bit platforms.

Probably it's fine to disable the test on 32bit platforms.

But I don't know how to test build and test 32-bit sanitizer, so I'm not sure about it.

Could you please describe how to build and test 32-bit sanitizer? Thanks!

That's how it's enabled on bots, and probably on my workstation. https://github.com/google/sanitizers/blob/26afa5f62cef5079e8cdfe96972fdfa057ed1b4b/buildbot/install_deps.sh#L16

Then cmake should automatically add them into check-compiler-rt check-asan etc
You should see in the cmake log:

  • Compiler-RT supported architectures: x86_64;i386
Enna1 updated this revision to Diff 551931.Aug 21 2023, 1:44 AM

Thanks! I have run the test on 32-bit platforms successfully.

Update test to run this test only on x86_64-target-arch.

vitalybuka accepted this revision.Aug 27 2023, 7:25 PM
This revision is now accepted and ready to land.Aug 27 2023, 7:25 PM