-
Notifications
You must be signed in to change notification settings - Fork 8
Description
We need a library like the encasement library for Repyv2 for the 3i interface in RustPOSIX. However, in our case, it is simpler since the memory isn't shared across cages naturally. Thus, you don't have to worry about TOCTTOU because the caller and callee don't have the same bits in memory.
I propose the creation of a library which makes it so that calls are routed the correct place and the correct arguments are copied, etc. My current thinking is you define some sort of bitmask as I do below to indicate what behavior you want for each arg. Importantly, arguments that should not be copied also can be avoided. You would define an interface you wish to provide.
For example, suppose that you wanted to track the amount of data written to files by the write system call. From a pseudocode standpoint, a simple bit of code using this library could look like this:
// From the encasement setup. I don't need to pass the args types, etc. along because these are standard and don't change.
// I need a good way to indicate what should happen for each. I have things like COPY_ALL_ARGS and PASS_THROUGH_ALL
// but likely there needs to be some bitmask or similar.
...
[my_open_syscall, COPY_ALL_ARGS], // int open(const char *pathname, int flags, ...mode_t mode), do the default for each arg type
[my_write_syscall, PASS_THROUGH_POINTERS] // ssize_t write(int fd, const void buf[.count], size_t count), pass through the second argument (don't copy it or fill it in)
...
filecountmap = HashMap <string,int=0>;
int open(const char *pathname, int flags, ...mode_t mode) {
filecountmap(pathname) = 0
// This is the open call that is provided to my cage
return open(pathname,flags, mode)
}
ssize_t my_write_syscall(int fd, const void *junk, size_t count) {
// Note that junk will be set to NULL (because it isn't needed. This means that buf isn't copied)
// This is the write call that is provided to my cage
int amount_written = write(fd,NULL,count); // The second arg is ignored here due to pass through.
// if they return an error, don't -1
if (amount_written > 0) filecountmap(pathname) += amount_written;
return amount_written
}
Things to ponder about this:
-
How do we handle vargs?
-
How do we handle errno? It likely should just be passed through
-
How do I make it hard for people to accidentally add a call in the wrong place?
-
Should this get imported everywhere and turn into preprocessor statements that get resolved out before runtime?
-
Should they be able to override a non-passed parameter by passing in a value?
-
If they call a function more than once, does the non-passed parameter only get added the first time?