summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.h9
-rw-r--r--src/dir.c12
-rw-r--r--src/fsade.c9
-rw-r--r--src/parse.c1
-rw-r--r--src/sanity.h89
-rw-r--r--src/stat.c18
-rw-r--r--src/xregex.c8
7 files changed, 110 insertions, 36 deletions
diff --git a/src/config.h b/src/config.h
index f06300e..dbe3c74 100644
--- a/src/config.h
+++ b/src/config.h
@@ -191,15 +191,6 @@ static inline size_t flex_sizeof_impl(size_t align, size_t min, size_t offset, s
return ret;
}
-/**
- * Initialize a variable, unless sanitizers would detect uninitialized uses.
- */
-#if __has_feature(memory_sanitizer)
-# define uninit(var, value) var
-#else
-# define uninit(var, value) value
-#endif
-
// Wrappers for attributes
/**
diff --git a/src/dir.c b/src/dir.c
index d9ee63b..01d26db 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -5,6 +5,7 @@
#include "bfstd.h"
#include "config.h"
#include "diag.h"
+#include "sanity.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -18,18 +19,13 @@
#endif
#if BFS_GETDENTS
-# if __has_feature(memory_sanitizer)
-# include <sanitizer/msan_interface.h>
-# endif
# if __linux__
# include <sys/syscall.h>
# endif
/** getdents() syscall wrapper. */
static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
-#if __has_feature(memory_sanitizer)
- __msan_allocated_memory(buf, size);
-#endif
+ sanitize_uninit(buf, size);
#if __linux__ && __GLIBC__ && !__GLIBC_PREREQ(2, 30)
ssize_t ret = syscall(SYS_getdents64, fd, buf, size);
@@ -39,11 +35,9 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
ssize_t ret = getdents(fd, buf, size);
#endif
-#if __has_feature(memory_sanitizer)
if (ret > 0) {
- __msan_unpoison(buf, ret);
+ sanitize_init(buf, ret);
}
-#endif
return ret;
}
diff --git a/src/fsade.c b/src/fsade.c
index 4d67940..ba89b60 100644
--- a/src/fsade.c
+++ b/src/fsade.c
@@ -159,13 +159,12 @@ static int bfs_check_acl_type(acl_t acl, acl_type_t type) {
#if __FreeBSD__
int trivial;
+ int ret = acl_is_trivial_np(acl, &trivial);
-#if __has_feature(memory_sanitizer)
- // msan seems to be missing an interceptor for acl_is_trivial_np()
- trivial = 0;
-#endif
+ // msan seems to be missing an interceptor for acl_is_trivial_np()
+ sanitize_init(&trivial);
- if (acl_is_trivial_np(acl, &trivial) < 0) {
+ if (ret < 0) {
return -1;
} else if (trivial) {
return 0;
diff --git a/src/parse.c b/src/parse.c
index 1a04e68..59a1e7d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -24,6 +24,7 @@
#include "opt.h"
#include "printf.h"
#include "pwcache.h"
+#include "sanity.h"
#include "stat.h"
#include "typo.h"
#include "xregex.h"
diff --git a/src/sanity.h b/src/sanity.h
new file mode 100644
index 0000000..5696036
--- /dev/null
+++ b/src/sanity.h
@@ -0,0 +1,89 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+/**
+ * Sanitizer interface.
+ */
+
+#ifndef BFS_SANITY_H
+#define BFS_SANITY_H
+
+#include "config.h"
+#include <stddef.h>
+
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+# define SANITIZE_ADDRESS true
+#endif
+
+#if __has_feature(memory_sanitizer) || defined(__SANITIZE_MEMORY__)
+# define SANITIZE_MEMORY true
+#endif
+
+#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
+# define SANITIZE_THREAD true
+#endif
+
+// Call macro(ptr, size) or macro(ptr, sizeof(*ptr))
+#define SANITIZE_CALL(...) \
+ SANITIZE_CALL_(__VA_ARGS__, )
+
+#define SANITIZE_CALL_(macro, ptr, ...) \
+ SANITIZE_CALL__(macro, ptr, __VA_ARGS__ sizeof(*(ptr)), )
+
+#define SANITIZE_CALL__(macro, ptr, size, ...) \
+ macro(ptr, size)
+
+#if SANITIZE_ADDRESS
+# include <sanitizer/asan_interface.h>
+
+/**
+ * sanitize_alloc(ptr, size = sizeof(*ptr))
+ *
+ * Mark a memory region as allocated.
+ */
+#define sanitize_alloc(...) SANITIZE_CALL(__asan_unpoison_memory_region, __VA_ARGS__)
+
+/**
+ * sanitize_free(ptr, size = sizeof(*ptr))
+ *
+ * Mark a memory region as free.
+ */
+#define sanitize_free(...) SANITIZE_CALL(__asan_poison_memory_region, __VA_ARGS__)
+
+#else
+# define sanitize_alloc sanitize_uninit
+# define sanitize_free sanitize_uninit
+#endif
+
+#if SANITIZE_MEMORY
+# include <sanitizer/msan_interface.h>
+
+/**
+ * sanitize_init(ptr, size = sizeof(*ptr))
+ *
+ * Mark a memory region as initialized.
+ */
+#define sanitize_init(...) SANITIZE_CALL(__msan_unpoison, __VA_ARGS__)
+
+/**
+ * sanitize_uninit(ptr, size = sizeof(*ptr))
+ *
+ * Mark a memory region as uninitialized.
+ */
+#define sanitize_uninit(...) SANITIZE_CALL(__msan_allocated_memory, __VA_ARGS__)
+
+#else
+# define sanitize_init(...)
+# define sanitize_uninit(...)
+#endif
+
+/**
+ * Initialize a variable, unless sanitizers would detect uninitialized uses.
+ */
+#if SANITIZE_MEMORY
+# define uninit(var, value) var
+#else
+# define uninit(var, value) value
+#endif
+
+#endif // BFS_SANITY_H
diff --git a/src/stat.c b/src/stat.c
index 590a1d6..3f70e6c 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -5,6 +5,7 @@
#include "bfstd.h"
#include "config.h"
#include "diag.h"
+#include "sanity.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@@ -132,17 +133,18 @@ static int bfs_stat_impl(int at_fd, const char *at_path, int at_flags, struct bf
* Wrapper for the statx() system call, which had no glibc wrapper prior to 2.28.
*/
static int bfs_statx(int at_fd, const char *at_path, int at_flags, unsigned int mask, struct statx *buf) {
-#if __has_feature(memory_sanitizer)
- // -fsanitize=memory doesn't know about statx(), so tell it the memory
- // got initialized
- memset(buf, 0, sizeof(*buf));
-#endif
-
#if BFS_LIBC_STATX
- return statx(at_fd, at_path, at_flags, mask, buf);
+ int ret = statx(at_fd, at_path, at_flags, mask, buf);
#else
- return syscall(SYS_statx, at_fd, at_path, at_flags, mask, buf);
+ int ret = syscall(SYS_statx, at_fd, at_path, at_flags, mask, buf);
#endif
+
+ if (ret == 0) {
+ // -fsanitize=memory doesn't know about statx()
+ sanitize_init(buf);
+ }
+
+ return ret;
}
/**
diff --git a/src/xregex.c b/src/xregex.c
index 1143f23..ce59ff5 100644
--- a/src/xregex.c
+++ b/src/xregex.c
@@ -4,6 +4,7 @@
#include "xregex.h"
#include "config.h"
#include "diag.h"
+#include "sanity.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -175,13 +176,10 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ
cflags |= REG_ICASE;
}
-#if __has_feature(memory_sanitizer)
- // https://github.com/google/sanitizers/issues/1496
- memset(&regex->impl, 0, sizeof(regex->impl));
-#endif
-
regex->err = regcomp(&regex->impl, pattern, cflags);
if (regex->err != 0) {
+ // https://github.com/google/sanitizers/issues/1496
+ sanitize_init(&regex->impl);
return -1;
}
#endif