aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-11-18 21:33:15 +0100
committerDmitry Vyukov <dvyukov@google.com>2015-11-18 21:33:15 +0100
commitf67856dae0496c8fd414a762b81e9b4307d486eb (patch)
tree39873ca259bb3a2097c2844262b0a7685e81ffce /executor
parent495113290ed28d4debdecb5934a78d0beb722db7 (diff)
allow executor execute particular syscalls under root
this is required to test e.g. fuse fs (non-root can't mount)
Diffstat (limited to 'executor')
-rw-r--r--executor/executor.cc38
1 files changed, 28 insertions, 10 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index cc3dcdeb1..671828703 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -75,6 +75,7 @@ res_t results[kMaxCommands];
struct thread_t {
bool created;
+ bool root;
int id;
pthread_t th;
uint32_t cover_data[16 << 10];
@@ -108,6 +109,7 @@ uint64_t copyout(char* addr, uint64_t size);
thread_t* schedule_call(int n, int call_index, int call_num, uint64_t num_args, uint64_t* args, uint64_t* pos);
void execute_call(thread_t* th);
void handle_completion(thread_t* th);
+void thread_create(thread_t* th, int id, bool root);
void* worker_thread(void* arg);
uint64_t current_time_ms();
void cover_open();
@@ -158,6 +160,9 @@ int main()
if (pid == 0) {
setpgid(0, 0);
if (flag_drop_privs) {
+ // Pre-create one thread with root privileges for execution of special syscalls (e.g. mount).
+ if (flag_threaded)
+ thread_create(&threads[kMaxThreads - 1], kMaxThreads - 1, true);
// TODO: 65534 is meant to be nobody
if (setgroups(0, NULL))
fail("failed to setgroups");
@@ -323,20 +328,20 @@ retry:
thread_t* schedule_call(int n, int call_index, int call_num, uint64_t num_args, uint64_t* args, uint64_t* pos)
{
+ // Figure out whether we need root privs for this call.
+ bool root = false;
+ switch (syscalls[call_num].sys_nr) {
+ case __NR_syz_dri_open:
+ root = true;
+ }
// Find a spare thread to execute the call.
thread_t* th = 0;
for (int i = 0; i < kMaxThreads; i++) {
th = &threads[i];
- if (!th->created) {
- th->created = true;
- th->id = i;
- th->done = true;
- th->handled = true;
- if (flag_threaded) {
- if (pthread_create(&th->th, 0, worker_thread, th))
- exitf("pthread_create failed");
- }
- }
+ if (!th->created)
+ thread_create(th, i, false);
+ if (flag_drop_privs && root != th->root)
+ continue;
if (__atomic_load_n(&th->done, __ATOMIC_ACQUIRE)) {
if (!th->handled)
handle_completion(th);
@@ -396,6 +401,19 @@ void handle_completion(thread_t* th)
th->handled = true;
}
+void thread_create(thread_t* th, int id, bool root)
+{
+ th->created = true;
+ th->id = id;
+ th->root = root;
+ th->done = true;
+ th->handled = true;
+ if (flag_threaded) {
+ if (pthread_create(&th->th, 0, worker_thread, th))
+ exitf("pthread_create failed");
+ }
+}
+
void* worker_thread(void* arg)
{
thread_t* th = (thread_t*)arg;