NULL pointer dereference in radeon drm code
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Confirmed
|
High
|
Unassigned |
Bug Description
On one of my systems I use, display connector 0 does not have DDC. This results in the DRM code trying to use radeon_
Known Problem Kernels: uBuntu 12.04 LTS (linux-3.2.55), uBuntu-MATE 14.04 LTS (linux-3.16.7) and uBuntu-MATE 16.04 LTS (linux-4.4.8) and linux-4.6.0 (git:/
/git.kernel.
Trying to use the uBuntu-MATE 16.04 LTS LiveCD ubuntu-
Using a serial console I extracted the following information when trying to boot from a uBuntu-MATE 16.04 LTS LiveCD USB Stick (it had been upgraded from 4.4.0-21-generic in an attempt to get something usable):
<snipped>
[ 0.000000] Linux version 4.4.0-22-generic (buildd@lgw01-41) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2
016 (Ubuntu 4.4.0-22.40-generic 4.4.8)
[ 0.000000] Command line: BOOT_IMAGE=
art,io,
[ 0.000000] KERNEL supported cpus:
[ 0.000000] Intel GenuineIntel
[ 0.000000] AMD AuthenticAMD
[ 0.000000] Centaur CentaurHauls
<snipped>
[ 0.000000] efi: EFI v2.00 by Phoenix Technologies Ltd.
[ 0.000000] efi: EFI v2.00 by Phoenix Technologies Ltd.
[ 0.000000] efi: [ 0.000000] efi: ACPI=0x973c7000 ACPI=0x973c7000 ACPI 2.0=0x973c7014 ACPI 2.0=0x973c7014 SMBIOS=0x9726b000 SMBIOS=0x9726b000
[ 0.000000] SMBIOS 2.6 present.
[ 0.000000] SMBIOS 2.6 present.
[ 0.000000] DMI: AMD Corporation EBrazos Platform/Persimmon, BIOS LV-683 Version: 1.1 02/14/2012
[ 0.000000] DMI: AMD Corporation EBrazos Platform/Persimmon, BIOS LV-683 Version: 1.1 02/14/2012
<snipped>
[ 8.262990] [drm] ib test on ring 5 succeeded
[ 8.288897] [drm] Radeon Display Connectors
[ 8.293175] [drm] Connector 0:
[ 8.296252] [drm] DP-1
[ 8.298791] [drm] Encoders:
[ 8.301770] [drm] DFP1: INTERNAL_UNIPHY
[ 8.305973] [drm] Connector 1:
[ 8.309043] [drm] DP-2
[ 8.311598] [drm] HPD2
[ 8.314169] [drm] DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[ 8.321609] [drm] Encoders:
[ 8.324589] [drm] DFP2: INTERNAL_UNIPHY
[ 8.328793] [drm] Connector 2:
[ 8.331856] [drm] VGA-1
[ 8.332316] scsi 0:0:0:0: Direct-Access SMI USB DISK 1100 PQ: 0 ANSI: 0 CCS
[ 8.342947] [drm] DDC: 0x64d8 0x64d8 0x64dc 0x64dc 0x64e0 0x64e0 0x64e4 0x64e4
[ 8.350341] [drm] Encoders:
[ 8.353310] [drm] CRT1: INTERNAL_
[ 8.358195] BUG: unable to handle kernel NULL pointer dereference at 0000000000000409
[ 8.366104] IP:[ 8.367176] sd 0:0:0:0: Attached scsi generic sg1 type 0
[ 8.368538] sd 0:0:0:0: [sdb] 7831552 512-byte logical blocks: (4.01 GB/3.73 GiB)
[ 8.369421] sd 0:0:0:0: [sdb] Write Protect is off
[ 8.369427] sd 0:0:0:0: [sdb] Mode Sense: 43 00 00 00
[ 8.370288] sd 0:0:0:0: [sdb] No Caching mode page found
[ 8.370292] sd 0:0:0:0: [sdb] Assuming drive cache: write through
[ 8.374944] sdb: sdb1
[ 8.378398] sd 0:0:0:0: [sdb] Attached SCSI removable disk
[ 8.409733] [<ffffffffc0202
[ 8.416805] PGD 0
[ 8.418841] Oops: 0000 [#1] SMP
[ 8.422104] Modules linked in: hid_generic e1000e psmouse amdkfd usbhid uas amd_iommu_v2 ptp radeon(+) pps_core e1000(+) hid i2c_algo_bit ttm drm_kms_helper
usb_storage syscopyarea sysfillrect sysimgblt ahci fb_sys_fops libahci drm video fjes
[ 8.444029] CPU: 0 PID: 131 Comm: systemd-udevd Not tainted 4.4.0-22-generic #40-Ubuntu
[ 8.452036] Hardware name: AMD Corporation EBrazos Platform/Persimmon, BIOS LV-683 Version: 1.1 02/14/2012
[ 8.461708] task: ffff88014780be80 ti: ffff880147888000 task.ti: ffff880147888000
[ 8.469194] RIP: 0010:[<
[ 8.478850] RSP: 0018:ffff880147
[ 8.484179] RAX: 0000000000000000 RBX: ffff88003485f000 RCX: 0000000000000000
[ 8.491321] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff88003485f000
[ 8.498469] RBP: ffff88014788b850 R08: 0000000000000000 R09: ffffffffc004aff6
[ 8.505602] R10: ffffea0000d5e540 R11: 0000000000000000 R12: 0000000000000001
[ 8.506137] e1000 0000:05:0b.0 eth1: (PCI:33MHz:32-bit) 00:03:1d:09:3b:61
[ 8.506142] e1000 0000:05:0b.0 eth1: Intel(R) PRO/1000 Network Connection
[ 8.526299] R13: ffff8800351f4080 R14: ffff880035120000 R15: ffff8801478e7000
[ 8.533441] FS: 00007f4ed97678c
[ 8.541525] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 8.547263] CR2: 0000000000000409 CR3: 0000000149f2d000 CR4: 00000000000006f0
[ 8.554396] Stack:
[ 8.556412] ffff88014788b888 ffffffffc01c27a6 ffff88003485f050 ffff88003485f000
[ 8.563867] 0000000000000003 ffff88003574e000 0000000000000001 ffff88014788b8e8
[ 8.571329] ffffffffc00ccd95 ffff88014788b920 ffffffffc01a9319 ffff8801478e6200
[ 8.578789] Call Trace:
[ 8.581289] [<ffffffffc01c2
[ 8.587918] [<ffffffffc00cc
[ 8.598217] [<ffffffffc01a9
[ 8.605356] [<ffffffffc00cd
[ 8.614508] [<ffffffffc00d9
[ 8.622816] [<ffffffffc01cd
[ 8.629471] [<ffffffffc01c7
[ 8.636391] [<ffffffffc019f
[ 8.643565] [<ffffffffc0035
[ 8.649765] [<ffffffffc0037
[ 8.655985] [<ffffffffc019b
[ 8.662438] [<ffffffff81439
[ 8.668006] [<ffffffff8143b
[ 8.673841] [<ffffffff8154c
[ 8.679939] [<ffffffff8154c
[ 8.685519] [<ffffffff8154c
[ 8.691787] [<ffffffff8154a
[ 8.697445] [<ffffffff8154b
[ 8.702845] [<ffffffff8154b
[ 8.708504] [<ffffffff8154d
[ 8.714077] [<ffffffff81439
[ 8.720191] [<ffffffffc0037
[ 8.726104] [<ffffffffc030d
[ 8.731288] [<ffffffffc030d
[ 8.737297] [<ffffffff81002
[ 8.742955] [<ffffffff811ce
[ 8.748093] [<ffffffff811ea
[ 8.754622] [<ffffffff8118c
[ 8.760193] [<ffffffff81109
[ 8.765764] [<ffffffff81106
[ 8.771252] [<ffffffff81212
[ 8.776651] [<ffffffff8110a
[ 8.782395] [<ffffffff8110a
[ 8.787970] [<ffffffff81825
[ 8.794404] Code: 41 5d 41 5e 41 5f 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 8b 87 a0 03 00 00 45 31 c0 31 d2 be 01 00 00 00 48 89 e5 <0f> b6 8
8 09 04 00 00 48 8b 07 48 8b 78 28 e8 23 f6 ff ff 5d c3
[ 8.814354] RIP [<ffffffffc0202
[ 8.821645] RSP <ffff88014788b850>
[ 8.825135] CR2: 0000000000000409
[ 8.828551] ---[ end trace 9fce5ace7679b4a0 ]---
Looking at the code, there are a number of places that assume that radeon_
The following workaround fixes the issue by ensuring that ddc_bus is always validated before use:
diff -rupd linux-source-
--- linux-source-
+++ linux-source-
@@ -232,6 +232,9 @@ void radeon_
struct radeon_device *rdev = dev->dev_private;
int ret;
+ if (!radeon_
+ return;
+
if (ASIC_IS_
@@ -352,6 +355,9 @@ u8 radeon_
struct drm_device *dev = radeon_
struct radeon_device *rdev = dev->dev_private;
+ if (!radeon_
+ return 0;
+
return radeon_
}
@@ -364,6 +370,9 @@ static void radeon_
if (!(dig_
+ if (!radeon_
+ return;
+
if (drm_dp_
@@ -379,6 +388,9 @@ bool radeon_
u8 msg[DP_DPCD_SIZE];
int ret, i;
+ if (!radeon_
+ return false;
+
for (i = 0; i < 7; i++) {
ret = drm_dp_
@@ -416,24 +428,26 @@ int radeon_
- if (dp_bridge != ENCODER_
- /* DP bridge chips */
- if (drm_dp_
- DP_EDP_
- if (tmp & 1)
- panel_mode = DP_PANEL_
- else if ((dp_bridge == ENCODER_
- (dp_bridge == ENCODER_
- panel_mode = DP_PANEL_
- else
- panel_mode = DP_PANEL_
- }
- } else if (connector-
- /* eDP */
- if (drm_dp_
- DP_EDP_
- if (tmp & 1)
- panel_mode = DP_PANEL_
+ if (radeon_
+ if (dp_bridge != ENCODER_
+ /* DP bridge chips */
+ if (drm_dp_
+ DP_EDP_
+ if (tmp & 1)
+ panel_mode = DP_PANEL_
+ else if ((dp_bridge == ENCODER_
+ (dp_bridge == ENCODER_
+ panel_mode = DP_PANEL_
+ else
+ panel_mode = DP_PANEL_
+ }
+ } else if (connector-
+ /* eDP */
+ if (drm_dp_
+ DP_EDP_
+ if (tmp & 1)
+ panel_mode = DP_PANEL_
+ }
}
}
@@ -499,6 +513,9 @@ bool radeon_
u8 link_status[
struct radeon_
+ if (!radeon_
+ return false;
+
if (drm_dp_
<= 0)
@@ -519,7 +536,7 @@ void radeon_
/* power up/down the sink */
- if (dig_connector-
+ if (radeon_
@@ -822,7 +839,8 @@ void radeon_
else
- if (drm_dp_
+ if (radeon_
+ drm_dp_
== 1) {
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
@@ -838,7 +856,7 @@ void radeon_
- dp_info.aux = &radeon_
+ dp_info.aux = radeon_
if (radeon_
diff -rupd linux-source-
--- linux-source-
+++ linux-source-
@@ -327,26 +327,27 @@ static void radeon_
if (radeon_
- if ((radeon_
- ENCODER_
- radeon_
- radeon_
- &radeon_
- } else if ((connector-
- (connector-
- struct radeon_
-
- if ((dig->dp_sink_type == CONNECTOR_
- dig->dp_sink_type == CONNECTOR_
- radeon_
- radeon_
+ if (radeon_
+ if ((radeon_
+ ENCODER_
+ radeon_
+ radeon_
- else if (radeon_
+ } else if ((connector-
+ (connector-
+ struct radeon_
+
+ if ((dig->dp_sink_type == CONNECTOR_
+ dig->dp_sink_type == CONNECTOR_
+ radeon_
+ radeon_
+ &radeon_
+ else
+ radeon_
+ &radeon_
+ } else
- } else if (radeon_
- radeon_
- &radeon_
}
if (!radeon_
@@ -1306,6 +1307,7 @@ radeon_
+ radeon_
diff -rupd linux-source-
--- linux-source-
+++ linux-source-
@@ -662,7 +662,7 @@ radeon_
{
struct drm_device *dev = radeon_
- if (!radeon_
+ if (!radeon_
@@ -689,6 +689,9 @@ radeon_
if (dig_connector-
+ if (!radeon_
+ return 0;
+
ret = drm_dp_
if (ret) {
@@ -718,6 +721,9 @@ radeon_
int ret = 0;
+ if (!radeon_
+ return -EINVAL;
+
go_again:
diff -rupd linux-source-
--- linux-source-
+++ linux-source-
@@ -63,6 +63,9 @@ bool radeon_
if (radeon_
+ if (!radeon_
+ return false;
+
if (use_aux) {
ret = i2c_transfer(
} else {
I think the changes to these four files should be pushed back to the main line kernel and it is probably also desirable to back port these changes to earlier kernels.
---
ApportVersion: 2.20.1-0ubuntu2.1
Architecture: amd64
AudioDevicesInUse: Error: command ['fuser', '-v', '/dev/snd/seq', '/dev/snd/timer'] failed with exit code 1:
CasperVersion: 1.376
CurrentDesktop: MATE
DistroRelease: Ubuntu 16.04
LiveMediaBuild: Ubuntu-MATE 16.04 LTS "Xenial Xerus" - Release amd64 (20160420.1)
MachineType: AMD Corporation EBrazos Platform
Package: linux (not installed)
ProcEnviron:
TERM=xterm
PATH=(custom, no user)
XDG_RUNTIME_
LANG=en_GB.UTF-8
SHELL=/bin/bash
ProcFB: 0 radeondrmfb
ProcKernelCmdLine: BOOT_IMAGE=
ProcVersionSign
RelatedPackageV
linux-
linux-
linux-firmware 1.157
RfKill:
Tags: xenial
Uname: Linux 4.4.0-22-generic x86_64
UpgradeStatus: No upgrade log present (probably fresh install)
UserGroups: adm cdrom dip lpadmin plugdev sambashare sudo
_MarkForUpload: True
dmi.bios.date: 02/14/2012
dmi.bios.vendor: Phoenix Technologies Ltd.
dmi.bios.version: LV-683 Version: 1.1
dmi.board.
dmi.board.name: Persimmon
dmi.board.vendor: AMD Corp.
dmi.board.version: A11
dmi.chassis.
dmi.chassis.type: 9
dmi.chassis.vendor: AMD Corporation
dmi.chassis.
dmi.modalias: dmi:bvnPhoenixT
dmi.product.name: EBrazos Platform
dmi.product.
dmi.sys.vendor: AMD Corporation
tags: | added: patch |
Changed in linux (Ubuntu): | |
importance: | Undecided → High |
tags: | added: precise trusty |
tags: | removed: precise trusty |
The patch in raw form so it can be used directly.