public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* NULL pointer dereference in inode_has_perm() while setquota
@ 2011-06-01  8:35 Lukas Czerner
  2011-06-08 20:40 ` Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Lukas Czerner @ 2011-06-01  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eric Paris, linux-security-module

Hi,

I was running xfstests on ext4 filesystem and I have run into NULL
pointer dereference in inode_has_perm() while running test no. 234. This
is on kernel 3.0.0-rc1.

 BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
 IP: [<ffffffff811ed05c>] inode_has_perm+0x3c/0xa0
 PGD 0
 Oops: 0000 [#1] SMP
 CPU 20
 Modules linked in: ext4 jbd2 autofs4 sunrpc ipv6 dm_mirror dm_region_hash dm_log dm_mod dcdbas microcode serio_raw pcspkr ghes hed iTCO_wdt iTCO_vendor_support i7core_edac edac_core ses enclosure sg bnx2 ext3 jbd mbcache sr_mod cdrom sd_mod crc_t10dif pata_acpi ata_generic ata_piix megaraid_sas [last unloaded: speedstep_lib]

 Pid: 18062, comm: setquota Not tainted 3.0.0-rc1+ #1 Dell Inc. PowerEdge R710/0MD99X
 RIP: 0010:[<ffffffff811ed05c>]  [<ffffffff811ed05c>] inode_has_perm+0x3c/0xa0
 RSP: 0018:ffff8801a9d13af8  EFLAGS: 00010282
 RAX: ffff8801a9d13b98 RBX: 0000000000000000 RCX: ffff88031c1c86a0
 RDX: 0000000000800000 RSI: ffff88012ee99d58 RDI: ffff880259898c80
 RBP: ffff8801a9d13b88 R08: 0000000000000001 R09: ffff88012ee99d58
 R10: 0000000000000678 R11: 0000000000000000 R12: ffff8801a9d13dd8
 R13: ffff88012ee99d58 R14: ffff88013829eb00 R15: 0000000000000000
 FS:  00007f5ff34c3700(0000) GS:ffff88032fd40000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 0000000000000020 CR3: 00000002e6a0b000 CR4: 00000000000006e0
 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
 Process setquota (pid: 18062, threadinfo ffff8801a9d12000, task ffff88013829eb00)
 Stack:
 ffff88032ffd7e00 0000000000000030 ffffea00066bb5b0 0000000000000000
 ffff8801a9d13c08 ffffffff81108a0a ffffffff00000000 ffff88013829f370
 00000002a9d13bb8 ffff8801a9d13fd8 000000002ffd7e00 ffff88032ffd7e60
 Call Trace:
 [<ffffffff81108a0a>] ? get_page_from_freelist+0x25a/0x570
 [<ffffffff811ed421>] selinux_inode_permission+0xd1/0x130
 [<ffffffff811ea593>] security_inode_exec_permission+0x23/0x30
 [<ffffffff8116b654>] link_path_walk+0xc4/0x920
 [<ffffffff8116c515>] path_lookupat+0x55/0x680
 [<ffffffff8116cb71>] do_path_lookup+0x31/0xc0
 [<ffffffff81168fd8>] ? getname_flags+0x1f8/0x280
 [<ffffffff8116d839>] user_path_at+0x59/0xa0
 [<ffffffff81128ae5>] ? handle_mm_fault+0x1d5/0x350
 [<ffffffff814d7948>] ? do_page_fault+0x1e8/0x470
 [<ffffffff811495c5>] ? kmem_cache_alloc+0x155/0x190
 [<ffffffff8116270c>] vfs_fstatat+0x4c/0x90
 [<ffffffff81074a51>] ? do_sigaction+0x91/0x1d0
 [<ffffffff8116282b>] vfs_stat+0x1b/0x20
 [<ffffffff81162854>] sys_newstat+0x24/0x50
 [<ffffffff810c1c1f>] ? audit_syscall_entry+0x1bf/0x1f0
 [<ffffffff814dc0c2>] system_call_fastpath+0x16/0x1b
 Code: 89 c8 65 48 8b 0c 25 28 00 00 00 48 89 4d f8 31 c9 f6 46 25 02 75 6f 48 8b 4f 68 48 85 c0 4c 8b 9e 30 02 00 00 44 8b 51 04 74 34
 RIP  [<ffffffff811ed05c>] inode_has_perm+0x3c/0xa0
 RSP <ffff8801a9d13af8>
 CR2: 0000000000000020
 ---[ end trace 26cf9362f1661921 ]---

Disassembly on inode_has_perm() did not help me very much, but here it
is for convenience.

Dump of assembler code for function inode_has_perm:
   0xffffffff811ed020 <+0>:     push   %rbp
   0xffffffff811ed021 <+1>:     mov    %rsp,%rbp
   0xffffffff811ed024 <+4>:     sub    $0x90,%rsp
   0xffffffff811ed02b <+11>:    callq  0xffffffff814dbe00
   0xffffffff811ed030 <+16>:    mov    %rcx,%rax
   0xffffffff811ed033 <+19>:    mov    %gs:0x28,%rcx
   0xffffffff811ed03c <+28>:    mov    %rcx,-0x8(%rbp)
   0xffffffff811ed040 <+32>:    xor    %ecx,%ecx
   0xffffffff811ed042 <+34>:    testb  $0x2,0x25(%rsi)
   0xffffffff811ed046 <+38>:    jne    0xffffffff811ed0b7 <inode_has_perm+151>
   0xffffffff811ed048 <+40>:    mov    0x68(%rdi),%rcx
   0xffffffff811ed04c <+44>:    test   %rax,%rax
   0xffffffff811ed04f <+47>:    mov    0x230(%rsi),%r11
   0xffffffff811ed056 <+54>:    mov    0x4(%rcx),%r10d
   0xffffffff811ed05a <+58>:    je     0xffffffff811ed090 <inode_has_perm+112>
   0xffffffff811ed05c <+60>:    movzwl 0x20(%r11),%edi
   0xffffffff811ed061 <+65>:    mov    0x1c(%r11),%esi
   0xffffffff811ed065 <+69>:    mov    %r8d,%r9d
   0xffffffff811ed068 <+72>:    mov    %edx,%ecx
   0xffffffff811ed06a <+74>:    mov    %rax,%r8
   0xffffffff811ed06d <+77>:    mov    %edi,%edx
   0xffffffff811ed06f <+79>:    mov    %r10d,%edi
   0xffffffff811ed072 <+82>:    callq  0xffffffff811ec760 <avc_has_perm_flags>
   0xffffffff811ed077 <+87>:    mov    -0x8(%rbp),%rdx
   0xffffffff811ed07b <+91>:    xor    %gs:0x28,%rdx
   0xffffffff811ed084 <+100>:   jne    0xffffffff811ed0b2 <inode_has_perm+146>
   0xffffffff811ed086 <+102>:   leaveq
   0xffffffff811ed087 <+103>:   retq
   0xffffffff811ed088 <+104>:   nopl   0x0(%rax,%rax,1)
   0xffffffff811ed090 <+112>:   lea    -0x90(%rbp),%r9
   0xffffffff811ed097 <+119>:   mov    $0x11,%ecx
   0xffffffff811ed09c <+124>:   mov    %r9,%rdi
   0xffffffff811ed09f <+127>:   rep stos %rax,%es:(%rdi)
   0xffffffff811ed0a2 <+130>:   movb   $0x9,-0x90(%rbp)
   0xffffffff811ed0a9 <+137>:   mov    %rsi,-0x80(%rbp)
   0xffffffff811ed0ad <+141>:   mov    %r9,%rax
   0xffffffff811ed0b0 <+144>:   jmp    0xffffffff811ed05c <inode_has_perm+60>
   0xffffffff811ed0b2 <+146>:   callq  0xffffffff810628e0 <__stack_chk_fail>
   0xffffffff811ed0b7 <+151>:   xor    %eax,%eax
   0xffffffff811ed0b9 <+153>:   jmp    0xffffffff811ed077 <inode_has_perm+87>
End of assembler dump.


from the hooks.lst:


static int inode_has_perm(const struct cred *cred,
                          struct inode *inode,
                          u32 perms,
                          struct common_audit_data *adp,
                          unsigned flags)
{

----snip----

        sid = cred_sid(cred);
        isec = inode->i_security;

        if (!adp) {
ffffffff811ed05a:       74 34                   je     ffffffff811ed090 <inode_has_perm+0x70>
                adp = &ad;
                COMMON_AUDIT_DATA_INIT(&ad, INODE);
                ad.u.inode = inode;
        }

        return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
ffffffff811ed05c:       41 0f b7 7b 20          movzwl 0x20(%r11),%edi
ffffffff811ed061:       41 8b 73 1c             mov    0x1c(%r11),%esi
ffffffff811ed065:       45 89 c1                mov    %r8d,%r9d
ffffffff811ed068:       89 d1                   mov    %edx,%ecx
ffffffff811ed06a:       49 89 c0                mov    %rax,%r8
ffffffff811ed06d:       89 fa                   mov    %edi,%edx
ffffffff811ed06f:       44 89 d7                mov    %r10d,%edi
ffffffff811ed072:       e8 00 00 00 00          callq  ffffffff811ed077 <inode_has_perm+0x57>
                        ffffffff811ed073: R_X86_64_PC32 avc_has_perm_flags-0x4
}

It looks like the problem is while calling avc_has_perm_flags(), more
specifically while dereferencing isec to pass the arguments. So it looks
like the inode->i_security is null for some reason. I do not understand
the code good enough to tell where the actual problem lies, but if you
need more info, just let me know.

Thanks!
-Lukas

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

* Re: NULL pointer dereference in inode_has_perm() while setquota
  2011-06-01  8:35 NULL pointer dereference in inode_has_perm() while setquota Lukas Czerner
@ 2011-06-08 20:40 ` Andrew Morton
  2011-06-09  6:15   ` Lukas Czerner
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2011-06-08 20:40 UTC (permalink / raw)
  To: Lukas Czerner; +Cc: linux-kernel, Eric Paris, linux-security-module

On Wed, 1 Jun 2011 10:35:51 +0200 (CEST)
Lukas Czerner <lczerner@redhat.com> wrote:

> I was running xfstests on ext4 filesystem and I have run into NULL
> pointer dereference in inode_has_perm() while running test no. 234. This
> is on kernel 3.0.0-rc1.

Is this a regression?  Was 2.6.39 OK?

Thanks.

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

* Re: NULL pointer dereference in inode_has_perm() while setquota
  2011-06-08 20:40 ` Andrew Morton
