docs(shared): clarify authorized_root accessor contracts
Document on utils_get_authorized_root_path() that the returned pointer is borrowed and invalidated by the next authorized-root setter, that the fd and path are not read atomically (non-reentrant), and that the fd remains caller-owned. Add a matching single-threaded/set-before-threads note at the accessor definitions in utils.c. In server.c, drop the redundant utils_set_authorized_root(-1, NULL) after a failed utils_set_authorized_root(): the setter already fail-closes the state on allocation failure. The following close(root_fd) is unchanged.
This commit is contained in:
+1
-1
@@ -231,7 +231,7 @@ static bool configure_authorization(const char* root) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!utils_set_authorized_root(root_fd, resolved)) {
|
if (!utils_set_authorized_root(root_fd, resolved)) {
|
||||||
utils_set_authorized_root(-1, NULL);
|
/* The setter already cleared the fd/path state on allocation failure. */
|
||||||
close(root_fd);
|
close(root_fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ void utils_set_authorized_root_fd(int fd) {
|
|||||||
(void)utils_set_authorized_root(fd, NULL);
|
(void)utils_set_authorized_root(fd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Accessors for the process-global authorized root. The path pointer is
|
||||||
|
* borrowed and valid until the next setter call; the root is a single-threaded,
|
||||||
|
* set-before-worker-threads value (see server.c), so these carry no locking. */
|
||||||
int utils_get_authorized_root_fd(void) {
|
int utils_get_authorized_root_fd(void) {
|
||||||
return authorized_root_fd;
|
return authorized_root_fd;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -131,7 +131,15 @@ void utils_set_authorized_root_fd(int fd);
|
|||||||
* site consumes the single shared state instead of keeping its own copy. The
|
* site consumes the single shared state instead of keeping its own copy. The
|
||||||
* fd is caller-owned (see the setters): it is returned verbatim, never dup'd,
|
* fd is caller-owned (see the setters): it is returned verbatim, never dup'd,
|
||||||
* and the caller that opened it is responsible for closing it. With no root
|
* and the caller that opened it is responsible for closing it. With no root
|
||||||
* configured the fd accessor returns -1 and the path accessor returns NULL. */
|
* configured the fd accessor returns -1 and the path accessor returns NULL.
|
||||||
|
*
|
||||||
|
* The pointer returned by utils_get_authorized_root_path() is borrowed into
|
||||||
|
* process-global state and is invalidated by the next
|
||||||
|
* utils_set_authorized_root() / utils_set_authorized_root_fd() call. The fd
|
||||||
|
* and path are stored separately and read independently, so the pair is NOT
|
||||||
|
* observed atomically together; the accessors are non-reentrant and callers
|
||||||
|
* must serialize configuration (the server installs the root before any worker
|
||||||
|
* threads spawn; see utils.c). */
|
||||||
int utils_get_authorized_root_fd(void);
|
int utils_get_authorized_root_fd(void);
|
||||||
const char* utils_get_authorized_root_path(void);
|
const char* utils_get_authorized_root_path(void);
|
||||||
/* True when `path` is `root` itself or lies directly beneath it: a lexical
|
/* True when `path` is `root` itself or lies directly beneath it: a lexical
|
||||||
|
|||||||
Reference in New Issue
Block a user