syscall: resolve the daemon's served-module anchor via the pinned module_dirfd

open_anchor_dirfd() now dups the identity-pinned module_dirfd when the
anchor is the served module root, instead of re-resolving the absolute
module_dir with openat(AT_FDCWD, ...) -- which re-traverses the module's
ancestors as the dropped-privilege module uid and EACCESes when the module
sits under a non-traversable parent (a 0700 home).  Functionally identical
(same inode), but privilege-drop-safe.  syscall.o links into the t_* test
helpers without clientserver.o, so add a module_dirfd stub to t_stub.c.

Test: daemon-module-private-parent.
(cherry picked from commit cf4860b22d0517c8a2bc4736a0e1a670a1024933)
This commit is contained in:
Andrew Tridgell committed 2026-06-15 15:26:15 +10:00
1 parent f294157591
commit b0ed3bc718
2 files changed
+12 -2

No files matched your search

+11 -2
View File
@@ -1840,11 +1840,20 @@ static int path_has_dotdot_component(const char *path)
/* Symlink-race-safe path resolver: a held-dirfd-stack walk (replaces the
* 3.4.x openat2/RESOLVE_BENEATH resolver) -- follows in-tree symlinks while
* confining beneath the anchor. */
extern char *module_dir;
extern int module_dirfd; /* daemon: served module root pinned by identity, or -1 */
#if defined AT_FDCWD && defined O_NOFOLLOW && defined O_DIRECTORY
/* Open a trusted absolute anchor directory as an owned dirfd. (The daemon
* module_dirfd privilege-drop optimization is added with that backport.) */
/* Open a trusted absolute anchor directory as an owned dirfd. When the anchor is
* the served module root and the daemon pinned it by identity (module_dirfd), dup
* that fd rather than re-resolving the absolute path with openat(AT_FDCWD, ...) --
* which re-traverses the module's ancestors as the dropped-privilege module uid
* and EACCESes when the module sits under a non-traversable parent (a 0700 home).
* Functionally identical (same inode), just privilege-drop-safe. */
static int open_anchor_dirfd(const char *path)
{
if (module_dirfd >= 0 && am_daemon && module_dir && strcmp(path, module_dir) == 0)
return dup(module_dirfd);
return openat(AT_FDCWD, path, O_RDONLY | O_DIRECTORY);
}
#endif
+1
View File
@@ -42,6 +42,7 @@ size_t max_alloc = (size_t)-1; /* unlimited: helpers link util2.o, where 0 makes
* secure_relative_open() fallback path). */
char *partial_dir;
char *module_dir;
int module_dirfd = -1;
/* curr_dir[]/curr_dir_len (read by secure_relative_open) are defined in
* syscall.c, which every helper links -- no stub needed here. */
filter_rule_list daemon_filter_list;