@ 2011-06-09  6:15   ` Lukas Czerner
  2011-06-09  7:47     ` Lukas Czerner
  0 siblings, 1 reply; 5+ messages in thread
From: Lukas Czerner @ 2011-06-09  6:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Lukas Czerner, linux-kernel, Eric Paris, linux-security-module

On Wed, 8 Jun 2011, Andrew Morton wrote:

> On Wed, 1 Jun 2011 10:35:51 +0200 (CEST)
> Lukas Czerner <lczerner@redhat.com> wrote:
> 
> > I was running xfstests on ext4 filesystem and I have run into NULL
> > pointer dereference in inode_has_perm() while running test no. 234. This
> > is on kernel 3.0.0-rc1.
> 
> Is this a regression?  Was 2.6.39 OK?
> 
> Thanks.
> 

I suppose, since I have never seen that bug before, however I am going
to retest.

Thanks!
-Lukas

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

* Re: NULL pointer dereference in inode_has_perm() while setquota
  2011-06-09  6:15   ` Lukas Czerner
@ 2011-06-09  7:47     ` Lukas Czerner
  2011-09-26  8:05       ` Paul Bolle
  0 siblings, 1 reply; 5+ messages in thread
From: Lukas Czerner @ 2011-06-09  7:47 UTC (permalink / raw)
  To: Lukas Czerner
  Cc: Andrew Morton, linux-kernel, Eric Paris, linux-security-module

On Thu, 9 Jun 2011, Lukas Czerner wrote:

> On Wed, 8 Jun 2011, Andrew Morton wrote:
> 
> > On Wed, 1 Jun 2011 10:35:51 +0200 (CEST)
> > Lukas Czerner <lczerner@redhat.com> wrote:
> > 
> > > I was running xfstests on ext4 filesystem and I have run into NULL
> > > pointer dereference in inode_has_perm() while running test no. 234. This
> > > is on kernel 3.0.0-rc1.
> > 
> > Is this a regression?  Was 2.6.39 OK?
> > 
> > Thanks.
> > 
> 
> I suppose, since I have never seen that bug before, however I am going
> to retest.
> 
> Thanks!
> -Lukas
> 

I am not able to reproduce it on 3.0.0-rc2, so I guess it got fixed
already.

-Lukas

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

* Re: NULL pointer dereference in inode_has_perm() while setquota
  2011-06-09  7:47     ` Lukas Czerner
