Hacker News new | past | comments | ask | show | jobs | submit login

It seems really interesting, and a good idea.

What I don't understand though is the incentive, what motivates a program-author to "[b]e careful writing such diffs; you need to fully understand the program and handle all cases"?




In addition to the other fine replies, I'd observe this falls in the set of things that are pretty easy to use if you start with them from scratch, but are hard to retrofit on to existing code. To retrofit requires the mentioned extensive knowledge of the target codebase... to use it on a new codebase just requires you to do any sort of testing at all, note the new thing you wrote is a security violation, then think about what that means and what you should do about it at precisely the point in time you have all the relevant context loaded in your brain.

At the moment the motivation is to armor existing code, but the general case for tame across its entire lifespan is to be used in new code. In that case the motivation is the same as any other security practice... not to see your code be fingered as the vulnerability that let $BAD_THING happen.


i think the recent hiding of unused libc symbols is related to the tame effort.


No, entirely unrelated.


If there is somehow an exploitable vulnerability in the program, if exploited after the tame call the attacker only takes control of a restricted process, which hopefully mitigate or blocks the attack.

This a very smart application of the least privilege principle. The idea is that most programs don't need most syscalls after they complete their initialization, and thus dropping the privilege to use them is both cheap, safe and effective.


Presumably the program author (or OpenBSD ports maintainer) knows more about what permissions the program requires than the end-user sysadmin who would be configuring SELinux, AppArmor, etc.


It depends, really. In terms of which system calls the program needs, that's certainly true.

However, in terms of things like "which files will this program need to access", the system administrator is in a much better position, because these kinds of questions often depend on how the program is used in a particular environment.

The approaches are complementary.


I'd imagine that it would be easy to miss a disallowed system call down one rarely used path in a larger program.

It might be interesting adding the ability to do something like:

    #define TAME_ENABLE
    #define TAME_ENABLE_FOO
    #define TAME_ENABLE_BAR
    #include <foo.h>
which would cause a compile error by removing declarations for uncallable functions.


>Generally there are two models of operation. The first model requires a major rewrite of application software for effective use (ie. capsicum). The other model in common use lacks granularity, and allows or denies an operation throughout the entire lifetime of a process. As a result, they lack differentiation between program "initialization" versus "main servicing loop". systrace had the same problem. My observation is that programs need a large variety of calls during initialization, but few in their main loops.

>Some BPF-style approaches have showed up. So you need to write a program to observe your program, to keep things secure? That is insane.

>So I asked myself if I could invent a simple system call, which people would place directly into programs, between initialization and main-loop.

>Subsequent calls to tame() can reduce abilities further, but abilities can never be regained.

What you are suggesting is not compatible with tame.


What I'm suggesting is entirely compatible with tame. It doesn't change anything about the implementation, but prevents you from accidentally calling functions that would error out.

The only thing that my suggestion optionally changes is that using, eg, socket() would be a compile time error AND a runtime error, instead of only a runtime error, if you tell the system that you want it. Don't define the macros to disable functions that you are trying to make uncallable? Your code is 100% unaffected.


It's not the same because the restrictions aren't in effect at the start of the program until the tame call is made.


Again, this doesn't change anything on that front. You just don't define the declaration hiding macros in the files that do the init.

It just prevents random-seeming issues off of the common path due to calling a function that you shouldn't have called.


Reading that man page sounds like the way to go about it is start with `tame(0)` as early as possible in the program and see how it fails. then iterate pushing `tame()` down and expanding the flags until the program functions.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: