97 comments

[ 2.6 ms ] story [ 149 ms ] thread
I got to the twentieth slide, and I still wonder:

What does tame() itself DO?

Instantly kill your process if it tries to use any syscall but the ones you have requested.
The ones _it_ has requested.
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/...

Whitelist syscalls. Any non-whitelisted syscall being invoked causes the process to be terminated with SIGKILL (or a non-blockable SIGABRT if `abort` it set). Further tame(2) calls can only further restrict the whitelist. The whitelisting can get down to just _exit(2).

I was wondering why you'd ever want to just limit yourself to _exit, but the man page answers that:

  A request value of "" restricts the process to the _exit(2)
  system call. This can be used for pure computation
  operating on memory shared with another process.
"The man page answers that" could probably be the OpenBSD motto.
It was the Unix motto. Before GNU ruined man pages...
That font makes reading difficult.
with that font and words like seperation, priviledge .... and the navigation! (would it have killed you to add just a tiny bit of javascript for a right and left arrow, or space, or page-down or...something) - it just comes off as just too unpolished. I rarely complain about form over substance but I didn't make it all the way through.
The OpenBSD folks are notorious for presenting extremely basic formatting on their sites, articles, presentations, etc. I think the Comic Sans is most likely a troll of other websites where the formatting, UI, etc, look like they got more polish than the content itself.

Move your mouse button, and keep clicking. Not really the biggest deal. If not having a JS-based presentation kept you from reading all the way through, you're probably the person who will never use tame() anyways, so... it is what it is. :P

No, I read through until I saw "priviledge" two or three times; along with "seperate" it was too much. It's 2015, a spell-check is not beyond anyone's editor.
It's likely I'll use tame() at some point, and I found the presentation annoying enough to read that I went to google and searched for information about it in an easier to digest format. Still though, point proved: if content is interesting enough, poor presentation won't entirely turn people off from learning about it.
"I think the Comic Sans is most likely a troll of other websites where the formatting, UI, etc, look like they got more polish than the content itself."

This issue has come up multiple times. At this point they're only trolling their own users.

I can understand why you're being downvoted, but I also understand the sentiment. There needs to be a way to tell the OS "I never want to see Comic Sans again".
Open the fonts folder, click "comic sans", press delete.
That works for stuff like emails and documents, but apparently not for web pages (I have actually done that on my Mac).
The link has comic sans embedded in pictures, how would an OS deal with that?
OCR all images and re-render text found to be Comic Sans. :)
I like where your head's at
If a picture contains comic sans, I don't need to view it that badly. I smell an opportunity for a new browser extension ;)
Perhaps the author is dyslexic, and wanted an easy to read font? As far as I know, Comic Sans is the only font that is easy to read for dyslexic folk that works in about every graphical web browser.
The slides are images, so the browser's support for fonts is irrelevant.
(comment deleted)
I'm dyslexic and disagree with the assessment that Comic Sans is easier to read. I stopped after the first third slide because I couldn't read it without reading each line multiple times, assuming that was indeed comic sans.
It's a running joke. Included on some of their slides and webpages is the disclaimer: "This page scientifically designed to annoy web hipsters. Donate now to stop the Comic Sans and Blink Tags "
Comic sans is not so bad.

Covering it with artifacts makes anything painful to read.

I think the OpenBSD people started doing this after the CERN presentation on the Higgs boson that also used Comic Sans. By making it slightly harder to read and therefore more difficult to scan diagonally, it increases the attention the reader gives to the text.
And yet they could have improved readability by simply using png instead of jpg. This isn't a 'hipster' thing, it's a 'be thoughtful of your users' thing.
Reminds me of Perl's taint mode. It is not the same in terms of implementation or the types of limits imposed, of course, but it has some of the same basic ideas...you have to work really hard to make some kinds of stupid mistakes when the code is tainted, and I think the same sort of idea is at play here.

