git: 38c5d60c367e - releng/15.1 - jail: avoid leaking jail config fds to exec.* hooks
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 07 May 2026 20:40:21 UTC
The branch releng/15.1 has been updated by cperciva:
URL: https://cgit.FreeBSD.org/src/commit/?id=38c5d60c367e788341e059ee3940183c293956ba
commit 38c5d60c367e788341e059ee3940183c293956ba
Author: Jan Bramkamp <crest+freebsd@rlwinm.de>
AuthorDate: 2026-05-06 23:28:53 +0000
Commit: Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2026-05-07 20:39:42 +0000
jail: avoid leaking jail config fds to exec.* hooks
The jail(8) command must not leave parsed configuration files open
since the file descriptors will be leaked to child processes
including the untrusted exec.start or exec.stop hooks.
While fopen() doesn't provide direct access to O_CLOEXEC, it does
provide access to FD_CLOEXEC via "e" in the mode string which
provides the desired defense in depth against leaking file descriptors
into exec.* hooks since those always execve() into a shell.
Jail configuration is potentially sensitive and some hooks execute from
within the jail context, leaving some opening for the jail to exfiltrate
information about the host environment.
(Commit message wordsmithed by kevans)
Approved by: re (cperciva)
PR: 295052
Reviewed by: kevans
(cherry picked from commit 276d9b88a9e6fd6fd90e57c36444756ad297d2ab)
(cherry picked from commit c35bb8ba898482920bf9b57967a9a11f98a89c81)
---
usr.sbin/jail/config.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
index 1bad04ccde68..f1e2da215790 100644
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -321,6 +321,7 @@ static void
parse_config(const char *cfname, int is_stdin)
{
struct cflex cflex = {.cfname = cfname, .error = 0};
+ FILE *yfp = NULL;
void *scanner;
yylex_init_extra(&cflex, &scanner);
@@ -328,7 +329,7 @@ parse_config(const char *cfname, int is_stdin)
cflex.cfname = "STDIN";
yyset_in(stdin, scanner);
} else {
- FILE *yfp = fopen(cfname, "r");
+ yfp = fopen(cfname, "re");
if (!yfp)
err(1, "%s", cfname);
yyset_in(yfp, scanner);
@@ -336,6 +337,8 @@ parse_config(const char *cfname, int is_stdin)
if (yyparse(scanner) || cflex.error)
exit(1);
yylex_destroy(scanner);
+ if (yfp != NULL)
+ fclose(yfp);
}
/*