aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'executor/common.h')
-rw-r--r--executor/common.h14
1 files changed, 13 insertions, 1 deletions
diff --git a/executor/common.h b/executor/common.h
index 81ddefd01..490595ce2 100644
--- a/executor/common.h
+++ b/executor/common.h
@@ -199,6 +199,7 @@ static void use_temporary_dir(void)
#if GOOS_akaros || GOOS_netbsd || GOOS_freebsd || GOOS_openbsd || GOOS_test
#if (SYZ_EXECUTOR || SYZ_REPEAT) && SYZ_EXECUTOR_USES_FORK_SERVER && (SYZ_EXECUTOR || SYZ_USE_TMP_DIR)
#include <dirent.h>
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@@ -207,8 +208,19 @@ static void use_temporary_dir(void)
static void remove_dir(const char* dir)
{
DIR* dp = opendir(dir);
- if (dp == NULL)
+ if (dp == NULL) {
+ if (errno == EACCES) {
+ // We could end up here in a recursive call to remove_dir() below.
+ // One of executed syscall could end up creating a directory rooted
+ // in the current working directory created by loop() with zero
+ // permissions. Try to perform a best effort removal of the
+ // directory.
+ if (rmdir(dir))
+ exitf("rmdir(%s) failed", dir);
+ return;
+ }
exitf("opendir(%s) failed", dir);
+ }
struct dirent* ep = 0;
while ((ep = readdir(dp))) {
if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)