I really like it when tools do the work of preventing me from doing dumb stuff. Security, in particular, is such a difficult task with so much knowledge required (particularly in a language like C) that it's almost surprising that software has as few vulnerabilities as it does.

I'm unlikely to ever start a new project in C again, but if I do find myself in a networked C project maintenance or patching situation, I certainly would consider pulling this in.

"I'm unlikely to ever start a new project in C again"

I wonder what this would look like in other languages? It would be interesting to try this out in another language.

There's a tendency to assume that because newer languages are safer than C that they are "safe". I suspect people would be unlikely to think about the problem in the same way for, say, Go or Rust, even though there are still security gotchas that can happen when dealing with system calls from those languages.

But, then again, a lot of the kinds of security bugs tame() is addressing really are already unlikely in Go or Rust. But, now that I think about it, I would like to see examples of priv-sep in Go or Rust. It's a challenging problem in C, and one that I never implemented (I was moving away from working on any C projects within a couple of years of priv-sep being introduced into OpenSSH), and one of the things that is neat about tame() is that is seems to abstract some of those difficult aspects. So, seeing best practices for priv-sep in a modern language would be really cool...I wouldn't even know where to start to figure it out, since I'm so new to both Rust and Go.

I keep wondering if it's time for a Gopen BSD or a Rust in BSDeace or some equally terrible name that means re-writing the OS except for the fiddly assembler bits in a safer language.

Where are Vernor Vinge's Focused programmers when you really need to outsource something?

lsub is currently working on a Plan 9-ish OS in Go called Clive, though still as a research system: http://lsub.org/ls/clive.html
Oh man Plan 9 broke my heart once already when they didn't become the Next Big Thing. I was digging their take on namespaces after seeing something similar for filesystems on Apollo's UNIX.

I would love to "break glass" (I.e. temporarily gain privileged access) to a remote system's namepace and dtrace/systemtap running processeses without ever leaving my desktop.

There's Redox, which was just discussed on HN yesterday: https://news.ycombinator.com/item?id=10295187

There are also a couple of projects re-implementing the standard UNIX utilities in Rust and Go. I suspect that, like Linux couldn't have exploded in popularity without an existing and excellent suite of utility programs, it's unlikely a new OS could take off without the same existing for it. Though, implementing a UNIX-like/POSIX-compatible kernel might be a reasonable starting point. So far, however, the folks working on operating systems in Rust and Go are wanting to implement actually new operating systems, not merely reimplement UNIX in those languages. Which is to say, maybe an impossible goal, I dunno. No other kind of "make a better OS" project has actually succeeded without massive financial backing, and there have been many.

> I would like to see examples of priv-sep in Go or Rust.

Both seccomp and separation of privileged processes seem fairly straightforward under Rust. (The former would require some knowledge of the syscalls Rust wants to use internally; the latter just involves fork and setuid/setgid.)

> Both seccomp and separation of privileged processes seem fairly straightforward under Rust.

I have a crate for this, the use of which should be landed in Servo any day now: https://github.com/pcwalton/gaol

> I wonder what this would look like in other languages?

The exact same. It's a syscall to restrict available syscalls. It would probably be more fraught with issues in other languages as the runtime might issue somewhat unexpected syscalls in the course of its operation.

You can call tame() from other languages, I assume it would offer just as much benefit in python or ruby.
Wouldn't it need to happen at a lower level than merely having some bindings to tame()? I mean, the interpreter itself wouldn't be subject to tame(), even if some specific C calls made within your Python or Ruby program are; when you call a Python or Ruby function that makes syscalls on your behalf (which is a lot of syscalls), they wouldn't be subject to tame(). But, maybe I'm misunderstanding how it works. It doesn't appear to be a switch that turns on tame() for the whole process.

I don't know that it would be useless when wrapped and called from Python or Ruby, but it seems unlikely to have the same effect it has on C code (but, then again, C code needs a lot more help than Python or Ruby).

