Gentle ping on this patch. On Fri, 2020-07-10 at 11:08 +0800, Neal Liu wrote: > On Thu, 2020-07-09 at 14:18 +0200, Rafael J. Wysocki wrote: > > On Mon, Jul 6, 2020 at 5:13 AM Neal Liu <neal.liu@xxxxxxxxxxxx> wrote: > > > > > > 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. > > > > Can you please explain this in a bit more detail? > > > > As it stands, I don't understand the problem statement enough to apply > > the patch. > > > > Okay, Let's me try to explain more details. > 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. > > There are multiple control flow instructions that could be manipulated > by the attacker and subvert control flow. The target instructions that > use data to determine the actual destination. > - indirect jump > - indirect call > - return > > In this case, function prototype between caller and callee are mismatch. > Caller: (type A)funcA > Callee: (type A)funcB > Callee: (type C)funcC > > funcA calls funcB -> no problem > funcA calls funcC -> CFI check failed > > That's why we try to align function prototype. > Please feel free to feedback if you have any questions. > > > > Align function prototype of enter() since it needs return value for > > > some use cases. The return value of enter_s2idle() is no > > > need currently. > > > > So last time I requested you to document why ->enter_s2idle needs to > > return an int in the code, which has not been done. Please do that. > > > > > Signed-off-by: Neal Liu <neal.liu@xxxxxxxxxxxx> > > > --- > > > drivers/acpi/processor_idle.c | 6 ++++-- > > > drivers/cpuidle/cpuidle-tegra.c | 8 +++++--- > > > drivers/idle/intel_idle.c | 6 ++++-- > > > include/linux/cpuidle.h | 6 +++--- > > > 4 files changed, 16 insertions(+), 10 deletions(-) > > > > > > diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c > > > index 75534c5..6ffb6c9 100644 > > > --- a/drivers/acpi/processor_idle.c > > > +++ b/drivers/acpi/processor_idle.c > > > @@ -655,8 +655,8 @@ static int acpi_idle_enter(struct cpuidle_device *dev, > > > return index; > > > } > > > > > > -static void acpi_idle_enter_s2idle(struct cpuidle_device *dev, > > > - struct cpuidle_driver *drv, int index) > > > +static int acpi_idle_enter_s2idle(struct cpuidle_device *dev, > > > + struct cpuidle_driver *drv, int index) > > > { > > > struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); > > > > > > @@ -674,6 +674,8 @@ static void acpi_idle_enter_s2idle(struct cpuidle_device *dev, > > > } > > > } > > > acpi_idle_do_entry(cx); > > > + > > > + return 0; > > > } > > > > > > static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, > > > diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c > > > index 1500458..a12fb14 100644 > > > --- a/drivers/cpuidle/cpuidle-tegra.c > > > +++ b/drivers/cpuidle/cpuidle-tegra.c > > > @@ -253,11 +253,13 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev, > > > return err ? -1 : index; > > > } > > > > > > -static void tegra114_enter_s2idle(struct cpuidle_device *dev, > > > - struct cpuidle_driver *drv, > > > - int index) > > > +static int tegra114_enter_s2idle(struct cpuidle_device *dev, > > > + struct cpuidle_driver *drv, > > > + int index) > > > { > > > tegra_cpuidle_enter(dev, drv, index); > > > + > > > + return 0; > > > } > > > > > > /* > > > diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c > > > index f449584..b178da3 100644 > > > --- a/drivers/idle/intel_idle.c > > > +++ b/drivers/idle/intel_idle.c > > > @@ -175,13 +175,15 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev, > > > * Invoked as a suspend-to-idle callback routine with frozen user space, frozen > > > * scheduler tick and suspended scheduler clock on the target CPU. > > > */ > > > -static __cpuidle void intel_idle_s2idle(struct cpuidle_device *dev, > > > - struct cpuidle_driver *drv, int index) > > > +static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, > > > + struct cpuidle_driver *drv, int index) > > > { > > > unsigned long eax = flg2MWAIT(drv->states[index].flags); > > > unsigned long ecx = 1; /* break on interrupt flag */ > > > > > > mwait_idle_with_hints(eax, ecx); > > > + > > > + return 0; > > > } > > > > > > /* > > > diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h > > > index ec2ef63..bee10c0 100644 > > > --- a/include/linux/cpuidle.h > > > +++ b/include/linux/cpuidle.h > > > @@ -66,9 +66,9 @@ struct cpuidle_state { > > > * suspended, so it must not re-enable interrupts at any point (even > > > * temporarily) or attempt to change states of clock event devices. > > > */ > > > - void (*enter_s2idle) (struct cpuidle_device *dev, > > > - struct cpuidle_driver *drv, > > > - int index); > > > + int (*enter_s2idle)(struct cpuidle_device *dev, > > > + struct cpuidle_driver *drv, > > > + int index); > > > }; > > > > > > /* Idle State Flags */ > > > -- > > > 1.7.9.5 > >