On 2024-12-11, Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote: > On Thu, Dec 12, 2024 at 02:56:59AM +1100, Aleksa Sarai wrote: > > > I think RESOLVE_BENEATH is usually more along the lines of what programs > > that are trying to restrict themselves would want (RESOLVE_IN_ROOT is > > what extraction tools want, on the other hand) as it only blocks ".." > > components that move you out of the directory you expect. > > > > It also blocks absolute symlinks, which this proposal does nothing about > > (it even blocks magic-links, which can be an even bigger issue depending > > on what kind of program we are talking about). Alas, RESOLVE_BENEATH > > requires education... > > So does this prctl, when you get to that - any references to "service manager" > that might turn it on are contradicted by the "after startup" bit in the > original posting. > > IOW, I very much doubt that this problem is amenable to cargo-culting. I'm not sure I understand what you're saying -- was this comment intended for me or Matthew? I was just trying to say that: 1. Most programs that want to access config files or static files to serve as a web server where there might be ".." symlinks would probably want RESOLVE_BENEATH behaviour (using the config directory as the root) because that will only block escaping ".."s (and will also block absolute symlinks as well as magic-links that can escape too -- which are also issues that you need to deal with anyway). 2. Blocking this on a process-wide level could cause issues for any given program because the language's stdlib or runtime could internally do a ".." open operation, and if that fails the runtime might decide to crash the program (we've run into issues like this in Go -- though those were related to errors from pthread_* functions). If the service manager sets the prctl then if the link loader or glibc on startup have to resolve ".." due to the way the system was set up, you would also get errors (and probably a crash). Obviously, some users would prefer the application crash rather than resolving a "..", but most would not which is why I'm unsure of how much this will help solve the problem in practice. As a devils-advocate proposal, I wonder if we could instead do something like nosymfollow (so nodotdot?) where you can mark particular mounts to have this restriction. This could be used to limit all ".."s globally for a process using a mntns, but it could also be scoped to application data directories (or to all untrusted directories) without requiring program changes (the same argument was used for adding nosymfollow when RESOLVE_NO_SYMLINKS existed). Obviously there would be problems with this proposal -- unlike nosymfollow (which is more like nodev or noexec in concept, and so is more about conceptually restricting access modes of inodes -- even though nosymfollow is piped through namei), this is would be nd->mnt impacting how lookups work, which seems kinda ugly and would burn another MS_ flag (the final one aside from internal ones AFAICS)... Just food for thought. (I think LOOKUP_NO_DOTDOT / RESOLVE_NO_DOTDOT is the most usable solution for most programs that really need this, fwiw.) > _If_ somebody wants to collect actual information about the use patterns, > something like prctl that would spew a stack trace when running into > .. would be an obvious approach, but I would strongly object to even > inserting a tracepoint of that sort into the mainline kernel. You probably don't need a custom tracepoint, I expect they can get most of the information they'd need with bpftrace. -- Aleksa Sarai Senior Software Engineer (Containers) SUSE Linux GmbH <https://www.cyphar.com/>
Attachment:
signature.asc
Description: PGP signature