capable() during kernel init was Re: 2.1.111: Could not allocate TCP control block

Andi Kleen (ak@muc.de)
Thu, 30 Jul 1998 00:14:09 +0200


[Andrew Morgan and Linus CC'ed]

On Wed, Jul 29, 1998 at 06:47:49AM +0200, Andrew McGregor wrote:
>
>
> Andi Kleen wrote:
>
> > Andrew McGregor <andrew@indranet.co.nz> writes:
> >
> > > (Please CC: me, as I read the digest form of the list and replying can be messy.)
> > >
> > >
> > > I just compiled 2.1.111 (UP) and got this message when I tried to boot it:
> > >
> > > kernel panic: Could not allocate TCP control block
> > >
> > > upon which it hung, saying "in swapper task, not syncing.".
> >
> > My 2.1.111 kernel source does not contain this message. Did you really get
> > this exact message, or do you use any non-standard modules?
> >
> > -Andi
> >
> >
>
> I didn't get that exact message, I relied on memory and got it wrong.
> Here's the code which created it, from tcp_ipv4.c, the panic is line 1777:
>
> tcp_socket->inode = &tcp_inode;
> tcp_socket->state = SS_UNCONNECTED;
> tcp_socket->type=SOCK_RAW;
>
> if ((err=ops->create(tcp_socket, IPPROTO_TCP))<0)
> panic("Failed to create the TCP control socket, err=%d.\n", err)
> ;
>
> The err= etc. is mine, to help debug a bit further.
> When I boot this it gives
>
> Failed to create the TCP control socket, err=-1.
>
> which is EPERM.
>
> As far as I can see, this comes from af_inet.c:inet_create lines 376-378:
>
> case SOCK_RAW:
> if (!capable(CAP_NET_RAW))
> goto free_and_badperm;
>
> which results in inet_create returning -EPERM, which is silly during bootup!

Ok, the problem is clear now.

capable is defined as:

extern inline int capable(int cap)
{
if (cap_raised(current->cap_effective, cap))

and sock_init() is called early in start_kernel() before current has any meaning. In most
cases it happens to work anyways because there is the right junk on the bottom of the
stack 8k segment, in your case it doesn't.

Possible solutions:
- Move sock_init() into init
- Add a special in_kernel or in_init flag for this case.

The special flag has the disadvantage that it is much harder to maintain in the long run
(because testing it in the capable() inline would bloat the kernel, and adding it to all
cases that might be called is hard and it is easy to miss one)

Linus, what do you think?

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html