top | item 18554333

Dot Dot Considered Harmful

345 points| rohan1024 | 7 years ago |fuchsia.googlesource.com | reply

173 comments

order
[+] delinka|7 years ago|reply
>If a handle is provided to a directory, it should imply access to resources within that directory (and additionally, their subdirectories).

Maybe within Fuschia, but not in my UNIXy systems. All users on a system need r-x on /Users, but that doesn't give them r-x on every user's home directory located as a subdirectoy of /Users - a handle acquired by bob to /Users does not imply access to /Users/delinka.

Further, if your process is treating '..' as a subdirectory, you're doing it wrong. Paths must be normalized (e.g. ~ expanded, . and .. resolved) before requesting a handle via absolute path.

Lastly, this document reads as if knowing a full path grants access to that path and its subdirectories. If that's the case ... oy.

[+] wahern|7 years ago|reply
> Further, if your process is treating '..' as a subdirectory, you're doing it wrong. Paths must be normalized (e.g. ~ expanded, . and .. resolved) before requesting a handle via absolute path.

".." is required for atomic traversal (similar to symlinks), which is important in some situations, such as making sure a file tree you've descended isn't removed out from under you in a way that breaks your state. (The directory itself can be moved while you hold the handle, but the important thing is that being able to rely on ".." permits certain algorithms that are safer and more consistent.) Canonicalizing paths introduces race conditions between canonicalization and actual access, which is why this is performed in the kernel.

Canonicalizing paths makes sense if you're accepting paths from untrusted sources and you cannot make use of POSIX openat() + extensions like O_BENEATH. HTTP GET requests are supposed to be idempotent, anyhow, so there shouldn't exist any sort of race condition as a conceptual matter.

But in regular software, it's better to just pass paths as-is. The shell performs "~" expansion, but it doesn't resolve "." or "..". And the shell performs other expansions, like file globbing, for which there's rarely any reason to implement in regular software. Supporting "~" expansion but not file globbing is inconsistent; if you're not the shell, don't implement shell-like features as it just creates confusion and unnecessary complexity.

Calling ".." a holdout from POSIX is misleading. The semantics exist for legitimate and even security-relevant reasons, albeit not necessarily reasons that an embedded smartphone OS may care about. What POSIX lacks is O_BENEATH (from Capsicum) or a similar flag for tagging a directory descriptor to prevent relative paths or otherwise ascending the tree. Capsicum extensions make POSIX perfectly capable of implementing strict capability semantics, and they do so by extending semantics in a manner consistent with POSIX. POSIX isn't inherently broken in this regard, it's just perhaps too feature rich for some use cases and not feature rich enough for others.

There's no end of complaints about POSIX--either it's too complex or too simple. The fact is, no single specification will ever please anybody, so griping about how POSIX is broken is not only pointless but belies a failure to appreciate the underling issues. The alternative to POSIX is basically nothing. Standardizing on Linux is, at best, a lateral move. Adding optional components to specifications has proven the worse of all worlds, and like most other standards POSIX has been slowly removing some optional components altogether while making others mandatory.

[+] ken|7 years ago|reply
> Further, if your process is treating '..' as a subdirectory, you're doing it wrong.

That's the point they make. And in Unix, it's really easy to do it the "wrong" way (like, "type 3 characters" easy), so lots of people do.

Back before protected memory was common on PCs, some people said "If you're chasing pointers without being sure that it points to a valid address, you're doing it wrong". Well, perhaps so, but in practice lots of programs were doing it wrong, and it was the users who suffered.

Capabilities sound to me a bit like protected memory for persistent storage. It'll be a little inconvenient for a little while, and eventually we'll wonder how we ever lived without it.

[+] ninkendo|7 years ago|reply
The answer to that for a capability-based system would be to not grant a process access to /Users, but instead give it an opaque handle that grants access to /Users/delinka. It's definitely not how unix systems work (where you need read access to all of the parents to access a child directory), but in a capability-based system it makes sense IMO.
[+] Ajedi32|7 years ago|reply
Sure, you can do it that way; but now that process being run by bob has full access to everything owned by bob (including, for example, `/Users/bob/.ssh/id_rsa`).

Fuchsia considers that level of access to be unacceptably broad for most applications, which is why it uses a capability-based permissions model instead of a user-based one.

[+] cryptonector|7 years ago|reply
Indeed, this ship has sailed. And if .. did not exist then chdir(2) would be the same as chroot(2) unless knowing an absolute path was enough to allow you to access it (assuming --x permissions on the path's dirname's directory components) then, yeah, you wouldn't gain that much as many paths can be guessed.

There just isn't a short-cut for making sandboxes trivial to setup.

