Skip to content

Commit 6f13445

Browse files
committed
[DFSan] Add custom wrapper for epoll_wait.
The wrapper clears shadow for any events written. Reviewed By: stephan.yichao.zhao Differential Revision: https://reviews.llvm.org/D92891
1 parent 10edd10 commit 6f13445

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

compiler-rt/lib/dfsan/dfsan_custom.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@
1111
// This file defines the custom functions listed in done_abilist.txt.
1212
//===----------------------------------------------------------------------===//
1313

14-
#include "sanitizer_common/sanitizer_common.h"
15-
#include "sanitizer_common/sanitizer_internal_defs.h"
16-
#include "sanitizer_common/sanitizer_linux.h"
17-
18-
#include "dfsan/dfsan.h"
19-
2014
#include <arpa/inet.h>
2115
#include <assert.h>
2216
#include <ctype.h>
@@ -32,6 +26,7 @@
3226
#include <stdio.h>
3327
#include <stdlib.h>
3428
#include <string.h>
29+
#include <sys/epoll.h>
3530
#include <sys/resource.h>
3631
#include <sys/select.h>
3732
#include <sys/stat.h>
@@ -40,6 +35,11 @@
4035
#include <time.h>
4136
#include <unistd.h>
4237

38+
#include "dfsan/dfsan.h"
39+
#include "sanitizer_common/sanitizer_common.h"
40+
#include "sanitizer_common/sanitizer_internal_defs.h"
41+
#include "sanitizer_common/sanitizer_linux.h"
42+
4343
using namespace __dfsan;
4444

4545
#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \
@@ -715,6 +715,18 @@ int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,
715715
return ret;
716716
}
717717

718+
SANITIZER_INTERFACE_ATTRIBUTE
719+
int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
720+
int timeout, dfsan_label epfd_label,
721+
dfsan_label events_label, dfsan_label maxevents_label,
722+
dfsan_label timeout_label, dfsan_label *ret_label) {
723+
int ret = epoll_wait(epfd, events, maxevents, timeout);
724+
if (ret > 0)
725+
dfsan_set_label(0, events, ret * sizeof(*events));
726+
*ret_label = 0;
727+
return ret;
728+
}
729+
718730
SANITIZER_INTERFACE_ATTRIBUTE
719731
int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,
720732
dfsan_label dfs_label, dfsan_label nfds_label,

compiler-rt/lib/dfsan/done_abilist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ fun:uselocale=discard
184184
fun:calloc=custom
185185
fun:clock_gettime=custom
186186
fun:dlopen=custom
187+
fun:epoll_wait=custom
187188
fun:fgets=custom
188189
fun:fstat=custom
189190
fun:getcwd=custom

compiler-rt/test/dfsan/custom.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <stdlib.h>
2323
#include <string.h>
2424
#include <strings.h>
25+
#include <sys/epoll.h>
2526
#include <sys/resource.h>
2627
#include <sys/select.h>
2728
#include <sys/stat.h>
@@ -638,6 +639,46 @@ void test_getpwuid_r() {
638639
ASSERT_READ_ZERO_LABEL(&pwd, 4);
639640
}
640641

642+
void test_epoll_wait() {
643+
// Set up a pipe to monitor with epoll.
644+
int pipe_fds[2];
645+
int ret = pipe(pipe_fds);
646+
assert(ret != -1);
647+
648+
// Configure epoll to monitor the pipe.
649+
int epfd = epoll_create1(0);
650+
assert(epfd != -1);
651+
struct epoll_event event;
652+
event.events = EPOLLIN;
653+
event.data.fd = pipe_fds[0];
654+
ret = epoll_ctl(epfd, EPOLL_CTL_ADD, pipe_fds[0], &event);
655+
assert(ret != -1);
656+
657+
// Test epoll_wait when no events have occurred.
658+
event = {};
659+
dfsan_set_label(i_label, &event, sizeof(event));
660+
ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);
661+
assert(ret == 0);
662+
assert(event.events == 0);
663+
assert(event.data.fd == 0);
664+
ASSERT_ZERO_LABEL(ret);
665+
ASSERT_READ_LABEL(&event, sizeof(event), i_label);
666+
667+
// Test epoll_wait when an event occurs.
668+
write(pipe_fds[1], "x", 1);
669+
ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);
670+
assert(ret == 1);
671+
assert(event.events == EPOLLIN);
672+
assert(event.data.fd == pipe_fds[0]);
673+
ASSERT_ZERO_LABEL(ret);
674+
ASSERT_READ_ZERO_LABEL(&event, sizeof(event));
675+
676+
// Clean up.
677+
close(epfd);
678+
close(pipe_fds[0]);
679+
close(pipe_fds[1]);
680+
}
681+
641682
void test_poll() {
642683
struct pollfd fd;
643684
fd.fd = 0;
@@ -1027,6 +1068,7 @@ int main(void) {
10271068
test_dfsan_set_write_callback();
10281069
test_dl_iterate_phdr();
10291070
test_dlopen();
1071+
test_epoll_wait();
10301072
test_fgets();
10311073
test_fstat();
10321074
test_get_current_dir_name();

0 commit comments

Comments
 (0)