summaryrefslogtreecommitdiff
path: root/net/samba422/files/0028-s3-lib-system-add-FreeBSD-proc_fd_pattern.patch
blob: 2721be912c76d254b6dbcb45d50923ad65db89c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
From 584c69e77abb537a7345222648a397a9963c01b7 Mon Sep 17 00:00:00 2001
From: "Timur I. Bakeyev" <timur@FreeBSD.org>
Date: Sat, 15 Oct 2022 04:02:43 +0200
Subject: [PATCH 28/28] s3:lib:system - add FreeBSD proc_fd_pattern

Add support for FreeBSD equivalent of /proc/self/fd through a special
fdescfs mount with option "nodup". This filesystem should be mounted
either to the private $PIDDIR/fd/ directory or to /dev/fd in order to
provide security and performance characteristics similar to Linux.

Signed-off-by: Timur I. Bakeyev <timur@FreeBSD.org>
Adapted for Samba 4.20 by: Andrea venturoli <ml@netfence.it>
---
--- source3/lib/system.c.orig	2025-06-27 15:05:05 UTC
+++ source3/lib/system.c
@@ -1047,6 +1047,68 @@ int sys_get_number_of_cores(void)
 }
 #endif
 
+static bool freebsd_fdesc_check(const char *pattern)
+{
+	char fdesc_path[PATH_MAX];
+	int fd, fd2;
+
+	fd = open(lp_pid_directory(), O_DIRECTORY);
+	if (fd == -1) {
+		DBG_ERR("%s: failed to open pid directory: %s\n",
+			lp_pid_directory(), strerror(errno));
+		return false;
+	}
+
+	snprintf(fdesc_path, sizeof(fdesc_path), pattern, fd);
+
+	fd2 = open(fdesc_path, O_DIRECTORY);
+	if (fd2 == -1) {
+		/*
+		 * Setting O_DIRECTORY on open of fdescfs mount
+		 * without 'nodup' option will fail with ENOTDIR.
+		 */
+		if (errno == ENOTDIR) {
+			DBG_ERR("%s: fdescfs filesystem is not mounted with "
+				"'nodup' option. This specific mount option is "
+				"required in order to enable race-free handling "
+				"of paths.\n"
+				"See documentation for Samba's New VFS' "
+				"for more details. The 'nodup' mount option was "
+				"introduced in FreeBSD 13.\n", fdesc_path);
+			close(fd);
+			return false;
+		}
+		DBG_ERR("%s: failed to open fdescfs path: %s\n",
+			fdesc_path, strerror(errno));
+		close(fd);
+		return false;
+	}
+	close(fd);
+	close(fd2);
+
+	return true;
+}
+
+static char* freebsd_pattern(char *buf, size_t bufsize) {
+	const char** base;
+	const char* base_dir[] = {
+		lp_pid_directory(), /* This is a preferred location */
+		"/dev",
+		NULL
+	};
+
+	for(base = &base_dir[0]; *base != NULL; base++) {
+		snprintf(buf, bufsize, "%s/fd/%%lu", *base);
+		if(freebsd_fdesc_check(buf)) {
+			return buf;
+		}
+	}
+	return NULL;
+}
+
+static char proc_fd_pattern_buf[PATH_MAX];
+static const char *proc_fd_pattern = NULL;
+
 bool sys_have_proc_fds(void)
 {
 	static bool checked = false;
@@ -1058,8 +1078,12 @@ bool sys_have_proc_fds(void)
 		return have_proc_fds;
 	}
 
-	ret = stat("/proc/self/fd/0", &sb);
-	have_proc_fds = (ret == 0);
+	if (freebsd_pattern(proc_fd_pattern_buf, sizeof(proc_fd_pattern_buf)) != NULL) {
+                have_proc_fds = true;
+		proc_fd_pattern = proc_fd_pattern_buf;
+	} else
+                have_proc_fds = false;
+
 	checked = true;
 
 	return have_proc_fds;
@@ -1067,10 +1091,18 @@ char *sys_proc_fd_path(int fd, struct sys_proc_fd_path
 
 char *sys_proc_fd_path(int fd, struct sys_proc_fd_path_buf *buf)
 {
+	 bool have_proc_fds = sys_have_proc_fds();
+        SMB_ASSERT(have_proc_fds);
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
 	int written =
-		snprintf(buf->buf, sizeof(buf->buf), "/proc/self/fd/%d", fd);
-
-	SMB_ASSERT(sys_have_proc_fds() && (written >= 0));
+		snprintf(buf->buf, sizeof(buf->buf), proc_fd_pattern, fd);
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+	SMB_ASSERT(written >= 0);
 
 	return buf->buf;
 }