Wouldn't tame applied to the process that called it? And for an interpreted language, that would be the interpreter. And if the interpreter can't is unable to do something, then the interpreted code would be unable to do it too.
Ah, yes, I guess you're right. I was thinking this wasn't just a switch for the whole process, but reading the examples again, I see that it is a switch for the whole process. So, it isn't as comparable to taint (which attaches to data, rather than the whole process) as I'd initially thought, except in the sense of being an automated method to prevent some kinds of stupid security mistakes.
Your ruby interpreter is in the same process as your ruby code. One might imagine using tame to prevent the yaml parser from calling system().
Perl's taint checking really was ahead of its time (introduced in 1988, according to Wikipedia!)

Are there other languages that have this feature? (wiki only mentions Ruby)

Taint checking offers a false sense of safety. Sure, data that originates in a request is unsafe, but does that means data retrieved from storage is safe?

The right thing to do is to move away from plain string concatenation/interpolation: don't build dynamic SQL, don't hack together strings into JavaScript or HTML - use smart, format-aware templating tools (like golang's HTML templates) and parameterization.

Data read from files is also tainted.

I disagree with the 'false sense of security' as well - just like every other security feature from any system or technique you care to name, taint checking improves security but makes absolutely no claim that it magically makes your code completely secure.

In a language with a modern type system it doesn't need to be a language-level feature. I use Scala and any use of unadorned String will be picked up in code review, because generally we prefer to use some specific type that says what it represents.
It's amusing the solution you present is code review.

I'd bet naked strings never get that far, because your business libraries all expect CustomerName or whatever.

Sure, but occasionally new programmers will do a bunch of work with a String and and only wrap it as a CustomerName before making a library call.
World of Warcraft's addon system uses a taint system to keep certain actions in the UI secure. It uses Lua, but I don't believe the taint system is available by default in Lua.
It seems really fragile that tame takes a string as argument that is tokenized and parsed? Why not just pass an array of pre-defined constants.
Because an array wouldn't be any safer than the string (still would be null-terminated or risk buffer overruns if you passed the length incorrectly), and using a string means you don't have to import a pile of constants if you want to use tame from languages other than C.
You could use bit flags to avoid the array issue. Your point about constants is reasonable although given that it's a one-time cost and there are already automated tools to do this for many popular languages, I don't think it presents a real barrier.

Edit: I see they originally use a bit mask and then changed to the space-separated string.

http://www.tedunangst.com/flak/post/string-interfaces

A bit meta, but...

Part of me appreciates that there is no magic javascript which mucks with the browser and makes the slideshow a real pain in the butt to navigate. However, this is going too far in the opposite direction. Each slide as its own page? Navigation is slow, all-but requires the mouse, and creates a N-length list of sites to go "back" through to return here.

Can we just come to a compromise: one page with each slide below the last? Allow us to take advantage of parallel fetching of assets, use native scrolling to progress, and you can even create anchors to link to a particular slide!

Even better, you could easily write some basic javascript and to turn such a page into the former version of a slideshow if you're so inclined.

Feel free to submit patches to magicpoont...
I was actually reply to gp along the lines of "blame your user agent for not providing navigation help with rel="next"[1] links" -- but having a look at the html-source, apparently magicpoint doesn't generate rel="next" links anyway...

And the link to magicpoint[2] is broken -- so where would one submit patches? The first one should probably be a new "generated by"-link that actually works...

[1] http://microformats.org/wiki/rel-next

[2] http://www.mew.org/mgp/

Magicpoint is located here:

http://member.wide.ad.jp/wg/mgp/

I've no idea how one would submit a patch though.

Fix all the bugs, upload to github, announce "magicpoint-ng is here!" Very simple. :)
Well, as far as I can tell, the URL is fixed in the latest snapshot: ftp://sh.wide.ad.jp/WIDE/free-ware/mgp-snap/mgp-snap-20150831.tar.gz -- but after a bit of fiddling I couldn't get the configure-script to build with libungif installed under my home-directory...

