From: Bruno Prémont Subject: nouveau: Prevent NULL dereference On some systems mthd->init may return NULL instead of an ERR_PTR. In that case ->fini would be called and that one may try to dereference its argument without NULL-checking it first. This fixes crash seen on NV1A IPG based system: [ 441.685835] wmi: Mapper loaded [ 442.129083] ACPI: PCI Interrupt Link [LNK5] enabled at IRQ 12 [ 442.135019] PCI: setting IRQ 12 as level-triggered [ 442.144839] nouveau [ DEVICE][0000:02:00.0] BOOT0 : 0x01a000b1 [ 442.151063] nouveau [ DEVICE][0000:02:00.0] Chipset: nForce (NV1A) [ 442.157481] nouveau [ DEVICE][0000:02:00.0] Family : NV10 [ 442.172505] BUG: unable to handle kernel NULL pointer dereference at (null) [ 442.179823] IP: [] pramin_fini+0x6/0x30 [nouveau] [ 442.180015] *pde = 00000000 [ 442.180015] Oops: 0000 [#1] [ 442.180015] Modules linked in: nouveau(+) wmi ttm drm_kms_helper nfsv3 nfs_acl nfs lockd grace sunrpc [ 442.180015] CPU: 0 PID: 1267 Comm: modprobe Not tainted 3.19.0-rc1-jupiter #1 [ 442.180015] Hardware name: NVIDIA Corporation. nFORCE-MCP/MS-6373, BIOS 6.00 PG 04/12/2002 [ 442.180015] task: dc010c90 ti: dcfba000 task.ti: dcfba000 [ 442.180015] EIP: 0060:[] EFLAGS: 00010286 CPU: 0 [ 442.180015] EIP is at pramin_fini+0x6/0x30 [nouveau] [ 442.180015] EAX: 00000000 EBX: 00000000 ECX: 00000000 EDX: dea2c6c0 [ 442.180015] ESI: dcfbb8a4 EDI: deacf670 EBP: dcfbb834 ESP: dcfbb830 [ 442.180015] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 442.180015] CR0: 8005003b CR2: 00000000 CR3: 1c042000 CR4: 000007d0 [ 442.180015] Stack: [ 442.180015] dcedad90 dcfbb860 dea2c02e dcedad90 00000004 deaef771 deaef81b 00000000 [ 442.180015] deaf5320 dcfbb8a4 dcfbb884 dcfbb884 dcfbb994 dea2c2db dcfbb87c c10dbf41 [ 442.180015] ddfcdb40 dd401180 dcedad90 00000000 dcfbb8a4 10000001 deaf54a0 00000000 [ 442.180015] Call Trace: [ 442.180015] [] shadow_method+0x8e/0xe0 [nouveau] [ 442.180015] [] nvbios_shadow+0x25b/0x360 [nouveau] [ 442.180015] [] ? init_object+0x51/0x60 [ 442.180015] [] nouveau_bios_ctor+0x4b/0x3b0 [nouveau] [ 442.180015] [] ? kmem_cache_alloc_trace+0xcf/0x160 [ 442.180015] [] nouveau_object_ctor+0x35/0xd0 [nouveau] [ 442.180015] [] nouveau_devobj_ctor+0x77f/0x880 [nouveau] [ 442.180015] [] nouveau_object_ctor+0x35/0xd0 [nouveau] [ 442.180015] [] nvkm_ioctl_new+0x229/0x300 [nouveau] [ 442.180015] [] nvkm_ioctl+0x2a0/0x340 [nouveau] ... [ 442.180015] Code: 43 7f e2 39 5d f0 89 07 77 e3 eb 08 90 c7 45 ec 00 00 00 00 8b 45 ec 83 c4 08 5b 5e 5f 5d c3 [ 442.180015] EIP: [] pramin_fini+0x6/0x30 [nouveau] SS:ESP 0068:dcfbb830 [ 442.180015] CR2: 0000000000000000 [ 442.555577] ---[ end trace 5944a013025347a6 ]--- See also: https://bugs.freedesktop.org/show_bug.cgi?id=87554 Signed-off-by: Bruno Prémont --- drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c index bb9e001..8a79e4f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c @@ -148,6 +148,8 @@ shadow_method(struct nouveau_bios *bios, struct shadow *mthd, const char *name) if (IS_ERR(mthd->data)) { mthd->data = NULL; return 0; + } else if (!mthd->data) { + return 0; } } mthd->score = shadow_score(bios, mthd);