Add interceptors for the strtoi(3)/strtou(3) from NetBSD

Summary:
strtoi/strtou converts string value to an intmax_t/uintmax_t integer.

Add a dedicated test.

Enable this API for NetBSD.

It's a reworked version of the original work by Yang Zheng.

Reviewers: joerg, vitalybuka

Reviewed By: vitalybuka

Subscribers: kubamracek, tomsun.0.7, mgorny, llvm-commits, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D54702

llvm-svn: 348663
This commit is contained in:
Kamil Rytarowski 2018-12-07 22:24:35 +00:00
parent 43cfce88b4
commit ae3ae31e9c
3 changed files with 76 additions and 0 deletions

View File

@ -7809,6 +7809,37 @@ INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
#define INIT_STATVFS1
#endif
#if SANITIZER_INTERCEPT_STRTOI
INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
INTMAX_T low, INTMAX_T high, int *rstatus) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
char *real_endptr;
INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
if (rstatus)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
return ret;
}
INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
UINTMAX_T low, UINTMAX_T high, int *rstatus) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
char *real_endptr;
UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
if (rstatus)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
return ret;
}
#define INIT_STRTOI \
COMMON_INTERCEPT_FUNCTION(strtoi); \
COMMON_INTERCEPT_FUNCTION(strtou)
#else
#define INIT_STRTOI
#endif
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@ -8076,6 +8107,7 @@ static void InitializeCommonInterceptors() {
INIT_STRTONUM;
INIT_FPARSELN;
INIT_STATVFS1;
INIT_STRTOI;
INIT___PRINTF_CHK;
}

View File

@ -532,5 +532,6 @@
#define SANITIZER_INTERCEPT_STRTONUM SI_NETBSD
#define SANITIZER_INTERCEPT_FPARSELN SI_NETBSD
#define SANITIZER_INTERCEPT_STATVFS1 SI_NETBSD
#define SANITIZER_INTERCEPT_STRTOI SI_NETBSD
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

View File

@ -0,0 +1,43 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
#include <inttypes.h>
#include <stdio.h>
void test_strtoi(const char *nptr, int base, intmax_t lo, intmax_t hi) {
char *p;
int status;
intmax_t i = strtoi(nptr, &p, base, lo, hi, &status);
printf("strtoi: conversion of '%s' to a number %s, using %jd, p=%#" PRIx8
"\n",
nptr, status ? "failed" : "successful", i, *p);
}
void test_strtou(const char *nptr, int base, intmax_t lo, intmax_t hi) {
char *p;
int status;
uintmax_t i = strtou(nptr, &p, base, lo, hi, &status);
printf("strtou: conversion of '%s' to a number %s, using %ju, p=%#" PRIx8
"\n",
nptr, status ? "failed" : "successful", i, *p);
}
int main(void) {
printf("strtoi\n");
test_strtoi("100", 0, 1, 100);
test_strtoi("100", 0, 1, 10);
test_strtoi("100xyz", 0, 1, 100);
test_strtou("100", 0, 1, 100);
test_strtou("100", 0, 1, 10);
test_strtou("100xyz", 0, 1, 100);
// CHECK: strtoi
// CHECK: strtoi: conversion of '100' to a number successful, using 100, p=0
// CHECK: strtoi: conversion of '100' to a number failed, using 10, p=0
// CHECK: strtoi: conversion of '100xyz' to a number failed, using 10, p=0x78
// CHECK: strtou: conversion of '100' to a number successful, using 100, p=0
// CHECK: strtou: conversion of '100' to a number failed, using 10, p=0
// CHECK: strtou: conversion of '100xyz' to a number failed, using 10, p=0x78
return 0;
}