Kevin Kofler via devel wrote:
But the thing is, fstatat is not really a newer version of fstat, it
unfortunately has very different security properties. fstat allows
retrieving the stat metadata only of already open files (if you know or
guess the fd). On the other hand, fstatat allows retrieving the stat
metadata of ANY file on the file system. It even accepts an absolute path
as the relative pathspec, in which case the fd is ignored entirely. (And I
guess it also allows directory traversal using "..", but that does not
matter anyway since it also accepts absolute paths to begin with.) And the
only way to distinguish the fstat case ("" pathspec) from the stat case
(absolute pathspec) is to actually look at the string, which cannot be
done in BPF.
Actually, there is one way the SIGSYS handler could call back into fstatat
without triggering another SIGSYS: instead of passing the original empty
string, it could pass a global empty string constant, which has a known
address that could be whitelisted in BPF.
So the BPF would look like:
if (args[3] == AT_EMPTY_PATH) {
if (args[1] == global_empty_string) { // pointer comparison
allow();
} else {
trap(); // to the SIGSYS handler checking that the string is empty
}
} else {
error(EACCES);
}
But all this is just papering over the fact that the fstatat syscall is just
too flexible for sandboxing.
Kevin Kofler