summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
authordzwdz2022-08-01 00:22:57 +0200
committerdzwdz2022-08-01 00:22:57 +0200
commita5333b094198487c68ad5bc43a67683030e04ed9 (patch)
treeaa0cb1c7045321fd75c1394d760318e57ff63c4d /src/user/lib
parent57e7161ce24a63e3e025d82216a15d6a95da0533 (diff)
user/fs: fs_whitelist injects directory entries
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/fs/misc.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/src/user/lib/fs/misc.c b/src/user/lib/fs/misc.c
index 0169bfe..95fef60 100644
--- a/src/user/lib/fs/misc.c
+++ b/src/user/lib/fs/misc.c
@@ -57,22 +57,71 @@ void fs_whitelist(const char **list) {
struct fs_wait_response res;
const size_t buf_len = 1024;
char *buf = malloc(buf_len);
- bool allow;
+ char *ipath;
+ bool passthru, inject;
if (!buf) exit(1);
while (!_syscall_fs_wait(buf, buf_len, &res)) {
+ ipath = res.id;
switch (res.op) {
case VFSOP_OPEN:
- allow = false;
- // TODO reverse dir_inject
+ passthru = false;
+ inject = false;
+
for (const char **iter = list; *iter; iter++) {
- size_t len = strlen(*iter); // inefficient, whatever
+ size_t len = strlen(*iter);
if (len <= res.len && !memcmp(buf, *iter, len)) {
- allow = true;
+ passthru = true;
break;
}
+ if (res.len < len &&
+ buf[res.len - 1] == '/' &&
+ !memcmp(buf, *iter, res.len))
+ {
+ inject = true;
+ }
+ }
+ if (passthru) {
+ _syscall_fs_respond(NULL, _syscall_open(buf, res.len, res.flags), FSR_DELEGATE);
+ } else if (inject) {
+ // TODO all the inject points could be precomputed
+ ipath = malloc(res.len + 1);
+ memcpy(ipath, buf, res.len);
+ ipath[res.len] = '\0';
+ _syscall_fs_respond(ipath, 0, 0);
+ } else {
+ _syscall_fs_respond(NULL, -1, 0);
+ }
+ break;
+
+ case VFSOP_READ:
+ struct dirbuild db;
+ dir_start(&db, res.offset, buf, buf_len);
+ size_t blen = strlen(ipath);
+ for (const char **iter = list; *iter; iter++) {
+ // TODO could be precomputed too
+ size_t len = strlen(*iter); // inefficient, whatever
+ if (blen < len && !memcmp(ipath, *iter, blen))
+ {
+ /* inject up to the next slash */
+ // TODO separate out into its own function
+ int ilen = 0;
+ while ((*iter)[blen + ilen]) {
+ if ((*iter)[blen + ilen] == '/') {
+ ilen++;
+ break;
+ }
+ ilen++;
+ }
+ dir_appendl(&db, (*iter) + blen, ilen);
+ }
}
- _syscall_fs_respond(NULL, allow ? _syscall_open(buf, res.len, res.flags) : -1, FSR_DELEGATE);
+ _syscall_fs_respond(buf, dir_finish(&db), 0);
+ break;
+
+ case VFSOP_CLOSE:
+ free(ipath);
+ _syscall_fs_respond(NULL, 0, 0);
break;
default: