Page MenuHomeFreeBSD

D7936.id20458.diff
No OneTemporary

D7936.id20458.diff

Index: head/usr.bin/soelim/soelim.c
===================================================================
--- head/usr.bin/soelim/soelim.c
+++ head/usr.bin/soelim/soelim.c
@@ -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 @@
exit(EXIT_FAILURE);
}
+static const char *
+relpath(const char *path)
+{
+ while (*path == '/' && *path != '\0')
+ path++;
+
+ return (path);
+}
+
static FILE *
-soelim_fopen(const char *name)
+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 @@
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 @@
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 @@
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 @@
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);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 16, 3:27 PM (6 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15826760
Default Alt Text
D7936.id20458.diff (3 KB)

Event Timeline