mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-29 08:08:37 +00:00
Capsicum-ize soelim(1).
As a trick to be able to access all files passed in arguments (readonly) within the sandbox we first open the root directory, then consider all files as relative to this file descriptor. This might be improved once casper add supports for filesystem. MFC after: 1 month Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D7936
This commit is contained in:
parent
f902d06ce3
commit
224d9e3ed2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305936
@ -27,15 +27,19 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stringlist.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define C_OPTION 0x1
|
||||
@ -51,18 +55,27 @@ usage(void)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
soelim_fopen(const char *name)
|
||||
static const char *
|
||||
relpath(const char *path)
|
||||
{
|
||||
while (*path == '/' && *path != '\0')
|
||||
path++;
|
||||
|
||||
return (path);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
soelim_fopen(int rootfd, const char *name)
|
||||
{
|
||||
FILE *f;
|
||||
char path[PATH_MAX];
|
||||
size_t i;
|
||||
int fd;
|
||||
|
||||
if (strcmp(name, "-") == 0)
|
||||
return (stdin);
|
||||
|
||||
if ((f = fopen(name, "r")) != NULL)
|
||||
return (f);
|
||||
if ((fd = openat(rootfd, relpath(name), O_RDONLY)) != -1)
|
||||
return (fdopen(fd, "r"));
|
||||
|
||||
if (*name == '/') {
|
||||
warn("can't open '%s'", name);
|
||||
@ -72,17 +85,17 @@ soelim_fopen(const char *name)
|
||||
for (i = 0; i < includes->sl_cur; i++) {
|
||||
snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i],
|
||||
name);
|
||||
if ((f = fopen(path, "r")) != NULL)
|
||||
return (f);
|
||||
if ((fd = openat(rootfd, relpath(path), O_RDONLY)) != -1)
|
||||
return (fdopen(fd, "r"));
|
||||
}
|
||||
|
||||
warn("can't open '%s'", name);
|
||||
|
||||
return (f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
soelim_file(FILE *f, int flag)
|
||||
soelim_file(int rootfd, FILE *f, int flag)
|
||||
{
|
||||
char *line = NULL;
|
||||
char *walk, *cp;
|
||||
@ -118,7 +131,7 @@ soelim_file(FILE *f, int flag)
|
||||
printf("%s", line);
|
||||
continue;
|
||||
}
|
||||
if (soelim_file(soelim_fopen(walk), flag) == 1) {
|
||||
if (soelim_file(rootfd, soelim_fopen(rootfd, walk), flag) == 1) {
|
||||
free(line);
|
||||
return (1);
|
||||
}
|
||||
@ -135,11 +148,15 @@ soelim_file(FILE *f, int flag)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, i;
|
||||
int ch, i, rootfd;
|
||||
int ret = 0;
|
||||
int flags = 0;
|
||||
unsigned long cmd;
|
||||
char cwd[MAXPATHLEN];
|
||||
cap_rights_t rights;
|
||||
|
||||
includes = sl_init();
|
||||
sl_add(includes, getcwd(cwd, sizeof(cwd)));
|
||||
if (includes == NULL)
|
||||
err(EXIT_FAILURE, "sl_init()");
|
||||
|
||||
@ -165,13 +182,42 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_IOCTL);
|
||||
/*
|
||||
* EBADF in case stdin is closed by the caller
|
||||
*/
|
||||
if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS
|
||||
&& errno != EBADF)
|
||||
err(EXIT_FAILURE, "unable to limit rights for stdin");
|
||||
cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_IOCTL);
|
||||
if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit rights for stdout");
|
||||
if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit rights for stderr");
|
||||
rootfd = open("/", O_DIRECTORY | O_RDONLY);
|
||||
cap_rights_init(&rights, CAP_READ, CAP_LOOKUP, CAP_FSTAT, CAP_FCNTL);
|
||||
if (cap_rights_limit(rootfd, &rights) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit rights");
|
||||
|
||||
cmd = TIOCGETA;
|
||||
if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit ioctls for stdout");
|
||||
if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit ioctls for stderr");
|
||||
if (cap_ioctls_limit(STDIN_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to limit ioctls for stdin");
|
||||
|
||||
if (cap_enter() < 0 && errno != ENOSYS)
|
||||
err(EXIT_FAILURE, "unable to enter capability mode");
|
||||
|
||||
if (argc == 0)
|
||||
ret = soelim_file(stdin, flags);
|
||||
ret = soelim_file(rootfd, stdin, flags);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
ret = soelim_file(soelim_fopen(argv[i]), flags);
|
||||
ret = soelim_file(rootfd, soelim_fopen(rootfd, argv[i]), flags);
|
||||
|
||||
sl_free(includes, 0);
|
||||
close(rootfd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user