[Deepin-Kernel-SIG] [linux 6.6.y] [Upstream] gpiolib: acpi: Fix potential out-of-boundary left shift#1715
Conversation
mainline inclusion from mainline-v6.19-rc8 commit e64d1cb category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9158 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e64d1cb21a1c6ecd51bc1c94c83f6fc656f7c94d -------------------------------- GPIO Address Space handler gets a pointer to the in or out value. This value is supposed to be at least 64-bit, but it's not limited to be exactly 64-bit. When ACPI tables are being parsed, for the bigger Connection():s ACPICA creates a Buffer instead of regular Integer object. The Buffer exists as long as Namespace holds the certain Connection(). Hence we can access the necessary bits without worrying. On the other hand, the left shift, used in the code, is limited by 31 (on 32-bit platforms) and otherwise considered to be Undefined Behaviour. Also the code uses only the first 64-bit word for the value, and anything bigger than 63 will be also subject to UB. Fix all this by modifying the code to correctly set or clear the respective bit in the bitmap constructed of 64-bit words. Fixes: 59084c564c41 ("gpiolib: acpi: use BIT_ULL() for u64 mask in address space handler") Fixes: 2c4d00c ("gpiolib: acpi: Use BIT() macro to increase readability") Cc: stable@vger.kernel.org Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://patch.msgid.link/20260128095918.4157491-1-andriy.shevchenko@linux.intel.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Reviewer's guide (collapsed on small PRs)Reviewer's GuidePorts an upstream gpiolib ACPI bugfix to correctly handle GPIO OperationRegions larger than 64 bits by indexing into a 64-bit word array instead of shifting by the absolute pin index, eliminating potential out-of-bounds and undefined left-shift behavior on 32-bit and multi-word values. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
有CVE编号的话可以在PR里备注一下 /approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Avenger-285714 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Pull request overview
This PR backports an upstream stable fix to gpiolib-acpi to avoid undefined behavior when handling GPIO OpRegion bitmasks larger than 64 bits, by switching from single-word shifts to word+bit addressing.
Changes:
- Compute a 64-bit word index and intra-word bit shift (
i / 64,i % 64) for GPIO OpRegion accesses. - Update ACPI_READ/ACPI_WRITE paths to set/clear bits in the backing value rather than shifting by an unbounded amount.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| shift = i % 64; | ||
|
|
||
| if (function == ACPI_WRITE) { | ||
| gpiod_set_raw_value_cansleep(desc, value[word] & BIT_ULL(shift)); |
| /* | ||
| * For the cases when OperationRegion() consists of more than | ||
| * 64 bits calculate the word and bit shift to use that one to | ||
| * access the value. | ||
| */ | ||
| word = i / 64; | ||
| shift = i % 64; | ||
|
|
||
| if (function == ACPI_WRITE) { | ||
| gpiod_set_raw_value_cansleep(desc, value[word] & BIT_ULL(shift)); | ||
| } else { | ||
| if (gpiod_get_raw_value_cansleep(desc)) | ||
| value[word] |= BIT_ULL(shift); | ||
| else | ||
| value[word] &= ~BIT_ULL(shift); | ||
| } |
mainline inclusion
from mainline-v6.19-rc8
commit e64d1cb
category: bugfix
bugzilla: https://atomgit.com/openeuler/kernel/issues/9158
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e64d1cb21a1c6ecd51bc1c94c83f6fc656f7c94d
GPIO Address Space handler gets a pointer to the in or out value. This value is supposed to be at least 64-bit, but it's not limited to be exactly 64-bit. When ACPI tables are being parsed, for the bigger Connection():s ACPICA creates a Buffer instead of regular Integer object. The Buffer exists as long as Namespace holds the certain Connection(). Hence we can access the necessary bits without worrying. On the other hand, the left shift, used in the code, is limited by 31 (on 32-bit platforms) and otherwise considered to be Undefined Behaviour. Also the code uses only the first 64-bit word for the value, and anything bigger than 63 will be also subject to UB. Fix all this by modifying the code to correctly set or clear the respective bit in the bitmap constructed of 64-bit words.
Fixes: 59084c564c41 ("gpiolib: acpi: use BIT_ULL() for u64 mask in address space handler")
Fixes: 2c4d00c ("gpiolib: acpi: Use BIT() macro to increase readability")
Cc: stable@vger.kernel.org
Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com
Link: https://patch.msgid.link/20260128095918.4157491-1-andriy.shevchenko@linux.intel.com
Summary by Sourcery
Bug Fixes: