This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] Intercept glibc's argp_parse()
ClosedPublic

Authored by iii on Feb 4 2023, 3:47 PM.

Details

Summary

Glibc provides the argp_parse() function for parsing command line
arguments [1].

Indicate that argc/argv are read from and arg_index is written to.
Strictly speaking, we also need to indicate that argp is read from,
but this would require describing its layout, and most people use a
static initializer there, so it's not worth the effort.

[1] https://www.gnu.org/software/libc/manual/html_node/Argp.html

Diff Detail

Event Timeline

iii created this revision.Feb 4 2023, 3:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 4 2023, 3:47 PM
Herald added a subscriber: Enna1. · View Herald Transcript
iii requested review of this revision.Feb 4 2023, 3:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 4 2023, 3:47 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript
vitalybuka added inline comments.Feb 6 2023, 4:11 PM
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
10385

I guess it should be always internal_strlen(argv[i]) + 1 ?
!strict_string_checks allows to pass non true C strings in API if we know that parser can return early.
Here I don't see why we should permit non zero terminate strings.

compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
8

why only the trivial test case?

iii updated this revision to Diff 495491.Feb 7 2023, 5:31 AM
  • Drop strict_string_checks.
  • Extend the testcase to check a more realistic use case.
iii marked 2 inline comments as done.Feb 7 2023, 5:33 AM
iii added inline comments.
compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
8

I've added a more realistic example here, please let me know if we need more, e.g., failures due to passing uninitialized or freed values in argv.

iii marked an inline comment as done.Feb 7 2023, 11:29 AM
vitalybuka added inline comments.Feb 7 2023, 3:21 PM
compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
44

what if you test on real argc and argv and pass them like "%run %t 1 2 3 4"
I suspect msan will complain because glibc does not mark them as initialized?
If so we need to remove COMMON_INTERCEPTOR_READ_RANGE.

iii added inline comments.Feb 8 2023, 2:43 AM
compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
44

Good point, thanks! I've added the test and it works. I believe that argv is unpoisoned by ClearShadowForThreadStackAndTLS().

iii updated this revision to Diff 495778.Feb 8 2023, 2:43 AM
  • Added a test with real args/argv.
iii marked an inline comment as done.Feb 8 2023, 2:44 AM
iii added a comment.Feb 16 2023, 3:59 PM

Ping. Is there anything else that needs improvement?

This revision is now accepted and ready to land.Mar 7 2023, 10:38 PM
vitalybuka added inline comments.Mar 7 2023, 10:40 PM
compiler-rt/test/sanitizer_common/TestCases/Linux/argp_parse.c
3

Please add

// This is GLIBC specific.
// UNSUPPORTED: android
3

Please add

// This is GLIBC specific.
// UNSUPPORTED: android

even
// UNSUPPORTED: android, target={{.*(freebsd|netbsd).*}}

iii updated this revision to Diff 503349.Mar 8 2023, 6:20 AM
  • Exclude Android and BSD.
iii marked 2 inline comments as done.Mar 8 2023, 6:26 AM
This revision was landed with ongoing or failed builds.Mar 8 2023, 7:08 AM
This revision was automatically updated to reflect the committed changes.