[Bug 3547] shell read is maybe too safe

Rich Felker dalias at aerifal.cx
Mon May 9 18:44:37 UTC 2011


On Mon, May 09, 2011 at 02:45:10PM +0200, Laurent Bercot wrote:
>  Oh, yes.
>  The huge majority of Unix apps *do* contain bugs wrt signals, starting
> with every app that uses a libc that does not protect system calls from
> EINTR. It's not hard to crash an entire system with signal abuse.

There is no reason for a correct program to ever check for EINTR
unless it specifically installs signal handlers and fails to specify
SA_RESTART for them. Checking for ret==-1&&errno==EINTR in your read
loop is purely bloat that does not belong in most programs.

> > Practicality dictates that the kernel-side fix is a better place for this
> > than auditing quadrazillion of syscalls in userspace code.
> 
>  That won't fix the other zillion of programs that just forget to set the
> SA_RESTART flag on the signals they trap. Better consider existing apps
> hopelessly broken and focus on doing the right thing from now on.

I can't imagine anyone using sigaction() but not setting SA_RESTART
unless their intent is to generate interrupting signals. And on Linux
and BSD systems, anyone using the legacy signal() api to install
signal handlers automatically gets SA_RESTART.

>  Does that mean that when you write a shell, you completely forbid
> yourself to use internal file descriptors ? You are not allowed to use

Yes it means that.

> open files for internal shell use ? That means, no way to listen to
> asynchronous notifications with a poll() ?

Are you thinking of that epoll nonsense? poll does not need a
dedicated file descriptor.

>  That doesn't sound right.
>  If I were to write a shell, I'd document a set of fds that are reserved
> for internal use (something high like 240-255, in order to keep low-
> numbered fds free for users), and make the shell crash with a loud error
> message if a user script is attempting to mess with fds in that reserved
> range. It's a slight breach of the specification, but it makes things
> manageable.

Hideous hack.

> > Will it work if I'll set signal handlers to SA_RESTART, but perform
> > all reads by checking data availability via poll() beforehand?
> 
>  No. A signal could still arrive between your poll() and your read().

This is what pselect() is for.

>  I'm afraid that if you're not allowed to use internal fds for notification
> purposes, you're basically screwed. Or maybe you could try to architecture
> your shell loop around a notification mechanism that does not involve fds,
> such as System V message queues. I don't even want to imagine how ugly that
> would be. XD

Or you could use threads. :-)

Rich


More information about the busybox mailing list