I really wish that Solaris/Illumos Zones were standard on Linux. You could have really light-weight containers as anonymous/ephemeral zones whose "init" is the program you want to sandbox, and more heavy-duty guest-like containers as Zones already is.

The difference between Zones (or BSD jails) and Linux containers is that with Zones (jails) you have to explicitly decide what to share to the zone, while with clone(2) you have to be explicit about all the things you DON'T want to share with the container. I.e., Zones requires white-listing while containers requires black-listing, and we all know that black-listing doesn't work as a security device. Granted, the kernel developers could have forgotten to virtualize something important, but when they fix that you don't have to modify and rebuild the zone/jail launcher.

[+] loeg|7 years ago|reply
I think you're confusing namespace and unix file permissions.

You can think of capability-restricted directory descriptors as (sort of) individual-fd chroots. File permissions still apply inside a chroot. But the namespace of anything outside the chroot is totally inaccessible.

[+] xg15|7 years ago|reply
> Lastly, this document reads as if knowing a full path grants access to that path and its subdirectories. If that's the case ... oy.

Well, they speak of the path as a "resource provided to a subprocess". In that context, it sounds more like a handle/file descriptor that the child process can pass to some "read", "write" or "get handles of children" syscalls - and that happens to correspond to the file object at /home/bob/foo.

If so, it wouldn't imply that knowing (or guessing) the string "/home/bob/foo" would automatically give you access to the handle.

That's just my reading of our though, no idea of that is what they actually do.

