forked from OSchip/llvm-project
Add new interceptor for strtonum(3)
Summary: strtonum(3) reliably convertss string value to an integer. This function is used in OpenBSD compat namespace and is located inside NetBSD's libc. Add a dedicated test for this interface. It's a reworked version of the original code by Yang Zheng. Reviewers: joerg, vitalybuka Reviewed By: vitalybuka Subscribers: tomsun.0.7, kubamracek, llvm-commits, mgorny, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D54527 llvm-svn: 348651
This commit is contained in:
parent
a0082afcb6
commit
0fed92a933
|
@ -7728,6 +7728,30 @@ INTERCEPTOR(int, modctl, int operation, void *argp) {
|
|||
#define INIT_MODCTL
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_STRTONUM
|
||||
INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
|
||||
long long maxval, const char **errstr) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
|
||||
|
||||
// TODO(kamil): Implement strtoll as a common inteceptor
|
||||
char *real_endptr;
|
||||
long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
|
||||
StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
|
||||
|
||||
ret = REAL(strtonum)(nptr, minval, maxval, errstr);
|
||||
if (errstr) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
|
||||
if (*errstr)
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
|
||||
#else
|
||||
#define INIT_STRTONUM
|
||||
#endif
|
||||
|
||||
static void InitializeCommonInterceptors() {
|
||||
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
|
||||
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
|
||||
|
@ -7992,6 +8016,7 @@ static void InitializeCommonInterceptors() {
|
|||
INIT_SYSCTLGETMIBINFO;
|
||||
INIT_NL_LANGINFO;
|
||||
INIT_MODCTL;
|
||||
INIT_STRTONUM;
|
||||
|
||||
INIT___PRINTF_CHK;
|
||||
}
|
||||
|
|
|
@ -529,5 +529,6 @@
|
|||
#define SANITIZER_INTERCEPT_SYSCTLGETMIBINFO SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_NL_LANGINFO (SI_NETBSD || SI_FREEBSD)
|
||||
#define SANITIZER_INTERCEPT_MODCTL SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_STRTONUM SI_NETBSD
|
||||
|
||||
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||
|
||||
#define _OPENBSD_SOURCE
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void) {
|
||||
const char *errstr;
|
||||
|
||||
printf("strtonum\n");
|
||||
|
||||
long long l = strtonum("100", 1, 100, &errstr);
|
||||
assert(!errstr);
|
||||
printf("%lld\n", l);
|
||||
|
||||
l = strtonum("200", 1, 100, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
l = strtonum("300", 1000, 1001, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
l = strtonum("abc", 1000, 1001, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
l = strtonum("1000", 1001, 1000, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
l = strtonum("1000abc", 1000, 1001, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
l = strtonum("1000.0", 1000, 1001, &errstr);
|
||||
assert(errstr);
|
||||
printf("%s\n", errstr);
|
||||
|
||||
// CHECK: strtonum
|
||||
// CHECK: 100
|
||||
// CHECK: too large
|
||||
// CHECK: too small
|
||||
// CHECK: invalid
|
||||
// CHECK: invalid
|
||||
// CHECK: invalid
|
||||
// CHECK: invalid
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue