Re: 2.1.82 & reproducible strange name module loading requests

Gabriel Paubert (paubert@iram.es)
Wed, 28 Jan 1998 11:27:12 +0100 (MET)


On Tue, 27 Jan 1998, Trevor Johnson wrote:

> I found that the GPF only happens when I run sshd from inetd. When I run
> it standalone, there is no problem. Here is the line from my inetd.conf:
>
> ssh stream tcp nowait root /usr/sbin/tcpd /usr/sbin/sshd -i
>
> Here is an strace of the sshd process from the time I press ^D to log out:
>
> # strace -p 203
> select(10, [5 9], [], NULL, NULL) = 1 (in [5])
> time(NULL) = 885951253
> read(5, "\0\0\0\n9H\216\346\370\244\227\n"..., 16384) = 20
> select(10, [5 9], [8], NULL, NULL) = 1 (out [8])
> time(NULL) = 885951253
> write(8, "\4", 1) = 1
> select(10, [5 9], [], NULL, NULL) = 1 (in [9])
> time(NULL) = 885951253
> read(9, "^D\10\10", 16384) = 4
> select(10, [5 9], [], NULL, {0, 17000}) = 1 (in [9], left {0, 20000})
> time(NULL) = 885951253
> read(9, "logout\r\n", 16384) = 8
> select(10, [5 9], [], NULL, {0, 17000}) = 1 (in [9], left {0, 0})
> time(NULL) = 885951253
> read(9, "\33[H\33[J", 16384) = 6
> select(10, [5 9], [], NULL, {0, 17000}) = 1 (in [9], left {0, 20000})
> --- SIGCHLD (Child exited) ---
> wait4(-1, [WIFEXITED(s) && WEXITSTATUS(s) == 0], 0, NULL) = 205
> sigaction(SIGCHLD, {0x8051ce0, [],
> SA_STACK|SA_RESTART|SA_INTERRUPT|SA_ONESHOT|0x7fff530}, {0x8051ce0, [],
> 0}) = 0
> sigreturn() = ? (mask now [])
> +++ killed by SIGSEGV +++
>

Ok, it's in sys_sigreturn. I was wrong when I said that the code
disallows null segment selectors :-( Now that I look back at it, it uses
the following macro to copy SS and CS, in arch/i386/kernel/signal.c.

#define COPY_SEG_STRICT(seg) \
{ unsigned int tmp = context->seg; \
if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
regs->x##seg = tmp; }

which should be changed to

#define COPY_SEG_STRICT(seg) \
{ unsigned int tmp = context->seg; \
if ((tmp & 3) != 3) goto badframe; \
regs->x##seg = tmp; }

Intel doc is quite clear about it, attempting to load CS or SS with a null
descriptor will result in a GPF, and this macro is only used to copy
these 2 segment registers.

This does not solve the other problem, the application is buggy: the
signal handler modifies the context it is passed in an uncontrolled way
and it wil be killed in any case. But it will avoid an oops ;)

Gabriel.