Linux Kernel: PM / clk: Fix clock error check in __pm_clk_add()
PM / clk: Fix clock error check in __pm_clk_add()
This kernel change corrects a logic error in the clock power management subsystem where an IS_ERR() check was operating on the wrong pointer variable, creating a potential NULL pointer dereference vulnerability.
The Problem
In commit 245bd6f6af8a62a2 (“PM / clock_ops: Add pm_clk_add_clk()”), a refcount increment was added to the __pm_clk_add() function in drivers/base/power/clock_ops.c. However, the accompanying error checking had a critical flaw:
if (IS_ERR(ce->clk) || !__clk_get(clk)) {
The IS_ERR() macro was checking ce->clk instead of the actual clk pointer being passed to the function. Since ce->clk is always zero at this point in the code flow, the check never catches actual errors. This means when __clk_get() later tries to dereference an error pointer, it can cause a NULL pointer dereference or use an invalid pointer.
The Fix
The correction is straightforward — check the correct pointer:
if (IS_ERR(clk) || !__clk_get(clk)) {
Now the error checking validates the actual clock pointer parameter before attempting to increment its refcount with __clk_get(clk).
Commit Details
- Author: Geert Uytterhoeven geert+renesas@glider.be
- Commit hash: 3fc3a0b
- Fixes: 245bd6f6af8a62a2 (“PM / clock_ops: Add pm_clk_add_clk()”)
- Date: Fri May 8 10:47:43 2015 +0200
- File: drivers/base/power/clock_ops.c (2 lines changed)
Why This Matters
This type of error is common in kernel code where pointers are validated with IS_ERR() and PTR_ERR() macros. The pattern requires careful attention to ensure you’re checking the right variable. In this case, the bug could have led to:
- Uncaught invalid clock pointers passed through the system
- NULL pointer dereferences deep in the clock framework
- Runtime failures in device power management operations
Code reviewers and maintainers typically flag such discrepancies, but this one slipped through during the final iteration of the change. The fix ensures that clock pointers are properly validated before being used in downstream functions.