Skip to content

Commit efe9711

Browse files
Neal Liurafaeljw
authored andcommitted
cpuidle: change enter_s2idle() prototype
Control Flow Integrity(CFI) is a security mechanism that disallows changes to the original control flow graph of a compiled binary, making it significantly harder to perform such attacks. init_state_node() assign same function callback to different function pointer declarations. static int init_state_node(struct cpuidle_state *idle_state, const struct of_device_id *matches, struct device_node *state_node) { ... idle_state->enter = match_id->data; ... idle_state->enter_s2idle = match_id->data; } Function declarations: struct cpuidle_state { ... int (*enter) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); void (*enter_s2idle) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); }; In this case, either enter() or enter_s2idle() would cause CFI check failed since they use same callee. Align function prototype of enter() since it needs return value for some use cases. The return value of enter_s2idle() is no need currently. Signed-off-by: Neal Liu <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 81f94dd commit efe9711

File tree

4 files changed

+19
-10
lines changed

4 files changed

+19
-10
lines changed

drivers/acpi/processor_idle.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,8 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
655655
return index;
656656
}
657657

658-
static void acpi_idle_enter_s2idle(struct cpuidle_device *dev,
659-
struct cpuidle_driver *drv, int index)
658+
static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
659+
struct cpuidle_driver *drv, int index)
660660
{
661661
struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
662662

@@ -674,6 +674,8 @@ static void acpi_idle_enter_s2idle(struct cpuidle_device *dev,
674674
}
675675
}
676676
acpi_idle_do_entry(cx);
677+
678+
return 0;
677679
}
678680

679681
static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,

drivers/cpuidle/cpuidle-tegra.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,13 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev,
253253
return err ? -1 : index;
254254
}
255255

256-
static void tegra114_enter_s2idle(struct cpuidle_device *dev,
257-
struct cpuidle_driver *drv,
258-
int index)
256+
static int tegra114_enter_s2idle(struct cpuidle_device *dev,
257+
struct cpuidle_driver *drv,
258+
int index)
259259
{
260260
tegra_cpuidle_enter(dev, drv, index);
261+
262+
return 0;
261263
}
262264

263265
/*

drivers/idle/intel_idle.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,15 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev,
173173
* Invoked as a suspend-to-idle callback routine with frozen user space, frozen
174174
* scheduler tick and suspended scheduler clock on the target CPU.
175175
*/
176-
static __cpuidle void intel_idle_s2idle(struct cpuidle_device *dev,
177-
struct cpuidle_driver *drv, int index)
176+
static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev,
177+
struct cpuidle_driver *drv, int index)
178178
{
179179
unsigned long eax = flg2MWAIT(drv->states[index].flags);
180180
unsigned long ecx = 1; /* break on interrupt flag */
181181

182182
mwait_idle_with_hints(eax, ecx);
183+
184+
return 0;
183185
}
184186

185187
/*

include/linux/cpuidle.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,13 @@ struct cpuidle_state {
6565
* CPUs execute ->enter_s2idle with the local tick or entire timekeeping
6666
* suspended, so it must not re-enable interrupts at any point (even
6767
* temporarily) or attempt to change states of clock event devices.
68+
*
69+
* This callback may point to the same function as ->enter if all of
70+
* the above requirements are met by it.
6871
*/
69-
void (*enter_s2idle) (struct cpuidle_device *dev,
70-
struct cpuidle_driver *drv,
71-
int index);
72+
int (*enter_s2idle)(struct cpuidle_device *dev,
73+
struct cpuidle_driver *drv,
74+
int index);
7275
};
7376

7477
/* Idle State Flags */

0 commit comments

Comments
 (0)