From 5e8a7a882eb056f7fc02736f2e92547f269ee553 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Wed, 15 May 2024 16:07:05 -0400
Subject: Work around https://github.com/llvm/llvm-project/issues/88163

---
 src/bfstd.c | 15 +++++++++++++++
 src/bfstd.h |  5 +++++
 src/ctx.c   |  3 ++-
 src/exec.c  |  4 ++--
 4 files changed, 24 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/bfstd.c b/src/bfstd.c
index 0ac3a72..7680f17 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -671,6 +671,21 @@ int xstrtofflags(const char **str, unsigned long long *set, unsigned long long *
 #endif
 }
 
+long xsysconf(int name) {
+#if __FreeBSD__ && SANITIZE_MEMORY
+	// Work around https://github.com/llvm/llvm-project/issues/88163
+	__msan_scoped_disable_interceptor_checks();
+#endif
+
+	long ret = sysconf(name);
+
+#if __FreeBSD__ && SANITIZE_MEMORY
+	__msan_scoped_enable_interceptor_checks();
+#endif
+
+	return ret;
+}
+
 size_t asciilen(const char *str) {
 	return asciinlen(str, strlen(str));
 }
diff --git a/src/bfstd.h b/src/bfstd.h
index f91e380..d06bbd9 100644
--- a/src/bfstd.h
+++ b/src/bfstd.h
@@ -410,6 +410,11 @@ char *xconfstr(int name);
  */
 int xstrtofflags(const char **str, unsigned long long *set, unsigned long long *clear);
 
+/**
+ * Wrapper for sysconf() that works around an MSan bug.
+ */
+long xsysconf(int name);
+
 #include <wchar.h>
 
 /**
diff --git a/src/ctx.c b/src/ctx.c
index 356adbc..11531df 100644
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -3,6 +3,7 @@
 
 #include "ctx.h"
 #include "alloc.h"
+#include "bfstd.h"
 #include "color.h"
 #include "diag.h"
 #include "expr.h"
@@ -22,7 +23,7 @@
 
 /** Get the initial value for ctx->threads (-j). */
 static int bfs_nproc(void) {
-	long nproc = sysconf(_SC_NPROCESSORS_ONLN);
+	long nproc = xsysconf(_SC_NPROCESSORS_ONLN);
 
 	if (nproc < 1) {
 		nproc = 1;
diff --git a/src/exec.c b/src/exec.c
index e782d49..15b3c79 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -56,7 +56,7 @@ static size_t bfs_exec_arg_size(const char *arg) {
 
 /** Determine the maximum argv size. */
 static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) {
-	long arg_max = sysconf(_SC_ARG_MAX);
+	long arg_max = xsysconf(_SC_ARG_MAX);
 	bfs_exec_debug(execbuf, "ARG_MAX: %ld according to sysconf()\n", arg_max);
 	if (arg_max < 0) {
 		arg_max = BFS_EXEC_ARG_MAX;
@@ -82,7 +82,7 @@ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) {
 
 	// Assume arguments are counted with the granularity of a single page,
 	// so allow a one page cushion to account for rounding up
-	long page_size = sysconf(_SC_PAGESIZE);
+	long page_size = xsysconf(_SC_PAGESIZE);
 	if (page_size < 4096) {
 		page_size = 4096;
 	}
-- 
cgit v1.2.3