Skip to content

Commit dd4f730

Browse files
nathanchancerafaeljw
authored andcommitted
ACPI: platform-profile: Fix CFI violation when accessing sysfs files
When an attribute group is created with sysfs_create_group(), the ->sysfs_ops() callback is set to kobj_sysfs_ops, which sets the ->show() and ->store() callbacks to kobj_attr_show() and kobj_attr_store() respectively. These functions use container_of() to get the respective callback from the passed attribute, meaning that these callbacks need to be of the same type as the callbacks in 'struct kobj_attribute'. However, ->show() and ->store() in the platform_profile driver are defined for struct device_attribute with the help of DEVICE_ATTR_RO() and DEVICE_ATTR_RW(), which results in a CFI violation when accessing platform_profile or platform_profile_choices under /sys/firmware/acpi because the types do not match: CFI failure at kobj_attr_show+0x19/0x30 (target: platform_profile_choices_show+0x0/0x140; expected type: 0x7a69590c) There is no functional issue from the type mismatch because the layout of 'struct kobj_attribute' and 'struct device_attribute' are the same, so the container_of() cast does not break anything aside from CFI. Change the type of platform_profile_choices_show() and platform_profile_{show,store}() to match the callbacks in 'struct kobj_attribute' and update the attribute variables to match, which resolves the CFI violation. Cc: All applicable <stable@vger.kernel.org> Fixes: a2ff95e ("ACPI: platform: Add platform profile support") Reported-by: John Rowley <lkml@johnrowley.me> Closes: ClangBuiltLinux#2047 Tested-by: John Rowley <lkml@johnrowley.me> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Nathan Chancellor <nathan@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca> Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca> Link: https://patch.msgid.link/20250210-acpi-platform_profile-fix-cfi-violation-v3-1-ed9e9901c33a@kernel.org [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 0ad2507 commit dd4f730

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

drivers/acpi/platform_profile.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,14 @@ static int _aggregate_choices(struct device *dev, void *data)
260260

261261
/**
262262
* platform_profile_choices_show - Show the available profile choices for legacy sysfs interface
263-
* @dev: The device
263+
* @kobj: The kobject
264264
* @attr: The attribute
265265
* @buf: The buffer to write to
266266
*
267267
* Return: The number of bytes written
268268
*/
269-
static ssize_t platform_profile_choices_show(struct device *dev,
270-
struct device_attribute *attr,
269+
static ssize_t platform_profile_choices_show(struct kobject *kobj,
270+
struct kobj_attribute *attr,
271271
char *buf)
272272
{
273273
unsigned long aggregate[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
@@ -333,14 +333,14 @@ static int _store_and_notify(struct device *dev, void *data)
333333

334334
/**
335335
* platform_profile_show - Show the current profile for legacy sysfs interface
336-
* @dev: The device
336+
* @kobj: The kobject
337337
* @attr: The attribute
338338
* @buf: The buffer to write to
339339
*
340340
* Return: The number of bytes written
341341
*/
342-
static ssize_t platform_profile_show(struct device *dev,
343-
struct device_attribute *attr,
342+
static ssize_t platform_profile_show(struct kobject *kobj,
343+
struct kobj_attribute *attr,
344344
char *buf)
345345
{
346346
enum platform_profile_option profile = PLATFORM_PROFILE_LAST;
@@ -362,15 +362,15 @@ static ssize_t platform_profile_show(struct device *dev,
362362

363363
/**
364364
* platform_profile_store - Set the profile for legacy sysfs interface
365-
* @dev: The device
365+
* @kobj: The kobject
366366
* @attr: The attribute
367367
* @buf: The buffer to read from
368368
* @count: The number of bytes to read
369369
*
370370
* Return: The number of bytes read
371371
*/
372-
static ssize_t platform_profile_store(struct device *dev,
373-
struct device_attribute *attr,
372+
static ssize_t platform_profile_store(struct kobject *kobj,
373+
struct kobj_attribute *attr,
374374
const char *buf, size_t count)
375375
{
376376
unsigned long choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
@@ -401,12 +401,12 @@ static ssize_t platform_profile_store(struct device *dev,
401401
return count;
402402
}
403403

404-
static DEVICE_ATTR_RO(platform_profile_choices);
405-
static DEVICE_ATTR_RW(platform_profile);
404+
static struct kobj_attribute attr_platform_profile_choices = __ATTR_RO(platform_profile_choices);
405+
static struct kobj_attribute attr_platform_profile = __ATTR_RW(platform_profile);
406406

407407
static struct attribute *platform_profile_attrs[] = {
408-
&dev_attr_platform_profile_choices.attr,
409-
&dev_attr_platform_profile.attr,
408+
&attr_platform_profile_choices.attr,
409+
&attr_platform_profile.attr,
410410
NULL
411411
};
412412

0 commit comments

Comments
 (0)