Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20130417011451.GZ20323@brightrain.aerifal.cx>
Date: Tue, 16 Apr 2013 21:14:51 -0400
From: Rich Felker <dalias@...ifal.cx>
To: musl@...ts.openwall.com
Subject: Re: unexpected syscall failures

On Tue, Apr 16, 2013 at 09:02:31AM +0100, Justin Cormack wrote:
> I noticed that in some places we assume some system calls will not fail,
> one example being in nice that I was looking at the other day, but there
> are others:
> 
> return setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS, 0)+inc);
> 
> Now in Linux you can use security frameworks (eg type 2 seccomp) to make
> any system call fail. Do we want to program defensively around these cases?
> (In the case of seccomp I think most people use it to abort the program not
> error, but you can).
> 
> I am inclined to think that if someone makes getpid fail they deserve
> anything they get. I can't see any security issues, just some potentially
> confusing behaviour, eg here nice might succeed (but set errno) if
> getpriority fails. But testing does have downsides.

Yes, I'm aware of the issue and don't intend to address it. If you
take an interface that has no reason to fail (e.g. something that just
reads process-local information) and make it fail, you deserve what
you get. As far as I'm concerned, Linux security modules have a
serious security design flaw: they should not be able to deny
arbitrary syscalls (which can actually make security worse, in cases
like this) but rather deny access to resources on a more abstract
level.

Note that even if we handled the case where interfaces fail in
situations like the example you gave, that only deals with a tiny
fraction of the problem. There are much bigger issues -- for example,
in some cases, it may be impossible for the program to make forward
progress if a syscall which should not be able to fail has failed. The
best example I can think of right off is sigprocmask: if an interface
has to temporarily block signals to do its job, and can't unblock them
before returning, it has left the process in an inconsistent and
possibly-dangerous state. There are also probably places where forward
progress is impossible when getpid fails, or at least where it's
impossible to report the error (and thus the program, if it continued
running, would be running on incorrect assumptions). Another great
example is _exit -- we actually go into an infinite loop if the _exit
syscall fails, just in case somebody breaks the kernel that way, but
there's definitely nothing correct that the program can do.

Basically, to make any sort of correct program that interacts with the
system or the outside world in nontrivial ways, operations which "back
out" or provide essential status information the program might need
must be unable-to-fail. Otherwise you can get stuck in situations
where no forward progress is possible. So the short answer is that
musl is designed with the intent of using it to make correct, robust
programs, and if somebody has intentionally broken the system so that
it cannot be used in a correct and robust way, that's their fault.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.