|
|
Log in / Subscribe / Register

Rust 1.58.1 released

Rust 1.58.1 released

Posted Feb 10, 2022 18:54 UTC (Thu) by nix (subscriber, #2304)
In reply to: Rust 1.58.1 released by jra
Parent article: Rust 1.58.1 released

An alternative approach that breaks much less, probably nothing, while retaining the security benefits of root-only symlinks: non-root symlinks (or, more generally, symlinks with uids/gids not specified in a new file under /proc/sys somewhere: root only by default) are only followed by the user that created them.

Now hostile users can create all the symlinks they want, as can non-hostile users, and the use case the non-hostile users wanted (they can follow them) still works, while the hostile users find that only they are following the hostile symlinks they created, but nobody else can.

(Anyone still broken by this is probably using gid-shared directories for something, like it was the 1980s still. They're probably using ACLs too. A variant mode, off by default or on only in directories with the setgid bit active or perhaps which are gid-writable, which applies the same check based on the gid of the symlink instead of the uid, would suffice for that. I'm sceptical there are enough such systems around to worry about, though.)


to post comments

Rust 1.58.1 released

Posted Feb 10, 2022 19:08 UTC (Thu) by nybble41 (subscriber, #55106) [Link] (5 responses)

> An alternative approach that breaks much less, probably nothing, while retaining the security benefits of root-only symlinks: non-root symlinks … are only followed by the user that created them.

While that is *less* problematic than limiting symlinks to root, I am still certain that would break some cases where I have used symlinks in practice. Perhaps we could just leave symlinks *alone* and fix the buggy applications instead?

For example: Say I have "$HOME/bin" symlinked to "$HOME/.local/bin" (true story) and I want to run a script located, according to the $PATH variable, at "$HOME/bin/somescript" as root via sudo. Your scheme breaks this since the bin → .local/bin symlink was created by my non-root user and needs to be followed by root to execute the script. Or more generally—say I just want to run a command as root on some file which has a symlink (which I created) somewhere in its path. Or perhaps I have versioned directories with a "latest" symlink and I want to share the path to the latest version with another user. These are all perfectly legitimate, real-world use cases which absolutely depend on the ability to create symlinks as a non-root user which will be followed by other users.

Rust 1.58.1 released

Posted Feb 10, 2022 20:58 UTC (Thu) by rahulsundaram (subscriber, #21946) [Link] (4 responses)

>Perhaps we could just leave symlinks *alone* and fix the buggy applications instead?

If fixing bugging applications were an easy way out, we wouldn't be having the conversation.

Rust 1.58.1 released

Posted Feb 10, 2022 22:56 UTC (Thu) by nybble41 (subscriber, #55106) [Link] (3 responses)

> If fixing bugging applications were an easy way out, we wouldn't be having the conversation.

I never said that it would be *easy*. Finding and eliminating bugs rarely is. You could say the same about any change to symlink semantics, of course, and any additional bugs that might introduce above and beyond *planned* loss of functionality.

Rust 1.58.1 released

Posted Feb 10, 2022 23:07 UTC (Thu) by rahulsundaram (subscriber, #21946) [Link] (2 responses)

There in lies the issue. The suggestion lacks the acknowledgment of this. If fixing bugs in the applications hasn’t worked well for so long it may very well be time to figure out what kind of mitigation strategies are possible. I will await a detailed proposal before dismissing it.

Rust 1.58.1 released

Posted Feb 11, 2022 6:52 UTC (Fri) by nybble41 (subscriber, #55106) [Link] (1 responses)

> If fixing bugs in the applications hasn’t worked well for so long it may very well be time to figure out what kind of mitigation strategies are possible.

To begin with, most applications don't need any mitigation. They just open certain paths and have no reason to care whether there were symlinks involved. If an application doesn't employ path-based access control or traverse a directory tree then symlinks probably don't affect it at all. (The issue with the Rust library function was of the latter type.) *Samba* has a particular problem with symlinks (among other things) because it's trying to implement non-native VFS semantics, validating requests in userspace before handing them off the the kernel, which is obviously going to be a rich source of TOCTTOU bugs—this, understandably, is the cause of jra's obsession. Personally I don't consider "symlinks don't mesh well with Windows-oriented network filesystem protocols" to be a good reason to cripple a very useful feature which has been part of Unix-based systems since the early days, but a Samba developer will naturally have a different perspective due to a narrow focus on the needs of their software.

Identifying the issue is easy: If your program has code like "if (check(path)) { operate_on(path); }", that's a bug. It may be a *tolerable* bug, depending on how the program is used, but it's vulnerable to changes in the filesystem between the condition and the operation. This is a classic pattern and not really filesystem-specific, much less specific to symlinks.

The mitigation strategy for filesystem TOCTTOU bugs is well-known but tedious to implement: consistently use handles rather than paths in every situation where you need to perform multiple operations on the same filesystem object. If given a path as input only use it once, to obtain the handle. Every operation after that should use the *at() family of functions, ensuring that it works on the original object even if something changes which affects path resolution—which is not just symlinks but also regular link/unlink/rename operations, changes in mount points, etc. This is exactly how the issue was mitigated in Samba, though it took several years to complete the conversion since path-based interfaces were so deeply ingrained.

Rust 1.58.1 released

Posted Feb 11, 2022 14:12 UTC (Fri) by rahulsundaram (subscriber, #21946) [Link]

> To begin with, most applications don't need any mitigation

We aren't talking about most applications, only the ones that are affected. If a few high profile applications get affected, that's enough to cause a large impact. It's never been about the majority.

> The mitigation strategy for filesystem TOCTTOU bugs is well-known but tedious to implement

Hence, the desire to have other mitigation strategies.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds