
Dot Dot Considered Harmful - rohan1024
https://fuchsia.googlesource.com/docs/+/HEAD/the-book/dotdot.md
======
delinka
>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.

~~~
ken
> 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.

~~~
wahern
> "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.

Except ".." also is a solution to permitting you to traverse a directory tree
without accidentally chasing an invalid pointer; no bug in your program nor
any external application can ever make ".." invalid. ".." is equivalent to a
back pointer in a linked list or tree structure. Imagine you have a handle to
/foo/bar/baz and want to ascend to baz's parent. Between acquiring the handle
to /foo/bar/baz and attempting to ascend to the parent, "baz" could have been
moved and "/foo/bar" may not exist. Without ".." all of a sudden you're
orphaned and your application is stuck in an inconsistent state. Maybe the
best solution is to just panic, but that's like saying that all applications
should be prepared for any pointer access to segfault at at any moment. That's
_one_ solution, and it's actually how some smartphone application environments
work. Another solution is _guaranteeing_ the condition can't happen, period.
Which is preferable depends on your use cases and which side of an interface
you'd prefer to place the burden. For pointers it's fairly obvious which
provides the most preferable semantics for maximum safety (or it was until the
smartphone and cloud paradigms), but for file systems the answer is less
obvious. In Unix when ascending directory trees the scenario of a valid
pointer becoming invalid is impossible such that there's always a valid path
to the root of the tree (even if the depth can change; you just stop when
opening ".." simply reopens the same directory), but for descent there remains
the race between readdir + open (as opposed to readdir atomically returning
file handles).

These particular semantics were clearly purposeful, not an accident. The
former was thought useful, the latter an acceptable simplification. It's why
in Unix you can't delete a populated directory in or when a process holds an
open reference (unlike other file types), and why you can't hardlink
directories.

~~~
ken
> no bug in your program nor any external application can ever make ".."
> invalid

Sure it can, if you consider lack of permissions to be invalid. We already do,
in other similar situations.

> Without ".." all of a sudden you're orphaned and your application is stuck
> in an inconsistent state.

No, it just means you need an out-of-band method to accomplish this.

> that's like saying that all applications should be prepared for any pointer
> access to segfault at at any moment

No, nobody's talking about crashing. It's more like saying you can't assume
you can do raw pointer arithmetic to jump around in an array. Languages like
Java and Python feel restrictive to C programmers at first, too.

> Without ".." all of a sudden you're orphaned and your application is stuck
> in an inconsistent state.

I don't understand these claims of races and segfaults. Doesn't Fuchsia avoid
race conditions like this with VFS cookies?

------
tyingq
Rob Pike apparently regrets all the "." file naming.

[https://plus.google.com/u/0/+RobPikeTheHuman/posts/R58WgWwN9...](https://plus.google.com/u/0/+RobPikeTheHuman/posts/R58WgWwN9jp)

~~~
nickysielicki
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.

~~~
donatj
My immediate thought when they announced they were shutting down was "What
about Linus's posts?!"

------
monocasa
> 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
Mach is capability based. (Mach ports are capabilities.)

~~~
monocasa
You're totally right of course.

I was falsely under the impression that the Mach port table only had a single
global namespace.

------
vermilingua
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
> 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.

~~~
c3534l
What about when it turned out Google was tracking users second-by-second
location data, even after users had removed consent and turned off locations?

~~~
icebraining
I dislike Google's data slurping practices, and moved away from Gmail and
other of their services years ago due to mistrust, but I think that was just
an honest documentation bug. The button was to disable only the Location
History feature, but the description made it sound like it was a global
setting for the whole device. As a developer, I could very well see myself
making that mistake; being embedded in the context, it's easy to miss how it
will be read by someone else.

------
csours
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.

------
yiyus
See also:
[http://doc.cat-v.org/plan_9/4th_edition/papers/lexnames](http://doc.cat-v.org/plan_9/4th_edition/papers/lexnames)

~~~
theoh
This paper, depending on how you look at it, either justifies the existence of
dot dot, or makes it seem like a wart. IMO dot dot is too well-established and
essentially sensible (in a minimal UNIX fashion) for it to be removed on a
whim. Consider the approach taken by
[https://man.openbsd.org/unveil.2](https://man.openbsd.org/unveil.2): if you
try to access a file you aren't explicitly allowed to, you get EACCESS or
ENOENT. I'm not an expert, and the possibility of errors obviously requires
applications to tread more carefully than they might have previously, but it
seems like a clean solution.

~~~
kiriakasis
> removed on a whim

They changed the whole concept of having one single root. As I understand the
plan is to use many fragmented and independent filesystem handles that can
optionally mounted together.

So the restriction is more about non being able to access a folder if you
don't have access to an appropriate handle.

Paths like folder1/folder2/../folder2/file are still perfectly fine.

~~~
theoh
To clarify: that's the Plan 9 situation. I'm talking about the merits of the
Fuchsia situation (".. is no longer available").

References to a forbidden parent directory from a chroot can just return
ENOENT, because it doesn't exist in that universe. I may not be understanding
this fully, but to condemn ".." based on some accusation that it's
incompatible with chroot semantics (or "a holdout from POSIX") seems
tendentious.

------
dsl
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](https://meyerweb.com/eric/comment/chech.html)

~~~
gowld
That's a silly article. The essay says that we should disregard essays if they
have a title like the essay's own, so... pradox.

When "considered harmful" is considered flaimbait rhetoric, perhaps the
problem is with the readers who refuse to engage with any mildly-worded
criticism.

~~~
donatj
It’s surely in how the reader interprets it, but I always read “considered
harmful” as quite mild but to the point. Something like “isn’t great”.

A refreshing opposite of clickbait as the actual proposition is in the title.

------
mattigames
For irony sake one may link this file as

    
    
        https://github.com/fuchsia-mirror/docs/blob/master/the-book/../../master/the-book/dotdot.md

~~~
Retr0spectrum
Nope, that actually 404's. It may appear to work, because most browsers will
apply some equivalent to the `__fdio_cleanpath()` function mentioned in the
article, resolving the traversal locally.

You can verify this as follows:

    
    
        curl -I --path-as-is 'https://github.com/fuchsia-mirror/docs/blob/master/the-book/../../master/the-book/dotdot.md'

~~~
mattigames
if most browsers apply it... doesn't that means it works? Maybe not in the
resolved-by-the-server-returning-a-304 sense but in at least some sense.

------
saagarjha
> 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”?

~~~
jepler
Their whole "scheme", where ".." can be dealt with as a canonicalizing step
_BEFORE_ submitting the path to the OS for actual opening, seems to require
refinement when symlinks are involved.

Take a perfectly spherical unix:

    
    
        $ mkdir /tmp/hn
        $ cd /tmp/hn
        $ ln -s . foo; mkdir bar; touch baz
        $ ls -l bar/../baz foo/baz foo/../baz
        ls: cannot access 'foo/../baz': No such file or directory
        -rw-r--r-- 1 jepler jepler 0 Nov 28 18:21 bar/../baz
        -rw-r--r-- 1 jepler jepler 0 Nov 28 18:21 foo/baz
    

Fuscsia-with-symlinks would have some extra hoops to jump through to make
rewriting act like POSIX in the case that /tmp/hn is not escaped, which surely
you'd want if you went ahead and introduced symlinks.

~~~
Dylan16807
> which surely you'd want

Nope. I don't want that at all. There's a reason that by default cd goes out
of its way to make .. ignore the parent of a symlink.

------
infinity0
> 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.

~~~
bun_at_work
I think the idea in Fuchsia is that directories can be passed as resources to
children processes, which can then move freely around in that directory
structure. If the parent passes a child "/foo/bar/", the child sees "bar/" and
it's contents, which might be "bar/baz/bingo/". The child can then move to
"/bar/baz/bingo/" do work there, and then recurse up the hierarchy. It simply
cannot ".." out of "foo/".

Hope that makes sense.

------
akerl_
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
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.

~~~
loeg
To add to that, as the document writes in the very first section, it can sort
of be thought of as a chroot. You can't .. out of a chroot; there is no "..".
(Yeah, it's not exactly a chroot; that's well covered in the document.)

------
IridiumFX
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
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.

~~~
ratmice
NLTSS as well

------
starclaps
That’s why tools like gosec complain when user input is used to access files -
specifically because ‚..‘ allows one to „escape“.

Gosec: [https://github.com/securego/gosec](https://github.com/securego/gosec)

------
IgorPartola
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
> This seems like a poorly thought out plan, and unnecessary at that.

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

------
DSingularity
Any good papers to read on fuchsia?

~~~
rohan1024
This is ironic

cd..

Here you go [https://fuchsia.googlesource.com/docs/+/HEAD/the-
book/](https://fuchsia.googlesource.com/docs/+/HEAD/the-book/)

------
hnbroseph
i really wish the "considered harmful" meme/trope/whatever would take a nap.

------
dooglius
This should probably point at the upstream page by the fuchsia project
([https://fuchsia.googlesource.com/docs/+/HEAD/the-
book/dotdot...](https://fuchsia.googlesource.com/docs/+/HEAD/the-
book/dotdot.md)) rather than a mirror source repo

~~~
sctb
Sure thing, we've updated the link from [https://github.com/fuchsia-
mirror/docs/blob/master/the-book/...](https://github.com/fuchsia-
mirror/docs/blob/master/the-book/dotdot.md).

~~~
rohan1024
I was wondering who updated it. Thanks.

------
mjfl
"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.

------
devit
That makes it impossible to properly implement POSIX on top of it and seems
like a poor design.

The correct design is to have both a "root" and a "current object" associated
with every "file descriptor object" and allow ".." to work up to the "root"
(and thoughtfully handle cases where the "current object" is moved outside the
"root").

You can't do it with paths because that doesn't track directories being
renamed, that would cause the descriptor to suddenly become inaccessible in
the middle of an operation.

~~~
empath75
> That makes it impossible to properly implement POSIX on top of it

so don't implement posix. I don't know why people get so hung up on new oses
being POSIX compliant.

~~~
vertex-four
Mostly because being POSIX compliant makes it far easier to port a lot of
command-line and server-side software quickly. Most new operating system
projects don’t have the manpower to rewrite the world - I think the last major
one was probably Android.

~~~
vlovich123
You'd be surprised how generic most code is or how easy it is to port if it's
POSIX-like. Out of the major consumer OSes, only OSX is POSIX certified (in
10.5 which is only 11 years ago). Hell, the majority of Android code is
written in Java which has no POSIX roots at all so avoiding POSIX isn't a
death knell you seem to imply. iOS, while it supports POSIX, most of the
developers use iOS-specific APIs unless they're in shared code with another OS
& not using something like Boost. Have you actually tried using POSIX
networking APIs? They're god awful. POSIX threading primitives are terrible.
etc etc.

POSIX is sometimes useful for writing cross-platform C/C++ code. It's
extremely limiting though, out-of-date, & doesn't actually offer the write-
once run anywhere you'd like with POSIX.

You can write POSIX code that will fail to build, fail at runtime, or even
behave incorrectly when you run it on another "POSIX" system (at least as far
as Windows/Linux/OSX/Android are concerned). Certainly a far cry from how a
standard is supposed to behave.

POSIX also, for the most part, targets the lowest common denominator of
platform features which means the POSIX API isn't as rich as makes sense for
the majority of applications, doesn't have the same performance/security,
and/or isn't as easy-to-use.

POSIX also leaves many subtle decisions to implementations' discretion which
means that even if everything works in the happy path, it'll break in subtle
corner cases. For example, PATH_MAX is defined as 256, _XOPEN_PATH_MAX is
1024, but Linux & OSX both have unbounded limits so a POSIX program can easily
fail to be able to open all files on an OS; making this a build-time constant
was the stupidest decision in the world & endemic of how POSIX is designed.

Most modern language runtimes these days (Rust, Go, Java, Swift) comes with a
far richer, less bug-prone & more feature-full set of features in the standard
library out-the-gate on all platforms (so you just need to port the 1 standard
library) & most libraries build on that standard library so you usually get
them for free.

Most platform vendors also provide custom APIs to interact more richly with
their specific features for performance, battery, usability, security, etc. To
take full advantage of a platform, which you're pushed to usually by market
forces, POSIX doesn't help you.

* EDIT: Also, POSIX is gigantic. The majority of useful existing tools probably use 20% of the entire standard. Porting that smaller API surface isn't challenging.

~~~
pjmlp
Basically POSIX is the C standard library they didn't want to make part of ISO
C.

As you well point out hardly significant when using other programming
languages, even C++ standard library improvements are making it less relevant
for C++ devs.

------
vinceguidry
Coming from Ruby, NodeJS annoys the crap out of me with its lack of decent
autoload functionality. Seeing relative paths in modules really annoys me. JS
world can't figure out what should be global and what should be local it
seems.

~~~
ricardobeat
What do you mean? Global packages are global, local packages are local.

------
koblas
It's interesting to think that the goal of '..' was for navigation around the
command line shell. Which is a tool that 95% of people developing software
never really use, or use as a necessity (type one command and leave). It's
really an interesting thought piece to consider that the idea of the '..'
directory is as legacy as the headphone jack.

~~~
Meph504
I think you vastly under estimate the usage of command lines by developers.
Not to mention opts and admins.

I don't think there is a week that has passed in the last 10 years that I
haven't used the command line for something.

To the point of the article, it sounds like the client will handle the work
the server once did in parsing the navigation and path commands.

Though the lack of symlinks sounds like it would be the a more painful loss
than ".."

Both of these would likely require many *nix utils to be changed to be
compatible.

~~~
ashelmire
A week! If I go an hour without using the command line, then it's because I'm
not actually coding.

~~~
BenjiWiebe
I actually code in the command line, usually. Vim.

~~~
paulddraper
Terminal, not command line.

~~~
meschi
Terminal emulator, not Terminal.

~~~
paulddraper
What does it matter if it is emulated or real?

