whilst installing an rpm, I hit this.. BUG: unable to handle kernel NULL pointer dereference at virtual address 0000000e printing eip: c04c26bb *pde = 38fd6067 Oops: 0000 [#1] SMP last sysfs file: /class/net/eth0/address Modules linked in: rfcomm hidp l2cap bluetooth ohci1394 ieee1394 button nfs lockd fscache nfs_acl autofs4 sunrpc ip_conntrack_netbios_ns ipt_REJECT xt_state ip_conntrack nfnetlink iptable_filter ip_tables ip6t_REJECT xt_tcpudp ip6table_filter ip6_tables x_tables cpufreq_ondemand dm_multipath video sbs i2c_ec dock battery asus_acpi ac ipv6 parport_pc lp parport snd_hda_intel snd_hda_codec snd_seq_dummy snd_seq_oss snd_seq_midi_event joydev snd_seq snd_seq_device snd_p cm_oss snd_mixer_oss snd_pcm snd_timer i2c_i801 snd sg i2c_core soundcore pcspkr serio_raw tg3 ide_cd snd_page_alloc cdrom dm_snapshot dm_zero dm_mirror dm_m od ata_piix libata sd_mod scsi_mod ext3 jbd ehci_hcd ohci_hcd uhci_hcd CPU: 0 EIP: 0060:[<c04c26bb>] Not tainted VLI EFLAGS: 00010282 (2.6.18-1.2798.fc6 #1) EIP is at selinux_inode_free_security+0x21/0x59 eax: f7d500f0 ebx: 0000000a ecx: 00000003 edx: 00000000 esi: c076f86c edi: f745a588 ebp: f7fb0f08 esp: f7fb0ed8 ds: 007b es: 007b ss: 0068 Process kswapd0 (pid: 231, ti=f7fb0000 task=f7d500f0 task.ti=f7fb0000) Stack: c076f86c c076f874 0000006d c0485107 c076f86c c04856ec c587bd5c 00000000 00000080 00000080 c0485895 00000080 c076facc c0769b8c 00001e78 f7ffb460 00000080 000000d0 c045b0c3 00000000 f7fb0f88 c0458729 00079e00 00000000 Call Trace: [<c0485107>] destroy_inode+0x22/0x45 [<c04856ec>] dispose_list+0x8e/0xb7 [<c0485895>] shrink_icache_memory+0x180/0x1a8 [<c045b0c3>] shrink_slab+0xd9/0x142 [<c045b471>] kswapd+0x2c9/0x3b6 [<c04369f3>] kthread+0xc0/0xed [<c0404dab>] kernel_thread_helper+0x7/0x10 DWARF2 unwinder stuck at kernel_thread_helper+0x7/0x10 Leftover inexact backtrace: ======================= Code: 5b 5e 5f 5d c3 e9 df 57 00 00 57 56 89 c6 53 8b 98 9c 01 00 00 8b 80 c0 00 00 00 8b b8 84 00 00 00 83 c7 48 89 f8 e8 60 18 15 00 <8b> 4b 04 8d 53 04 39 d1 74 0e 8b 42 04 89 41 04 89 08 89 52 04 EIP: [<c04c26bb>] selinux_inode_free_security+0x21/0x59 SS:ESP 0068:f7fb0ed8
What do you get with gdb on vmlinux and 'l *0xc04c26bb' ? I'm guessing we're still trying to reference an inode in SELinux while it's being destroyed under memory pressure.
NULL deref was in inode_free_security called by destroy_inode to free the inode security struct. If the inode or its security struct was already freed, the real bug happened earlier; this is just the messenger. inode_free_security also dereferences inode->i_sb->s_security, but that should be valid until destroy_super calls selinux_sb_free_security just prior to freeing the superblock itself. As destroy_inode dereferences inode->i_sb itself, that shouldn't be gone yet either.
> What do you get with gdb on vmlinux and 'l *0xc04c26bb' ? 0xc04c26bb is in selinux_inode_free_security (include/linux/list.h:299). 294 * list_empty - tests whether a list is empty 295 * @head: the list to test. 296 */ 297 static inline int list_empty(const struct list_head *head) 298 { 299 return head->next == head; 300 } 301 302 /** 303 * list_empty_careful - tests whether a list is empty and not being modified
Wow, ok now i'm totally lost. isec->list is actually a struct list_head embeded in the inode_security_struct. It is not a pointer to a struct list_head. Thus we see in inode_free_security static void inode_free_security(struct inode *inode) { [SNIP] spin_lock(&sbsec->isec_lock); if (!list_empty(&isec->list)) list_del_init(&isec->list); spin_unlock(&sbsec->isec_lock); [SNIP] } So we are passing &isec->list to list_empty() Since inode_security_struct is deined as: struct inode_security_struct { struct inode *inode; /* back pointer to inode object */ struct list_head list; /* list of inode_security_struct */ u32 task_sid; /* SID of creating task */ [SNIP] }; I was under the impression that &isec->list = isec + sizeof(struct inode *) = isec + 4 But then when we get into list_empty it is saying that we tried to dereference memory at 0000000e. So I have no idea where it got 0000000e. I just don't understand how this can be anything other than hardware or maybe a compiler problem (I haven't looked at the assembly around this area yet) But it certainly looks like the value of struct list_head *head in list_empty is messed up but there doesn't appear to be any way in the code for that to happen....
(In reply to comment #4) > I was under the impression that &isec->list = isec + sizeof(struct inode *) = > isec + 4 Was the hardware x86_64? Also, structs aren't necessarily packed.
Since the backtrace was all 32 bit I assumed i686 not x86_64
ebx = 0000000a ebx+4 = 0000000e Assuming that ebx holds isec there.
Anyway, if that is correct, isec aka inode->i_security is already corrupt on entry to inode_free_security, and this is just the messenger, not the cause of the bug. Seeing the state of the relevant inode would be interesting.
As usual you are correct. Dave, can I assume you do not have a core dump from this? If you do can I get it? Any way you know to reproduce it? From looking at the assembly, the inode is at %esi and it must be corrupted. ebx is actually supposed to be i_security as you thought. edi - 0x48 is the s_security which at least is in kernel memory. I'll troll around tomorrow looking for anything that plays with setting/changing i_security or the inode fields around it, but I doubt I find anything...
I didn't get a coredump, and I only saw it happen once after doing an FC6 install and then a yum update to suck down a hundred or so RPMs. No other boxes that I've done an identical procedure on have hit this. That was on a 32bit core duo laptop btw.
I don't see what I can do here. Haven't seen it since F6. Closing as worksforme