@ 2011-09-26  8:05       ` Paul Bolle
  0 siblings, 0 replies; 5+ messages in thread
From: Paul Bolle @ 2011-09-26  8:05 UTC (permalink / raw)
  To: Lukas Czerner
  Cc: Andrew Morton, linux-kernel, Eric Paris, linux-security-module

On Thu, 2011-06-09 at 09:47 +0200, Lukas Czerner wrote:
> I am not able to reproduce it on 3.0.0-rc2, so I guess it got fixed
> already.

0) This might not be correct, as I just ran into something very similar
on v3.0.4 (this is copied by hand from a manual screenshot, so there's a
chance of typo's):

[23760.116272] CPU 1 
[23760.116286] Modules linked in: tcp_lp fuse vfat fat usb_storage uas nf_conntrack_ipv4 nf_defrag_ipv4 ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables binfmt_misc kvm_intel kvm uinput snd_hda_codec_analog arc4 snd_hda_intel snd_hda_codec snd_hwdep iwl4965 snd_seq iwl_legacy snd_seq_device btusb snd_pcm e1000e mac80211 bluetooth cfg80211 iTCO_wdt snd_timer i2c_i801 iTCO_vendor_support snd_page_alloc thinkpad_acpi rfkill snd microcode soundcore pcspkr sdhci_pci yenta_socket sdhci firewire_ohci firewire_core mmc_core crc_itu_t i915 drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: scsi_wait_scan]
[23760.116761] 
[23760.116773] Pid: 861, comm: irqbalance Not tainted 3.0.4-local0.fc14.x86_64 #1 LENOVO 76735GG/76735GG
[23760.116830] RIP: 0010:[<ffffffff81206de5>]  [<ffffffff81206de5>] inode_has_perm+0x5a/0x7a
[23760.116871] RSP: 0018:ffff880133767bb8  EFLAGS: 00010246
[23760.116900] RAX: 0000000000000000 RBX: ffff88013327a900 RCX: 0000000000800000
[23760.116933] RDX: ffff880105a88006 RSI: ffff880131ed9a08 RDI: ffff88013327a900
[23760.116966] RBP: ffff880133767be8 R08: ffff880133767c08 R09: 0000000000000001
[23760.116998] R10: 00000000000000f6 R11: 0000000000800000 R12: ffff880131ed9a08
[23760.117008] R13: ffff880133767c08 R14: 0000000000800000 R15: 0000000000000001
[23760.117008] FS:  00007fa86f36f740(0000) GS:ffff88013bc00000(0000) knlGS:0000000000000000
[23760.117008] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[23760.117008] CR2: 0000000000000020 CR3: 00000001320d3000 CR4: 00000000000006e0
[23760.117008] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[23760.117008] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[23760.117008] Process irqbalance (pid: 861, threadinfo ffff880133766000, task ffff88013357a3d0)
[23760.117008] Stack:
[23760.117008]  ffffffff81154252 ffff880131ed9a08 ffff88013327a900 0000000000000000
[23760.117008]  ffff88013357a3d0 0000000000000000 ffff880133767ca8 ffffffff81207302
[23760.117008]  ffff880100000000 ffffffff00000001 0000000000000009 0000000000000000
[23760.117008] Call Trace:
[23760.117008]  [<ffffffff81154252>] ? dentry_cmp+0x21/0x31
[23760.117008]  [<ffffffff81207302>] selinux_inode_permission+0x9c/0xbc
[23760.117008]  [<ffffffff81201727>] security_inode_exec_permission+0x25/0x27
[23760.117008]  [<ffffffff8114c3db>] exec_permission+0x81/0x8f
[23760.117008]  [<ffffffff8114ec89>] link_path_walk+0x71/0x477
[23760.117008]  [<ffffffff8114cec4>] ? handle_dots+0x218/0x218
[23760.117008]  [<ffffffff8114d619>] ? path_init+0x11c/0x2fc
[23760.117008]  [<ffffffff8114fa71>] path_openat+0xae/0x35b
[23760.117008]  [<ffffffff8114fd5b>] do_filp_open+0x3d/0x89
[23760.117008]  [<ffffffff814ef7df>] ? _raw_spin_unlock+0x2b/0x2f
[23760.117008]  [<ffffffff8115aa28>] ? alloc_fd+0x181/0x193
[23760.117008]  [<ffffffff811427bc>] do_sys_open+0x74/0x106
[23760.117008]  [<ffffffff811162d7>] ? remove_vma+0x7f/0x87
[23760.117008]  [<ffffffff8114286e>] sys_open+0x20/0x22
[23760.117008]  [<ffffffff814f62c2>] system_call_fastpath+0x16/0x1b
[23760.117008] Code: c9 05 00 00 48 c7 c6 98 68 7e 81 48 89 df e8 51 97 e7 ff 31 c0 41 f6 44 24 69 02 75 21 49 8b 44 24 78 45 89 f9 4d 89 e8 44 89 f1 <0f> b7 50 20 8b 70 1c 48 8b 43 78 8b 78 04 e8 aa ca ff ff 41 58
[23760.117008] RIP  [<ffffffff81206de5>] inode_has_perm+0x5a/0x7a
[23760.117008]  RSP <ffff880133767bb8>
[23760.117008] CR2: 0000000000000020

1) Poking with gdb into vmlinux gives:

(gdb) info line 1489
Line 1489 of "security/selinux/hooks.c" starts at address 0xffffffff81206ddc <inode_has_perm+81>
   and ends at 0xffffffff81206dec <inode_has_perm+97>.
(gdb) disass /m inode_has_perm+81,+16
Dump of assembler code from 0xffffffff81206ddc to 0xffffffff81206dec:
1489		return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
   0xffffffff81206ddc <inode_has_perm+81>:	mov    %r15d,%r9d
   0xffffffff81206ddf <inode_has_perm+84>:	mov    %r13,%r8
   0xffffffff81206de2 <inode_has_perm+87>:	mov    %r14d,%ecx
   0xffffffff81206de5 <inode_has_perm+90>:	movzwl 0x20(%rax),%edx
   0xffffffff81206de9 <inode_has_perm+94>:	mov    0x1c(%rax),%esi

End of assembler dump.
(gdb) disass /r inode_has_perm+81,+16
Dump of assembler code from 0xffffffff81206ddc to 0xffffffff81206dec:
   0xffffffff81206ddc <inode_has_perm+81>:	 45 89 f9	mov    %r15d,%r9d
   0xffffffff81206ddf <inode_has_perm+84>:	 4d 89 e8	mov    %r13,%r8
   0xffffffff81206de2 <inode_has_perm+87>:	 44 89 f1	mov    %r14d,%ecx
   0xffffffff81206de5 <inode_has_perm+90>:	 0f b7 50 20	movzwl 0x20(%rax),%edx
   0xffffffff81206de9 <inode_has_perm+94>:	 8b 70 1c	mov    0x1c(%rax),%esi
End of assembler dump.

(Note that gdb prints addresses in hexadecimal and offsets in decimal,
while the kernel prints both in hexadecimal. This means one has to do
some dec/hex translations to match their output.)

2) So the problematic instruction is "movzwl 0x20(%rax),%edx". I know
next to nothing about x86_64 assembler, but it seems this corresponds to
looking up isec->sclass for the avc_has_perm_flags() call, as the offset
of sclass in struct inode_security_struct should be 0x20. Apparently
isec (ie, inode->i_security) was NULL. This echoes Lukas' analysis.

3) I have no idea what triggered this. Nor do I know under what
circumstances inode->i_security can be NULL.


Paul Bolle


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

end of thread, other threads:[~2011-09-26  8:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-01  8:35 NULL pointer dereference in inode_has_perm() while setquota Lukas Czerner
2011-06-08 20:40 ` Andrew Morton
2011-06-09  6:15   ` Lukas Czerner
2011-06-09  7:47     ` Lukas Czerner
2011-09-26  8:05       ` Paul Bolle

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