[sanitizer] Intercept sem_open/sem_unlink

Without interceptor implementation may call strlen on internal
buffers causing false msan errors.

Differential Revision: https://reviews.llvm.org/D107615
This commit is contained in:
Vitaly Buka 2021-08-05 19:47:48 -07:00
parent b987c283ae
commit 69a909b9fe
2 changed files with 49 additions and 1 deletions

View File

@ -6538,6 +6538,29 @@ INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
}
return res;
}
INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {
void *ctx;
va_list ap;
va_start(ap, oflag);
u32 mode = va_arg(ap, u32);
u32 value = va_arg(ap, u32);
COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
__sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);
if (s)
COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));
va_end(ap);
return s;
}
INTERCEPTOR(int, sem_unlink, const char *name) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
return REAL(sem_unlink)(name);
}
# define INIT_SEM \
COMMON_INTERCEPT_FUNCTION(sem_init); \
COMMON_INTERCEPT_FUNCTION(sem_destroy); \
@ -6545,7 +6568,9 @@ INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
COMMON_INTERCEPT_FUNCTION(sem_trywait); \
COMMON_INTERCEPT_FUNCTION(sem_timedwait); \
COMMON_INTERCEPT_FUNCTION(sem_post); \
COMMON_INTERCEPT_FUNCTION(sem_getvalue);
COMMON_INTERCEPT_FUNCTION(sem_getvalue); \
COMMON_INTERCEPT_FUNCTION(sem_open); \
COMMON_INTERCEPT_FUNCTION(sem_unlink);
#else
# define INIT_SEM
#endif // SANITIZER_INTERCEPT_SEM

View File

@ -0,0 +1,23 @@
// RUN: %clangxx -O0 %s -o %t && %run %t
#include <assert.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
int main() {
char name[1024];
sprintf(name, "/sem_open_test_%d", getpid());
sem_t *s1 = sem_open(name, O_CREAT, 0644, 123);
assert(s1 != SEM_FAILED);
sem_t *s2 = sem_open(name, O_CREAT, 0644, 123);
assert(s2 != SEM_FAILED);
assert(sem_close(s1) == 0);
assert(sem_close(s2) == 0);
assert(sem_unlink(name) == 0);
}