public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* kernel NULL pointer deref in pipe() - hotplug in initramfs
@ 2006-12-02 23:55 Michael Tokarev
  2006-12-03  9:10 ` Andrew Morton
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Tokarev @ 2006-12-02 23:55 UTC (permalink / raw)
  To: Linux-kernel

When /sbin/hotplug is present in initramfs, and it's a shell
script, kernel OOPSes on every hotplug invocation.  Here's an
example:

<4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
<1> printing eip:
<4>c015c80a
<1>*pde = 00000000
<0>Oops: 0000 [#2]
<4>Modules linked in:
<0>CPU:    0
<0>EIP:    0060:[<c015c80a>]    Not tainted VLI
<0>EFLAGS: 00010282   (2.6.19-c3 #2.6.19.0)
<0>EIP is at create_write_pipe+0x1a/0x1c0
<0>eax: 00000000   ebx: bfb07cfc   ecx: 00000000   edx: c13915a0
<0>esi: cf739820   edi: ffffffff   ebp: c13a2fa8   esp: c13a2f40
<0>ds: 007b   es: 007b   ss: 0068
<0>Process hotplug (pid: 34, ti=c13a2000 task=c13915a0 task.ti=c13a2000)
<0>Stack: 00001fff c1382da0 c137fba0 c1387b7c 00000000 c12b2ce0 080dfd04 080dfd04
<0>       00000003 c015a27f 00000000 c1382da0 b7f64d30 00000004 c011412a 00000000
<0>       bfb07cfc 00000004 ffffffff c015cfde c137fba0 bfb07cfc 00000004 ffffffff
<0>Call Trace:
<0> [<c015cfde>] do_pipe+0xe/0xa0
<0> [<c0107cac>] sys_pipe+0xc/0x40
<0> [<c0102eb7>] syscall_call+0x7/0xb
<0> [<b7f6607d>] 0xb7f6607d
<0> =======================
<0>Code: 00 00 00 89 b3 74 01 00 00 89 d8 5b 5e c3 8d 76 00 57 56 53 83 ec 40 e8 35 bb ff ff 89 c6 85 c0 0f 84 7b 01 00 00 a1 c0 85 2d c0 <8b> 40 14 e8 de d0 00 00 89 c3 85 c0 0f 84 44 01 00 00 e8 8f ff
<0>EIP: [<c015c80a>] create_write_pipe+0x1a/0x1c0 SS:ESP 0068:c13a2f40
<4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
<1> printing eip:
...[more entries like this follows]...

(note also the formatting is a bit wrong here -- that <4> prefix in front of <1>BUG..)

The only pipe() call in my hotplug script is this:

case "$ACTION:$SUBSYSTEM" in
add:block)
  ...
  usage="$(/bin/blkid $dev 2>/dev/null | cut -d\  -f2-)"
...


This is 2.6.19 running on an x86 machine (VIA C3 "Ezra" CPU if that matters).
The same thing happens on 2.6.18, but the error was slightly different (due
to introduction of create_write_pipe() routine in 2.6.19).

Are pipes disallowed in hotplug fired off initramfs?
(Even if they are, kernel probably still should not OOPS like that ;)

The error seems to be harmful however.  That is, hotplug script does not
run, but the kernel continues running.

Thanks.

/mjt

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: kernel NULL pointer deref in pipe() - hotplug in initramfs
@ 2006-12-03  8:43 Chuck Ebbert
  2006-12-03 11:34 ` Michael Tokarev
  0 siblings, 1 reply; 4+ messages in thread
From: Chuck Ebbert @ 2006-12-03  8:43 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: linux-kernel

In-Reply-To: <45721258.1070802@tls.msk.ru>

On Sun, 03 Dec 2006 02:55:04 +0300, Michael Tokarev wrote:

> When /sbin/hotplug is present in initramfs, and it's a shell
> script, kernel OOPSes on every hotplug invocation.

Does this mean that if it's _not_ a shell script everything
is fine?