[+] noja|7 years ago|reply
It does on Ubuntu. /home/* is readable and executable to everyone.
[+] userbinator|7 years ago|reply
Lastly, this document reads as if knowing a full path grants access to that path and its subdirectories. If that's the case ... oy.

Indeed. When I read...

As a consequence, this implies that a handle to a directory can be upgraded arbitrarily to access the entire filesystem.

...I was wondering whether the author even knows what filesystem permissions are and how they work. I say let the filesystem handle resolving relative paths; and let the permissions system handle the check on whether one is allowed to access the referenced object.

[+] tyingq|7 years ago|reply
Rob Pike apparently regrets all the "." file naming.

https://plus.google.com/u/0/+RobPikeTheHuman/posts/R58WgWwN9...

[+] nickysielicki|7 years ago|reply
This comment made me realize that there are a lot of really good posts on Google Plus by people like Rob Pike, Greg Kroah-Hartman, Linus Torvalds and others. For whatever reason, systems programmers liked Google Plus.

Anyway, I hope someone is archiving them somewhere, because there's a lot of knowledge there that will otherwise be lost in a few months.

[+] charonn0|7 years ago|reply
Isn't he talking about something different, though? Specifically the convention that file names starting with "." are hidden?
[+] ori_b|7 years ago|reply
Reading that post indicates that he regrets the existence of hidden files, not the existence of '.' and '..'
[+] IgorPartola|7 years ago|reply
Your comment is a bit misleading. He is regretting introducing a bug which resulted in creation of hidden files. He isn’t regretting using . and ..
[+] monocasa|7 years ago|reply
> this is an essential idea encompassing microkernels, and other “capability-based” systems

Tiny nit, but microkernels don't imply a capability based security model. For instance Mach, QNX, Redox, etc. aren't capability based.

It's a very good idea for your microkernel to be capability based because it cuts a lot of validation out of the critical path for IPC, but it's by no means a requirement.

[+] comex|7 years ago|reply
Mach is capability based. (Mach ports are capabilities.)
[+] vermilingua|7 years ago|reply
This may be off topic, and is hard to ask without doomsaying: but can we trust Fuchsia? Google is a machine for turning user's personal data into their dollars, and has been getting more and more crafty at achieving this goal.

I want to believe that this is a good-natured effort at improving the state of modern operating systems; but I feel like I've been burned by my trust in Google too many times.

[+] landryraccoon|7 years ago|reply
> I feel like I've been burned by my trust in Google too many times

I'm genuinely curious about this. In what way do you feel burned?

I think I get what you're saying. I use gmail and Google uses an algorithm on gmail to decide what ads to show me when I do a search. The ads make money for Google and I don't get any of that money. All I get is free search results. I think what you're saying is that because Google is using your information to show you ads and make money that somehow you feel cheated?

But I don't feel particularly burned by this arrangement. If Google gave an option to start charging me money to avoid ads if I'm honest with myself I'm pretty sure I'll choose to continue seeing ads instead. I guess I'm curious about exactly how you feel burned.

[+] brianpgordon|7 years ago|reply
Well, it's open source. Are there mysterious binary blobs that I'm not aware of? If not, then when this becomes Google's new mobile OS then it's going to be the same as the situation today with AOSP running a bunch of untrustworthy closed-source Google services and apps.
[+] StreamBright|7 years ago|reply
There is no chance that you do massive surveillance in a microkernel. There might be running an app on the top of the kernel that does that sure, and yes we cannot trust google with mobile OS like Android but I think developing a microkernel is fine.
[+] csours|7 years ago|reply
I'm very surprised that I agree after reading. As I read initially, I was thinking "what about..." but it's really about separation of concerns.
[+] dsl|7 years ago|reply
It is ironic this is coming out of a company with an internal site dedicated to depreciating "Considered Harmful" because it is the epitome of grandstanding.

Here is some further reading on why we should downvote these types of things into oblivion: https://meyerweb.com/eric/comment/chech.html

[+] mattigames|7 years ago|reply
For irony sake one may link this file as

    https://github.com/fuchsia-mirror/docs/blob/master/the-book/../../master/the-book/dotdot.md
[+] saagarjha|7 years ago|reply
> at the time of writing, symbolic links do not exist on Fuchsia

Is this for technical reasons, or similar philosophical ones because symbolic links also allow for escaping from “jails”?

[+] infinity0|7 years ago|reply
> What about shell traversal? > [..] For example, if the CWD is “/foo/bar”, and a user calls “cd ..”, then the underlying call may be transformed into “chdir /foo/bar/..”, which can be canonicalized to “/foo”.

So fuchsia also won't have CWD, then? Because if it has CWD, then the process can always chdir / rendering this lack-of-.. exercise pointless.

[+] akerl_|7 years ago|reply
Given that they’re still resolving “..”, they’re just resolving it in code client-side before requesting the content, they really haven’t gotten rid of “..”: they’ve implemented a path sanitization library, similarly to how many other frameworks (notably those designed to serve files over the web) behave.
[+] itp|7 years ago|reply
No, it's deeper than that. They are describing the capabilities of a process handed a file descriptor, which means it does not have a path at all. There's no way to resolve '..' relative to no path.

Compare that to a POSIX system where a directory has an actual child which is a reference to the directory's parent whose name is always '..'.

The talk about resolving '..' is merely a demonstration that the behavior of "cd .." can be supported/emulated in a context where you have both an open directory and corresponding path, without requiring that '..' literally exist.

[+] ivanbakel|7 years ago|reply
That is getting rid of ".." - the client-side version is fundamentally different in behaviour, since it can't be resolved without prior knowledge of the filesystem. ".." isn't being sanitised from user paths, it's being translated, because there is no equivalent concept in the file server.
[+] IridiumFX|7 years ago|reply
It’s a thing born in google. It shows. The reasoning behind problems and solutions is so abstract that makes for a beautiful paper or a nightmarish reality. In the ‘80s there was a little known machine, called the Commodore Amiga. Paths were addressed by a volume:folder/file schema. Apps had logical volumes too (progdir:) and the os injected others (env: temp: fonts: ..) guess what? Just use that schema and control what an app can access or not. If you don’t give me a volume for a disk, I cannot make my way to it if it’s not collated into a mountpoint thing
[+] wmf|7 years ago|reply
This particular idea wasn't born in Google; it traces back through previous secure OSes like EROS and KeyKOS maybe with a dash of Plan 9 thrown in.
[+] ycmbntrthrwaway|7 years ago|reply
What you describe is called "namespaces". Plan 9 and Linux have them already.
[+] mixmastamyk|7 years ago|reply
I wouldn't say the Amiga was little known, though it did lose the war over the desktop.

I like that syntax by the way, kind of like drive letters but much more descriptive and not limited to A-Z. Netware also used it for full path specs.

[+] trasz|7 years ago|reply
I believe it comes from DIGITAL systems, eg VMS.
[+] GauntletWizard|7 years ago|reply
Docker "Volumes" are headed that way... but aren't quite there yet. There's a lot of finer detail to hash out first, though.
[+] IgorPartola|7 years ago|reply
So can a process create a symlink a la

    ln -s ../../.. root
And gain access? Or are symlinks now fucked with too? This seems like a poorly thought out plan, and unnecessary at that.
[+] otabdeveloper1|7 years ago|reply
> This seems like a poorly thought out plan, and unnecessary at that.

Welcome to Google Future (c). Enjoy your stay.

[+] hnbroseph|7 years ago|reply
i really wish the "considered harmful" meme/trope/whatever would take a nap.
[+] mjfl|7 years ago|reply
"considered harmful" considered harmful

The origin of the meme was an editor's labeling of Dijkstra's commentary. Titling your own article this makes it seem like you wrote the article, forgot you wrote it, found it again, and are presenting it to others as an interesting perspective.