10 ms·
Ghosts of Unix past, part 3: Unfixable designs (2010)
- pavon 5y agoTitle should have (2010)
- bediger4000 5y agoLots of difference between how unfixable design problems are treated in open source vs closed source operating systems. Is this difference good or bad?
- deleted 5y ago[deleted]
- surajrmal 5y agoI would argue being open source vs closed source doesn't matter. The governance model does as do the priorities of the project. This isn't to say you need a BDFL or single company running the project to address "unfixable" problems, but they certainly do seem to help. On a more meta note, open source means a lot of different things. There is actually a lot of nuance in the different styles of open source. Linux vs chromium vs that project that just does source dumps. Whether they accept contributions, accept bug reports/feature requests, allow you to build from source (source dumps often don't include a working build system), have open communication channels, etc can all vary. I hope we have more specific terms for the different styles of open source in the future.
- bombcar 5y agoI agree - though open source does allow for a major fork if the users don't agree with the developers (or project leadership) on how it should be fixed. Project leadership is the most significant aspect - look at Linus's absolute declaration that the kernel can "never break userspace" meaning that once an API is exported to userspace it never gets removed. This is actually similar to Microsoft's philosophy though theirs is more "business oriented" (nobody will buy Win95 if their DOS and Win 3.1 programs won't work). Another example of this is Knuth's TeX code. Open source developments seem to lean (in general) more toward "rip it out and replace everything" (see for example internal kernel APIs not exported to userspace) because access to the source means they can fix the things that touch it. Closed source programs more likely just die and get entirely replaced, otherwise they roughly try to keep working as is.
- pjmlp 5y agoHere is some food for thought, imagine Linux when all those hardliner leaders are gone.
- cbsmith 5y agoOpen source isn't a governance model.
- primis 5y agoOne of the complaints brought up - the 16 bit group/uid seems to have been fixed quite nicely in modern linux systems by adding an additional 16 bit s to each. It seems these problems aren't "unfixable" after all
- Macha 5y agoProper ACLs exist on Linux these days as an alternative to user/group permissioning as well for use cases which call for a more powerful system.
- bombcar 5y agoThe "systematic" part of things is relatively easy to handle (as the code can be made to handle anything complex) - it's the "user" interface that is harder. A user with root access wants to give access to a given file/directory to a user - this needs to be made easy to do successfully and securely. Too many times I've seen entire web directories 777 because they just wanted it to work. Commands providing "why user X can't access Y" and recommended solutions can help.
- samf 5y agoYes, this is a major problem when you introduce ACLs into unix-like systems. A comment in the article mentions the "Richacl" work. A key problem with this work was that even "chmod 777" might not get you out of a situation where an ACL was denying access. It's been over ten years since I've been involved in this; it might have changed. The POSIX draft ACLs had the same problem, where a chmod might not grant you the permission that you're asking for. Back when Solaris implemented POSIX draft ACLs, they needed to change many user-level interfaces (e.g., the chmod command and the ftp daemon) to have a chmod request work the way end users expected.
- devchix 5y agoHave you worked with setfacl(1), getfacl(1) recently? The agony they inflict makes me want to die. Do you need log dirs read by a non-root logreader? Are there nested subdirs? What are the defaults? Extra crispy boss-mode: is SELinux on? I think the extended ACLs have taken us further into the weeds, and I think the permission architecture needs to be rethink entirely. It was designed for shared university-type computing resources at a time when 30 profs and researchers shared dirs and commingle a set of files, and daemons are users with own places to keep things. No longer. The RBAC and inheritance model, I dunno, they may work correctly but they are so fiddly with so many knobs and intersections that you end up front-loading a huge amount of work; nobody wants to do that, nor have I seen it done correctly, with design and intent.
- zxzax 5y agoSomething else that doesn't often get brought up here is that kill(2) itself is an unfixable race condition waiting to happen. It's only safe to use that to signal direct child processes. In Linux, programs should be using the newer pidfd_send_signal syscall in almost every case where they would otherwise use kill(2). Edit: waitpid is also similarly broken and unfixable for a lot of the same reasons as signals, pidfds and waitid(P_PIDFD, ...) should be replacing most uses of that as well.
- colonwqbang 5y agoCould you explain what the problem is, or provide a link?
- taviso 5y agoThe primary problem is that a process could exit, and the pid might be recycled, so you kill() the wrong process.
- Jasper_ 5y agoI've always felt like it should be the case that as long as a pidfd for that process is open, the pid doesn't get recycled, so you could open the pidfd and then use kill safely, then close it later. Means you wouldn't need a whole bunch of new syscalls. Unfortunately, it seems like this idea was rejected during the introduction of pidfd.
- bombcar 5y agoIsn't the case with something like signals is that it needs to simply be left as is and instead a new API for interprocess communication be developed alongside? It seems pretty clear that they're used for way more than originally expected (did threads even exist when signals began?) - and I suspect a number of systems use other communication paths already.
- icedchai 5y agoThreads arrived relatively late to Unix, long after signals. I think Solaris 2.x was the first mainstream Unix to have threads.
- usr1106 5y agoAre you talking about kernel threads or user space threads? I believe none of them were really in Unix very early, but the time of introduction varied.
- icedchai 5y agoI was referring to kernel threads.
- usr1106 5y agoI vaguely remember that kernel threads were something new in HP-UX in the end of the 1990s. The question is, was that late? Windows NT had kernel threads from the beginning, so maybe a few years earlier. But then it took NT years to become stable enough to be used in servers, so saying they were generally ahead would not be a correct description. So if Unix is considered late (according to the GGP) and NT not a comparable competitor, who was really early? If anybody.
- pjmlp 5y agoXerox PARC workstations, Solo OS, Topaz are some early examples.
- SavantIdiot 5y agoRegarding file permissions: This kind of archeaology (or forensics) is very important. Why? Because it exposes the trial-and-error over a multi-decade evolution. Sometimes trial-and-error is used as a pejorative (brute force hacking), but over the course of decades as technology advances, it is inevitable. The author is clear to point out that much of the issue here was due to scalability, but i think there is something else at work: unknown unknowns. It is impossible to be a 100% defensive software architecture team, and "room to grow" is usually jettisoned because it can lead to sloppy code, or worse, attack vectors. It's such a hard problem and analyses like these papers are first step in what I believe will become a full-blown historic discipline of software meta-thought. I say "become" because you can't really do this kind of analysis with 5, 10 or 20 years of history: you need multiple decades, and that is just now upon us. I think there are applications for this kind of study. It can very clearly feed back into current practices, and possibly even more formalized language syntax that can be defensive and extensible. I would also love to see if this kind of analysis bears out which aspects of various languages (and architectural OS decisions) proved to be the most robust. Like with hemaglobin: it is one of the largest and oldest genes, it is hard to break via mutatation, and is shared by every animal with oxygenated blood cells. Something was done right with that design!
- wmf 5y agoThis trial-and-error history should also destroy any reverence people have for "Unix philosophy".
- pjmlp 5y agoThat is something that became cargo cult with GNU/Linux, go pick any commercial UNIX to see how much "Unix philosophy" is there.
- SavantIdiot 5y agoThat's a pretty aggro response. "Unix Philosophy" sounds like a convenient straw-man.
- jude- 5y agoI think "unfixable" is in the eye of the beholder. A lot of these design choices make a lot more sense if you believe that complex Unix applications are supposed to be built from multiple loosely-coupled programs that perform exactly one task each, and communicate by piping data to one another. I think the two design decisions discussed in this article only create problems for developers who write programs that do "too much," such that the programs can no longer make best use of the OS facilities. > Unix signals Unix signals are an asynchronous best-effort form of out-of-band IPC. Because the programs that make up your Unix application already use pipes for IPC (which are synchronous and reliable), the role of the signal handler in a program would be to either absorb the signal by taking some localized action, or translate the signal into some piped IPC message to other program(s) in the application to consume and handle. It's been pointed out elsewhere that threads and signals don't play nicely. But that shouldn't be a problem for a multi-program Unix application -- you'd keep the multi-threaded logic in a separate program(s) from the signal-handling logic, and have the signal-handling program forward the multi-threaded program the signal data in-band, via a pipe. For example, you might factor the application into a supervisor program and one or more subordinate programs (which can be multi-threaded), and have the supervisor intercept signals and route the relevant IPC notification to subordinates via pipes. > Unix permissions The "one user and one group" model for files stops being so limiting if you can make it so the different programs that make up your application run as different users and groups. For example, a "logger" program in your application would have a separate user/group ID than a "database" program, and in doing so, ensure that the "logger" program can only access log state, and the "database" program can only access database state.
- zxzax 5y agoBut that's more working around the problems than fixing them, no? You can't really move all signal handling logic to a dedicated process, because every process can receive signals. And as for databases: every major production database I've seen implements its own authentication and permission scheme, so it can do things like provide ACLs on a more granular (per-table, sometimes per-row) basis.
- jude- 5y ago
- nooyurrsdey 5y agoReally enjoyed reading about the struggles of implementing file permissions. It seems like something that should be so simple, but once you sit down and try to build it you'll realize you have to support so many uses cases. I bet if you asked everyone on HN how they'd do it, you'd end up with so many confident answers that also had shortcomings themselves.
- williesleg 5y agoWell kids, get off your ass and write a new operating system. We invented it, you all sit on your ass and do nothing but complain. With ads.
- kazinator 5y agoForgets threads! Speaking of signals, the mess of when POSIX threads collided with signals. And with fork. And chdir being process wide ...
- Juntu 5y agoBiometrical specimens can be another 5 to 20 years. No threads old now tomorrow I can create data to show easy tasks the year is decade plus one passed part 2 and 1. No threads