----------------------
<4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
<1> printing eip:
<4>c015c80a
<1>*pde = 00000000
<0>Oops: 0000 [#2]
<4>Modules linked in:
<0>CPU:    0
<0>EIP:    0060:[<c015c80a>]    Not tainted VLI
<0>EFLAGS: 00010282   (2.6.19-c3 #2.6.19.0)
<0>EIP is at create_write_pipe+0x1a/0x1c0
<0>eax: 00000000   ebx: bfb07cfc   ecx: 00000000   edx: c13915a0
<0>esi: cf739820   edi: ffffffff   ebp: c13a2fa8   esp: c13a2f40
<0>ds: 007b   es: 007b   ss: 0068
<0>Process hotplug (pid: 34, ti=c13a2000 task=c13915a0 task.ti=c13a2000)
<0>Stack: 00001fff c1382da0 c137fba0 c1387b7c 00000000 c12b2ce0 080dfd04 080dfd04
<0>       00000003 c015a27f 00000000 c1382da0 b7f64d30 00000004 c011412a 00000000
<0>       bfb07cfc 00000004 ffffffff c015cfde c137fba0 bfb07cfc 00000004 ffffffff
<0>Call Trace:
<0> [<c015cfde>] do_pipe+0xe/0xa0
<0> [<c0107cac>] sys_pipe+0xc/0x40
<0> [<c0102eb7>] syscall_call+0x7/0xb
<0> [<b7f6607d>] 0xb7f6607d
<0> =======================
<0>Code: 00 00 00 89 b3 74 01 00 00 89 d8 5b 5e c3 8d 76 00 57 56 53 83 ec 40 e8 35 bb ff ff 89 c6 85 c0 0f 84 7b 01 00 00 a1 c0 85 2d c0 <8b> 40 14 e8 de d0 00 00 89 c3 85 c0 0f 84 44 01 00 00 e8 8f ff
<0>EIP: [<c015c80a>] create_write_pipe+0x1a/0x1c0 SS:ESP 0068:c13a2f40
<4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
<1> printing eip:
----------------------

> (note also the formatting is a bit wrong here -- that <4> prefix in front of <1>BUG..)

Yeah, that's from the previous oops.  I don't know why bust_spinlocks() leaves
that hanging space, but it's been that way for a long time.

BTW did you hand-edit the kernel .version file? "(2.6.19-c3 #2.6.19.0)"
should not print unless you put that 2.6.19.0 there yourself.

> Are pipes disallowed in hotplug fired off initramfs?

AFAICT the pipe filesystem isn't registered yet, so probably not.

> (Even if they are, kernel probably still should not OOPS like that ;)

Either (a) pipefs should be registered early, or (b) the call should just
fail instead of oopsing. Untested patch for (b) below, can you test it?
(I'm not messing with the init sequence.)

> The error seems to be harmful however.  That is, hotplug script does not
> run, but the kernel continues running.

You mean harmless, right?


Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>

--- 2.6.19.0.2-32.orig/fs/pipe.c
+++ 2.6.19.0.2-32/fs/pipe.c
@@ -839,9 +839,11 @@ static struct dentry_operations pipefs_d
 
 static struct inode * get_pipe_inode(void)
 {
-	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
+	struct inode *inode = NULL;
 	struct pipe_inode_info *pipe;
 
+	if (pipe_mnt)
+		inode = new_inode(pipe_mnt->mnt_sb);
 	if (!inode)
 		goto fail_inode;
 
-- 
Chuck
"Even supernovas have their duller moments."

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: kernel NULL pointer deref in pipe() - hotplug in initramfs
  2006-12-02 23:55 Michael Tokarev
@ 2006-12-03  9:10 ` Andrew Morton
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Morton @ 2006-12-03  9:10 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: Linux-kernel

On Sun, 03 Dec 2006 02:55:04 +0300
Michael Tokarev <mjt@tls.msk.ru> wrote:

> When /sbin/hotplug is present in initramfs, and it's a shell
> script, kernel OOPSes on every hotplug invocation.  Here's an
> example:
> 
> <4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
> <1> printing eip:
> <4>c015c80a
> <1>*pde = 00000000
> <0>Oops: 0000 [#2]
> <4>Modules linked in:
> <0>CPU:    0
> <0>EIP:    0060:[<c015c80a>]    Not tainted VLI
> <0>EFLAGS: 00010282   (2.6.19-c3 #2.6.19.0)
> <0>EIP is at create_write_pipe+0x1a/0x1c0
> <0>eax: 00000000   ebx: bfb07cfc   ecx: 00000000   edx: c13915a0
> <0>esi: cf739820   edi: ffffffff   ebp: c13a2fa8   esp: c13a2f40
> <0>ds: 007b   es: 007b   ss: 0068
> <0>Process hotplug (pid: 34, ti=c13a2000 task=c13915a0 task.ti=c13a2000)
> <0>Stack: 00001fff c1382da0 c137fba0 c1387b7c 00000000 c12b2ce0 080dfd04 080dfd04
> <0>       00000003 c015a27f 00000000 c1382da0 b7f64d30 00000004 c011412a 00000000
> <0>       bfb07cfc 00000004 ffffffff c015cfde c137fba0 bfb07cfc 00000004 ffffffff
> <0>Call Trace:
> <0> [<c015cfde>] do_pipe+0xe/0xa0
> <0> [<c0107cac>] sys_pipe+0xc/0x40
> <0> [<c0102eb7>] syscall_call+0x7/0xb
> <0> [<b7f6607d>] 0xb7f6607d
> <0> =======================
> <0>Code: 00 00 00 89 b3 74 01 00 00 89 d8 5b 5e c3 8d 76 00 57 56 53 83 ec 40 e8 35 bb ff ff 89 c6 85 c0 0f 84 7b 01 00 00 a1 c0 85 2d c0 <8b> 40 14 e8 de d0 00 00 89 c3 85 c0 0f 84 44 01 00 00 e8 8f ff
> <0>EIP: [<c015c80a>] create_write_pipe+0x1a/0x1c0 SS:ESP 0068:c13a2f40
> <4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
> <1> printing eip:
> ...[more entries like this follows]...
> 
> (note also the formatting is a bit wrong here -- that <4> prefix in front of <1>BUG..)
> 
> The only pipe() call in my hotplug script is this:
> 
> case "$ACTION:$SUBSYSTEM" in
> add:block)
>   ...
>   usage="$(/bin/blkid $dev 2>/dev/null | cut -d\  -f2-)"
> ...
> 
> 
> This is 2.6.19 running on an x86 machine (VIA C3 "Ezra" CPU if that matters).
> The same thing happens on 2.6.18, but the error was slightly different (due
> to introduction of create_write_pipe() routine in 2.6.19).
> 
> Are pipes disallowed in hotplug fired off initramfs?
> (Even if they are, kernel probably still should not OOPS like that ;)
> 
> The error seems to be harmful however.  That is, hotplug script does not
> run, but the kernel continues running.
> 

blah.  pipefs isn't mounted yet.  I assume that swapping the order of the
calls to populate_rootfs() and do_basic_setup() in init/main.c:init() will
help.

I wonder what to do about this.  Perhaps create a new post-initramfs
initcall level.  Or mount pipefs before running populate_rootfs().  Or
require that the "drivers which want to access firmware files" be modular.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: kernel NULL pointer deref in pipe() - hotplug in  initramfs
  2006-12-03  8:43 kernel NULL pointer deref in pipe() - hotplug in initramfs Chuck Ebbert
@ 2006-12-03 11:34 ` Michael Tokarev
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Tokarev @ 2006-12-03 11:34 UTC (permalink / raw)
  To: Chuck Ebbert; +Cc: linux-kernel

Chuck Ebbert wrote:
> In-Reply-To: <45721258.1070802@tls.msk.ru>
> 
> On Sun, 03 Dec 2006 02:55:04 +0300, Michael Tokarev wrote:
> 
>> When /sbin/hotplug is present in initramfs, and it's a shell
>> script, kernel OOPSes on every hotplug invocation.
> 
> Does this mean that if it's _not_ a shell script everything
> is fine?

It means that if there's no pipe() call, everything is fine.
That is, for a shell script it's just more likely to contain
some pipelines.

[]
>> <0>EFLAGS: 00010282   (2.6.19-c3 #2.6.19.0)
[]
>> <4> <1>BUG: unable to handle kernel NULL pointer dereference at virtual address 00000014
>> (note also the formatting is a bit wrong here -- that <4> prefix in front of <1>BUG..)
> 
> Yeah, that's from the previous oops.  I don't know why bust_spinlocks() leaves
> that hanging space, but it's been that way for a long time.

So can this be fixed, too? ;)

> BTW did you hand-edit the kernel .version file? "(2.6.19-c3 #2.6.19.0)"
> should not print unless you put that 2.6.19.0 there yourself.

Yes I did.  For an rpm- or deb-based kernel, the "build number" is irrelevant
(it's always 1, since both rpm and deb rebuilds everything from scratch).
This #2.6.19.0 comes from the package revision number - I just do
  echo $revision > .version
and remove the part from Makefile which updates the file on every (re)build.
But this isn't relevant for the discussion.

>> Are pipes disallowed in hotplug fired off initramfs?
> 
> AFAICT the pipe filesystem isn't registered yet, so probably not.
> 
>> (Even if they are, kernel probably still should not OOPS like that ;)
> 
> Either (a) pipefs should be registered early, or (b) the call should just
> fail instead of oopsing. Untested patch for (b) below, can you test it?
> (I'm not messing with the init sequence.)
> 
>> The error seems to be harmful however.  That is, hotplug script does not
>> run, but the kernel continues running.
> 
> You mean harmless, right?

Yup.  Oh those foreign languages... :)

> Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
> 
> --- 2.6.19.0.2-32.orig/fs/pipe.c
> +++ 2.6.19.0.2-32/fs/pipe.c

Another funny revision number? ;)

> @@ -839,9 +839,11 @@ static struct dentry_operations pipefs_d
>  
>  static struct inode * get_pipe_inode(void)
>  {
> -	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
> +	struct inode *inode = NULL;
>  	struct pipe_inode_info *pipe;
>  
> +	if (pipe_mnt)
> +		inode = new_inode(pipe_mnt->mnt_sb);
>  	if (!inode)
>  		goto fail_inode;

Well, that fixes the OOPs, but I'd do it a in bit more readable way,
and eliminating the gotos too (this is a stylistic change - I see alot
of gotos in kernel for error returns, but here, in such a small function,
gotos looks somewhat funny, esp. when the only statement after the label
is 'return NULL'):

--- linux-2.6.19/fs/pipe.c.orig	2006-11-30 00:57:37.000000000 +0300
+++ linux-2.6.19/fs/pipe.c	2006-12-03 14:27:06.000000000 +0300
@@ -839,15 +839,20 @@ static struct dentry_operations pipefs_d

 static struct inode * get_pipe_inode(void)
 {
-	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
+	struct inode *inode;
 	struct pipe_inode_info *pipe;

+	if (!pipe_mnt)	/* if pipefs isn't mounted (yet) */
+		return NULL;
+	inode = new_inode(pipe_mnt->mnt_sb);
 	if (!inode)
-		goto fail_inode;
+		return NULL;

 	pipe = alloc_pipe_info(inode);
-	if (!pipe)
-		goto fail_iput;
+	if (!pipe) {
+		iput(inode);
+		return NULL;
+	}
 	inode->i_pipe = pipe;

 	pipe->readers = pipe->writers = 1;
@@ -866,12 +871,6 @@ static struct inode * get_pipe_inode(voi
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

 	return inode;
-
-fail_iput:
-	iput(inode);
-
-fail_inode:
-	return NULL;
 }

 struct file *create_write_pipe(void)


Or like this (without messing up with goto):

--- linux-2.6.19/fs/pipe.c.orig	2006-11-30 00:57:37.000000000 +0300
+++ linux-2.6.19/fs/pipe.c	2006-12-03 14:31:19.000000000 +0300
@@ -839,9 +839,12 @@ static struct dentry_operations pipefs_d

 static struct inode * get_pipe_inode(void)
 {
-	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
+	struct inode *inode;
 	struct pipe_inode_info *pipe;

+	if (!pipe_mnt)	/* in case pipefs isn't mounted (yet) */
+		goto fail_inode;
+	inode = new_inode(pipe_mnt->mnt_sb);
 	if (!inode)
 		goto fail_inode;


In either case, this change not fixes the problem.  As I said, the OOPs is
harmless (yes, not harmful :), so the end effect is the same, just instead
of the OOPs, now the bad stuff is coming from shell complaining about failing
to create pipe.

/mjt

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-12-03 11:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-03  8:43 kernel NULL pointer deref in pipe() - hotplug in initramfs Chuck Ebbert
2006-12-03 11:34 ` Michael Tokarev
  -- strict thread matches above, loose matches on Subject: below --
2006-12-02 23:55 Michael Tokarev
2006-12-03  9:10 ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox