commit df84249f3751747a0e36c0620c2c608dc76cfb8d (patch)
parent a37db38a47c02ad652a2043e90d3e8994175260f
Author: Alex Karle <alex@alexkarle.com>
Date: Sun, 25 Apr 2021 23:59:00 -0400
kiosk: Demo super secure pledge (stdio + rpath only)
This is mostly a "spike" for fun, but it's worth keeping in the git
history if I want to go back to it.
The idea here is that kiosk will be a login shell open to anonymous,
untrusted, users. As such, I want to be SUPER sure I don't give anyone
shell access to my machine. In this iteration of kiosk, it restricts its
view to just the kiosk/ directory (and /dev/tty for prompting), and then
immediately drops privelages to just standard io and read-only access to
those limited paths. This means that even if there were a bad use of
memory or something like that, the attacker can never spawn a new
process, talk over the internet, or do anything else nefarious to hurt
the system.
The cost? Well, not having the pager ability is kind-of a pain,
especially for longer blog posts... As such, I'll likely just revert
this patch in a commit or two (maybe I'll try writing my own pager.
hmm).
Diffstat:
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/kiosk.c b/src/kiosk.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
int list(void) {
DIR *dirp = opendir(MANDIR);
@@ -46,10 +47,16 @@ void mandoc(int choice) {
int i = 0;
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_name[0] != '.' && ++i == choice) {
- char *cmd_base = "less";
- char cmd[sizeof(cmd_base) + PATH_MAX + 2];
- sprintf(cmd, "%s %s/%s", cmd_base, MANDIR, dp->d_name);
- system(cmd);
+ char path[PATH_MAX];
+ sprintf(path, "%s/%s", MANDIR, dp->d_name);
+ FILE *fd = fopen(path, "r");
+ if (fd == NULL)
+ err(1, "open");
+ char c;
+ while ((c = getc(fd)) != EOF) {
+ putc(c, stdout);
+ }
+ fclose(fd);
break;
}
}
@@ -98,14 +105,10 @@ int main(void) {
/* All unveils for this proc only (not for less) */
if (unveil(MANDIR, "r") == -1)
err(1, "unveil");
- if (unveil("/usr/bin/less", "rx") == -1)
- err(1, "unveil");
if (unveil("/dev/tty", "r") == -1)
err(1, "unveil");
- if (unveil("/bin/sh", "rx") == -1) /* for system(3) */
- err(1, "unveil");
/* no more unveil's past here! requires pledge*/
- if (pledge("stdio rpath proc exec", NULL) == -1)
+ if (pledge("stdio rpath", NULL) == -1)
err(1, "pledge");
#endif
int n = list();