Looks like the html "template" is embedded in mgp.c, in the genhtml-function:

  496 static void
  497 genhtml(start_page)
  498     int start_page;
  499 {
There's apparently only one reference to "next page" (page +1):

  596         if (page < maxpage) {
  597             fprintf(html,
  598             "<A HREF=mgp%05d.html>[next&gt;]</A> "
  599             "<A HREF=mgp%05d.html>[last&gt;&gt;]</A>\n",
  600                 page + 1, maxpage);
I guess:

  596         if (page < maxpage) {
  597             fprintf(html,
  598             "<A HREF=mgp%05d.html REL='NEXT'>[next&gt;]</A> "
  599             "<A HREF=mgp%05d.html>[last&gt;&gt;]</A>\n",
  600                 page + 1, maxpage);
might do the trick?

Then one could either add a js-shim to navigate based on rel=next, or use a client with support for that. Or, use a more modern package for generating slides. That'd be my first choice. Something like pandoc with S5:

http://pandoc.org/demo/example9/producing-slide-shows-with-p...

http://meyerweb.com/eric/tools/s5/s5-intro.html

Or (I don't use Emacs, so no idea if this really works) org-s5:

https://github.com/sigma/org-s5

Then again, I suppose there are no perfect tools...

A js-shim for navigating with [←] and [→] would be definitely nice, after one added the rel=next.

And it would degrade nicely, too.

Well, if you open that single page containing all the slides, and there are many slides, you would be putting a lot of load on your server. So then you would still need some magic javascript to make it load in a delayed way.
If your server can't handle serving up 1-200 images at same time, your server sort of doesn't deserve to be on the internet.

Any server today should be able to saturate it's network connection serving static content.

If there are 1000 simultaneous requests (from many users), 1-200 images become 1,000-200,000 images. I hope you see now why your argument is flawed.
Nope. My argument "Any server today should be able to saturate it's network connection serving static content." still stands. Which I wrote as clarification to stop someone from thinking / posting what you did.

It doesn't matter how many requests for same images. Any server should be to fill network link serving static content. Even slow Apache could saturate 100Mbps 15! years ago. https://www.devside.net/articles/apache-performance-tuning

Those 200 images all fit into memory. All the server is doing is answering requests and copying those to the network interface. No disk IO, no computation, maybe not even the copy if server/nic can do zero-copy.

I understand what you say. But consider the server as being the machine including the network interface. Then, still, the pipes are going to be congested sooner with multiple images instead of a single image per page.
Most browsers (I know Firefox, Chrome, and IE) automatically limit the number of concurrent requests they'll do on a single server.

Adding JS to only prefetch, say, 10 slides forward, might be a good progressive enhancement, but not a requirement. And, along the lines of what someone else said, if your server is excessively burdened by a malicious client, or even one that doesn't execute your JS, that's a server problem.

Those arguments are flawed for the following reason. Suppose your website has a single slide per page. Let's say the website allows N simultaneous users before it breaks down (becomes too slow). Of course, even a superfast server will break down at some point.

Now, suppose browsers perform X concurrent requests (because of built-in behavior of the browser). Suddenly, you can not serve N users anymore, but only approximately N/X users.

I didn't event realize it was a slideshow until I read your comment.
(To keep the meta posts in one place)

Even the OpenBSD project is talking about "disruptive innovation"! The tech industry has really collectively jumped the shark.

(comment deleted)
This was developed to work in all browsers. Even 1995 ones. Why change it? It still works.
Because it makes the presentation hard and slow to read.
No, it wasn't developed to work in all browsers - jpgs don't work well in text-mode browsers like w3m or lynx. Likewise, jpgs of text are worthless to things like screenreaders, and there's no useful info in the alt text. jpgs of text also don't work with people who have tools to style pages so they can read them better. Ironically if they had've just used simple text, it would have worked in all browsers.

In addition to this, the OP suggests ways in which it doesn't work well. Just because something 'works', doesn't mean it can't be significantly improved.

Funny enough, JPGs can work in links.
Sure, but not on a default install. This is what I see on a basic install of lynx: http://i.imgur.com/UlxBCk4.png
Links, elinks, and lynx are different browsers.
Ah, my mistake. I just assumed that you could add a plugin for graphics. Thanks.
I remember when `graceful degradation` was still a thing...
I always found the OpenBSD slides above anything else I've seen online. I just hover my mouse over the link to the next slide and because the links stay a the same point on all pages I can just click when I want to progress.

With the exception of the slides from Henning Brauer, who pick horrible red images for the background, most of the OpenBSD slide decks are very easy to read. Do anyone really care that they're using Comic Sans?

tame() is one of those things that is so simple and obvious in retrospect that it's flabbergasting that it took so long to be invented/(re)discovered.
Probably because it's theoretically inelegant. A lot of people are quite absolutist when it comes to security, and shun solutions that aren't entirely robust to all possible edge cases.

Yet in practice, tame(2) makes privilege dropping such a trivial activity that it will quite likely influence far more programmers than a more capable but also more grueling and complex mechanism like seccomp-bpf.

Speaking of which, here's a tame(2)-like wrapper over libseccomp: https://github.com/dimkr/libwaive

Quoting myself from the lobste.rs thread[0]:

>> No matter how good the interface is, it’s almost certain this will never hit Linux in the next 5-10 years. It’s not because the interface is bad, but because the glibc-devs and other people are scared of simple and straight-forward interfaces, rather not doing anything than implementing an interface which handles the general case rather than trying to cover the 0.5% of edge cases, being complex and bloated.

> This is such a tough lesson to learn and to apply. I still fail at it most of the time in my own code, thinking up the weirdest edge cases possible that I need to handle rather than making the 99% case nice and simple.

I'm a CS grad student, I've worked in the industry before, and I am 100% guilty of sometimes dismissing a nice and simple solution because the perfectionist in me is annoyed that an edge case takes O(n^2) or that the algorithm won't give the optimal answer in some pretty rare circumstances.

[0] https://lobste.rs/s/4jlaod/tame_-_bad_kitty_no_socket_for_yo...

Even though this is mentioned as being "OpenBSD only - not a stable interface!" on slide 25...

As OpenBSD's userland and libc is used extensively in Android, I wonder what the chances are of Google embracing tame() in future versions of Android.

While it's true that Android's C library (bionic) uses code from OpenBSD libc.. tame(2) is a system call, in the kernel.
This is a system call requiring significant changes in the kernel. It also hardcodes a lot of weird implementation details into the kernel, like this description of the 'dns' request: "Subsequent to a successful open(2) of /etc/resolv.conf, a few system calls become able to allow DNS network transactions: sendto(2), recvfrom(2), socket(2), connect(2)." That's acceptable when the same people are building the kernel and the userland, like on a BSD, but it wouldn't work on Linux where the userspace is controlled by a bunch of separate parties that like changing implementation details.
Folks at Google are already working on a Linux port of Capsicum. I think its far more likely they would go with that.
http://www.openbsd.org/papers/tame-fsec2015/mgp00007.html

"Optional security is irrelevant (in the long term). Mitigation technologies which can be disabled -> fade into history"

This this this this this. As much as I like having control over my system and the ability to disable things, I've seen enough examples of users and corporate sysadmins taking years to fix basic security issues because there exists a quick and dirty workaround.

Yeah, this was, to me, the most insightful slide of the whole talk.
That is by far the best summary of selinux's history to date.
Theo mentions a hackathon in Croatia in the second slide, and some might not know this, but the OpenBSD project actually invented the concept of a hackathon in 1999 as a way of gathering their global developer community together in one place to hack on OpenBSD in a festive atmosphere.

Sixteen years later, the concept has been completely co-opted by (often VC-backed) tech companies as a means of promoting their products and extracting unpaid labor from developers.