Bug 198481

Summary: UBSAN: Undefined behaviour in drivers/acpi/sysfs.c:849:33
Product: ACPI Reporter: Paul Menzel (pmenzel+bugzilla.kernel.org)
Component: Config-InterruptsAssignee: Zhang Rui (rui.zhang)
Status: RESOLVED CODE_FIX    
Severity: normal CC: rui.zhang
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.15-rc8 Subsystem:
Regression: No Bisected commit-id:
Attachments: Linux kernel configuration
ACPI: use bitmap helper for masked GPEs

Description Paul Menzel 2018-01-15 12:01:27 UTC
Created attachment 273617 [details]
Linux kernel configuration

Enabling the undefined behavior sanitizer, and building Linus’ master branch (4.15-rc3) under Ubuntu 17.10 with gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0 shows a problem in the code.

```
$ grep UBSAN /boot/config-4.15.0-rc3+
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set
CONFIG_UBSAN=y
CONFIG_UBSAN_SANITIZE_ALL=y
# CONFIG_UBSAN_ALIGNMENT is not set
CONFIG_UBSAN_NULL=y
```

Starting the system the messages below are printed.

```
[    0.758899] ================================================================================
[    0.758960] UBSAN: Undefined behaviour in drivers/acpi/sysfs.c:849:33
[    0.759008] shift exponent 64 is too large for 64-bit type 'long long unsigned int'
[    0.759064] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc3+ #12
[    0.759076] Hardware name: Notebook N24_25BU/N24_25BU, BIOS 5.12 07/07/2017
[    0.759088] Call Trace:
[    0.759118]  ? ftrace_graph_caller+0x98/0x98
[    0.759133]  dump_stack+0x70/0xae
[    0.759167]  ubsan_epilogue+0x9/0x40
[    0.759188]  __ubsan_handle_shift_out_of_bounds+0x12b/0x170
[    0.759214]  ? ftrace_graph_caller+0x68/0x98
[    0.759293]  ? acpi_gpe_apply_masked_gpes+0x50/0xa9
[    0.759314]  acpi_gpe_apply_masked_gpes+0x50/0xa9
[    0.759348]  ? ftrace_graph_caller+0x98/0x98
[    0.759363]  acpi_scan_init+0x145/0x2e4
[    0.759385]  ? acpi_sleep_proc_init+0x24/0x24
[    0.759413]  ? acpi_sleep_proc_init+0x24/0x24
[    0.759429]  ? ftrace_graph_caller+0x98/0x98
[    0.759444]  acpi_init+0x340/0x3a0
[    0.759500]  ? ftrace_graph_caller+0x98/0x98
[    0.759515]  do_one_initcall+0x173/0x200
[    0.759553]  ? acpi_sleep_proc_init+0x24/0x24
[    0.759573]  ? do_one_initcall+0x5/0x200
[    0.759612]  ? ftrace_graph_caller+0x98/0x98
[    0.759628]  kernel_init_freeable+0x305/0x395
[    0.759653]  ? rest_init+0xd0/0xd0
[    0.759689]  kernel_init+0xb/0x119
[    0.759705]  ? rest_init+0xd0/0xd0
[    0.759721]  ret_from_fork+0x1f/0x30
[    0.759815] ================================================================================
```

I also reproduced it with Linux 4.15-rc7.
Comment 1 Zhang Rui 2018-01-23 07:09:23 UTC
Created attachment 273803 [details]
ACPI: use bitmap helper for masked GPEs

Good catch.
I can reproduce this on my local machine as well, and the patch attached fixes the problem.
Comment 2 Paul Menzel 2018-01-23 07:24:48 UTC
Comment on attachment 273803 [details]
ACPI: use bitmap helper for masked GPEs

Dear Zhang, thank you for the quick fix. Some nitpicks.


>From c34c7cc98a43beb5405cff677fa1525f20add88e Mon Sep 17 00:00:00 2001
>From: Zhang Rui <rui.zhang@intel.com>
>Date: Tue, 23 Jan 2018 10:07:43 +0800
>Subject: [PATCH] ACPI: use bitmap helper for masked GPEs
>
>"acpi_mask_gpe=" kernel parameter is introduced to mask one or more GPEs
>at boot stage, to prevent GPE flooding.
>
>currently, a maximum of 128 GPEs (from GPE 0x00 to GPE 0x7f) are allowed

*C*urrently

>to be masked by this kernel parameter, but only one u64 variant is used
>as the bitmap for the masked GPEs in kernel.
>
>This is bogus and make some GPEs masked unexpected when masking a GPE

make*s*

>larger than 0x40.
>For example, with CONFIG_UBSAN=y, when "acpi_mask_gpe=0x6f" is parsed,
>we got

One blank line? I’d also use present tense: s/got/get/

>[    0.039669] ACPI: Masking GPE 0x2f.
>[    0.039681]
>================================================================================
>[    0.039684] UBSAN: Undefined behaviour in drivers/acpi/sysfs.c:846:33
>[    0.039688] shift exponent 64 is too large for 64-bit type 'long long
>unsigned int'
>[    0.039692] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.0-UBSAN-check+
>#37
>[    0.039695] Hardware name: Microsoft Corporation Surface Pro 4/Surface Pro
>4, BIOS 106.1281.768 08/01/2016
>[    0.039698] Call Trace:
>[    0.039704]  dump_stack+0x64/0x91
>[    0.039709]  ubsan_epilogue+0xd/0x40
>[    0.039712]  __ubsan_handle_shift_out_of_bounds+0xf6/0x140
>[    0.039716]  ? do_syscall_64+0x1e6/0x760
>[    0.039720]  ? acpi_ev_mask_gpe+0x141/0x14c
>[    0.039724]  acpi_gpe_apply_masked_gpes+0x41/0x8a
>[    0.039727]  ? acpi_gpe_apply_masked_gpes+0x41/0x8a
>[    0.039731]  acpi_scan_init+0x14d/0x2df
>[    0.039734]  acpi_init+0x32d/0x379
>[    0.039737]  ? acpi_sleep_proc_init+0x2a/0x2a
>[    0.039740]  do_one_initcall+0x116/0x1d0
>[    0.039743]  kernel_init_freeable+0x304/0x39a
>[    0.039746]  ? rest_init+0xf0/0xf0
>[    0.039749]  kernel_init+0xf/0x120
>[    0.039752]  ? rest_init+0xf0/0xf0
>[    0.039756]  ret_from_fork+0x25/0x30
>[    0.039758]
>================================================================================
>[    0.039762] ACPI: Masking GPE 0x6f.
>
>Fix this by using the bitmap helper, for declaring, testing and setting
>the bitmap.
>
>Link: https://bugzilla.kernel.org/show_bug.cgi?id=198481
>Reported-by: Paul Menzel <pmenzel+bugzilla.kernel.org@molgen.mpg.de>
>Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Please mark it for stable too.

>---
> drivers/acpi/sysfs.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)

[…]

The diff looks good. I’ll test later.
Comment 3 Paul Menzel 2018-01-24 22:01:41 UTC
Tested-by: Paul Menzel <pmenzel@molgen.mpg.de> (TUXEDO Book BU1406, BIOS 5.12 07/07/201)