Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144532787
D46284.1775286562.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D46284.1775286562.diff
View Options
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -29,14 +29,18 @@
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/wait.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <err.h>
+#include <fcntl.h>
#include <glob.h>
#include <netdb.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -306,10 +310,79 @@
--depth;
}
+extern char **environ;
+
+static FILE *
+open_config(const char *cfname, pid_t pid[static 1])
+{
+
+ int read_fd, write_fd, exec_fd, pipes[2];
+ char *argv[] = { __DECONST(char *, cfname), __DECONST(char *, cfname), NULL };
+ FILE *file;
+
+ /* Invalidate the child PID. */
+ *pid = -1;
+
+ /* The configuration must be readable. */
+ read_fd = open(cfname, O_RDONLY);
+ if (read_fd < 0)
+ err(1, "open(): %s", cfname);
+
+ /* Try to open the configuration for execution (to parse its standard output config instead). */
+ exec_fd = openat(read_fd, "", O_EMPTY_PATH|O_EXEC);
+ if (exec_fd < 0) {
+ if (errno != EACCES)
+ err(1, "openat(): %s", cfname);
+ } else {
+ /* Read from the pipe instead of the configuration. */
+ close(read_fd);
+ if (pipe(pipes))
+ err(1, "pipe(): %s", cfname);
+ read_fd = pipes[0];
+ write_fd = pipes[1];
+
+ /* Run the configuration as child process. */
+ switch ((*pid = fork())) {
+ /* Failure to fork() is fatal. */
+ case -1:
+ err(1, "fork(): %s", cfname);
+ break;
+
+ /* Redirect the child's standard output into the pipe. */
+ case 0:
+ close(read_fd);
+ if (write_fd != STDOUT_FILENO) {
+ if (dup2(write_fd, STDOUT_FILENO) != STDOUT_FILENO)
+ err(1, "dup2(): %s", cfname);
+ close(write_fd);
+ }
+
+ // Replace the forked child with the configuration command.
+ fexecve(exec_fd, argv, environ);
+ err(1, "fexecve(): %s", cfname);
+ break;
+
+ // Close the write end of the pipe and the executable file descriptor in the parent.
+ default:
+ close(write_fd);
+ close(exec_fd);
+ break;
+ }
+ }
+
+ /* Wrap a FILE handle around the read-only file descriptor. */
+ file = fdopen(read_fd, "r");
+ if (file == NULL)
+ err(1, "fdopen(): %s", cfname);
+
+ return file;
+}
+
static void
parse_config(const char *cfname, int is_stdin)
{
struct cflex cflex = {.cfname = cfname, .error = 0};
+ pid_t child = -1;
void *scanner;
yylex_init_extra(&cflex, &scanner);
@@ -317,7 +390,7 @@
cflex.cfname = "STDIN";
yyset_in(stdin, scanner);
} else {
- FILE *yfp = fopen(cfname, "r");
+ FILE *yfp = open_config(cfname, &child);
if (!yfp)
err(1, "%s", cfname);
yyset_in(yfp, scanner);
@@ -325,6 +398,16 @@
if (yyparse(scanner) || cflex.error)
exit(1);
yylex_destroy(scanner);
+ if (child > 0) {
+ pid_t exited;
+ int status;
+ do {
+ exited = waitpid(child, &status, 0);
+ } while (exited < 0 || errno == EINTR);
+ status = WEXITSTATUS(status);
+ if (status != 0)
+ errx(status, "Config child failed with status=%i): %s", status, cfname);
+ }
}
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 7:09 AM (10 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28258184
Default Alt Text
D46284.1775286562.diff (3 KB)
Attached To
Mode
D46284: Add the ability have executable jail.conf
Attached
Detach File
Event Timeline
Log In to Comment