[MSAN] add __b64_pton and __b64_ntop intercepts

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D122849
This commit is contained in:
Kevin Athey 2022-04-08 15:00:09 -07:00
parent 6aa8a836c0
commit e9c8d0ff71
4 changed files with 153 additions and 0 deletions

View File

@ -2496,6 +2496,34 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
#define INIT_GLOB64
#endif // SANITIZER_INTERCEPT_GLOB64
#if SANITIZER_INTERCEPT___B64_TO
INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,
char *target, SIZE_T targsize) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);
int res = REAL(__b64_ntop)(src, srclength, target, targsize);
if (res >= 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);
return res;
}
INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
int res = REAL(__b64_pton)(src, target, targsize);
if (res >= 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);
return res;
}
# define INIT___B64_TO \
COMMON_INTERCEPT_FUNCTION(__b64_ntop); \
COMMON_INTERCEPT_FUNCTION(__b64_pton);
#else // SANITIZER_INTERCEPT___B64_TO
#define INIT___B64_TO
#endif // SANITIZER_INTERCEPT___B64_TO
#if SANITIZER_INTERCEPT_POSIX_SPAWN
template <class RealSpawnPtr>
@ -10396,6 +10424,7 @@ static void InitializeCommonInterceptors() {
INIT_TIME;
INIT_GLOB;
INIT_GLOB64;
INIT___B64_TO;
INIT_POSIX_SPAWN;
INIT_WAIT;
INIT_WAIT4;

View File

@ -235,6 +235,7 @@
#define SANITIZER_INTERCEPT_TIME SI_POSIX
#define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
#define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
#define SANITIZER_INTERCEPT___B64_TO SI_LINUX
#define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX
#define SANITIZER_INTERCEPT_WAIT SI_POSIX
#define SANITIZER_INTERCEPT_INET SI_POSIX

View File

@ -0,0 +1,81 @@
// RUN: %clangxx_msan -O0 %s -o %t -lresolv && %run %t
// RUN: not %run %t NTOP_READ 2>&1 | FileCheck %s --check-prefix=NTOP_READ
// RUN: not %run %t PTON_READ 2>&1 | FileCheck %s --check-prefix=PTON_READ
#include <assert.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sanitizer/msan_interface.h>
int main(int iArgc, char *szArgv[]) {
char* test = nullptr;
if (iArgc > 1) {
test = szArgv[1];
}
if (test == nullptr) {
// Check NTOP writing
const char *src = "base64 test data";
size_t src_len = strlen(src);
size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
char dst[dst_len];
int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
dst, dst_len);
assert(res >= 0);
__msan_check_mem_is_initialized(dst, res);
// Check PTON writing
unsigned char target[dst_len];
res = b64_pton(dst, target, dst_len);
assert(res >= 0);
__msan_check_mem_is_initialized(target, res);
// Check NTOP writing for zero length src
src = "";
src_len = strlen(src);
assert(((src_len + 2) / 3) * 4 + 1 < dst_len);
res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
dst, dst_len);
assert(res >= 0);
__msan_check_mem_is_initialized(dst, res);
// Check PTON writing for zero length src
dst[0] = '\0';
res = b64_pton(dst, target, dst_len);
assert(res >= 0);
__msan_check_mem_is_initialized(target, res);
return 0;
}
if (strcmp(test, "NTOP_READ") == 0) {
// Check NTOP reading
size_t src_len = 80;
char src[src_len];
__msan_poison(src, src_len);
size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
char dst[dst_len];
int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
dst, dst_len);
// NTOP_READ: Uninitialized bytes in __interceptor___b64_ntop
return 0;
}
if (strcmp(test, "PTON_READ") == 0) {
// Check PTON reading
size_t src_len = 80;
char src[src_len];
strcpy(src, "junk longer than zero");
// pretend it is uninitialized
__msan_poison(src, src_len);
unsigned char target[src_len];
int res = b64_pton(src, target, src_len);
// PTON_READ: Uninitialized bytes in __interceptor___b64_pton
return 0;
}
return 0;
}

View File

@ -0,0 +1,42 @@
// RUN: %clangxx %s -o %t -lresolv && %run %t %p
#include <assert.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int main(int iArgc, char *szArgv[]) {
// Check NTOP writing
const char *src = "base64 test data";
size_t src_len = strlen(src);
size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
char dst[dst_len];
int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len, dst,
dst_len);
assert(res >= 0);
assert(strcmp(dst, "YmFzZTY0IHRlc3QgZGF0YQ==") == 0);
// Check PTON writing
unsigned char target[dst_len];
res = b64_pton(dst, target, dst_len);
assert(res >= 0);
assert(strncmp(reinterpret_cast<const char *>(target), src, res) == 0);
// Check NTOP writing for zero length src
src = "";
src_len = strlen(src);
assert(((src_len + 2) / 3) * 4 + 1 < dst_len);
res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len, dst,
dst_len);
assert(res >= 0);
assert(strcmp(dst, "") == 0);
// Check PTON writing for zero length src
dst[0] = '\0';
res = b64_pton(dst, target, dst_len);
assert(res >= 0);
assert(strncmp(reinterpret_cast<const char *>(target), src, res) == 0);
return 0;
}