Skip to content

Commit 416de02

Browse files
nathanchancejwrdegoede
authored andcommitted
platform/x86: intel-uncore-freq: Fix types in sysfs callbacks
When booting a kernel with CONFIG_CFI_CLANG, there is a CFI failure when accessing any of the values under /sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00: $ cat /sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00/max_freq_khz fish: Job 1, 'cat /sys/devices/system/cpu/int…' terminated by signal SIGSEGV (Address boundary error) $ sudo dmesg &| grep 'CFI failure' [ 170.953925] CFI failure at kobj_attr_show+0x19/0x30 (target: show_max_freq_khz+0x0/0xc0 [intel_uncore_frequency_common]; expected type: 0xd34078c5 The sysfs callback functions such as show_domain_id() are written as if they are going to be called by dev_attr_show() but as the above message shows, they are instead called by kobj_attr_show(). kCFI checks that the destination of an indirect jump has the exact same type as the prototype of the function pointer it is called through and fails when they do not. These callbacks are called through kobj_attr_show() because uncore_root_kobj was initialized with kobject_create_and_add(), which means uncore_root_kobj has a ->sysfs_ops of kobj_sysfs_ops from kobject_create(), which uses kobj_attr_show() as its ->show() value. The only reason there has not been a more noticeable problem until this point is that 'struct kobj_attribute' and 'struct device_attribute' have the same layout, so getting the callback from container_of() works the same with either value. Change all the callbacks and their uses to be compatible with kobj_attr_show() and kobj_attr_store(), which resolves the kCFI failure and allows the sysfs files to work properly. Closes: ClangBuiltLinux#1974 Fixes: ae7b2ce ("platform/x86/intel/uncore-freq: Use sysfs API to create attributes") Cc: stable@vger.kernel.org Signed-off-by: Nathan Chancellor <nathan@kernel.org> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Link: https://lore.kernel.org/r/20240104-intel-uncore-freq-kcfi-fix-v1-1-bf1e8939af40@kernel.org Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 8446f9d commit 416de02

2 files changed

Lines changed: 57 additions & 57 deletions

File tree

drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@ static int (*uncore_read)(struct uncore_data *data, unsigned int *min, unsigned
2323
static int (*uncore_write)(struct uncore_data *data, unsigned int input, unsigned int min_max);
2424
static int (*uncore_read_freq)(struct uncore_data *data, unsigned int *freq);
2525

26-
static ssize_t show_domain_id(struct device *dev, struct device_attribute *attr, char *buf)
26+
static ssize_t show_domain_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
2727
{
28-
struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_dev_attr);
28+
struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_kobj_attr);
2929

3030
return sprintf(buf, "%u\n", data->domain_id);
3131
}
3232

33-
static ssize_t show_fabric_cluster_id(struct device *dev, struct device_attribute *attr, char *buf)
33+
static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
3434
{
35-
struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_dev_attr);
35+
struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_kobj_attr);
3636

3737
return sprintf(buf, "%u\n", data->cluster_id);
3838
}
3939

40-
static ssize_t show_package_id(struct device *dev, struct device_attribute *attr, char *buf)
40+
static ssize_t show_package_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
4141
{
42-
struct uncore_data *data = container_of(attr, struct uncore_data, package_id_dev_attr);
42+
struct uncore_data *data = container_of(attr, struct uncore_data, package_id_kobj_attr);
4343

4444
return sprintf(buf, "%u\n", data->package_id);
4545
}
@@ -97,30 +97,30 @@ static ssize_t show_perf_status_freq_khz(struct uncore_data *data, char *buf)
9797
}
9898

9999
#define store_uncore_min_max(name, min_max) \
100-
static ssize_t store_##name(struct device *dev, \
101-
struct device_attribute *attr, \
100+
static ssize_t store_##name(struct kobject *kobj, \
101+
struct kobj_attribute *attr, \
102102
const char *buf, size_t count) \
103103
{ \
104-
struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
104+
struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
105105
\
106106
return store_min_max_freq_khz(data, buf, count, \
107107
min_max); \
108108
}
109109

110110
#define show_uncore_min_max(name, min_max) \
111-
static ssize_t show_##name(struct device *dev, \
112-
struct device_attribute *attr, char *buf)\
111+
static ssize_t show_##name(struct kobject *kobj, \
112+
struct kobj_attribute *attr, char *buf)\
113113
{ \
114-
struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
114+
struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
115115
\
116116
return show_min_max_freq_khz(data, buf, min_max); \
117117
}
118118

119119
#define show_uncore_perf_status(name) \
120-
static ssize_t show_##name(struct device *dev, \
121-
struct device_attribute *attr, char *buf)\
120+
static ssize_t show_##name(struct kobject *kobj, \
121+
struct kobj_attribute *attr, char *buf)\
122122
{ \
123-
struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
123+
struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
124124
\
125125
return show_perf_status_freq_khz(data, buf); \
126126
}
@@ -134,11 +134,11 @@ show_uncore_min_max(max_freq_khz, 1);
134134
show_uncore_perf_status(current_freq_khz);
135135

136136
#define show_uncore_data(member_name) \
137-
static ssize_t show_##member_name(struct device *dev, \
138-
struct device_attribute *attr, char *buf)\
137+
static ssize_t show_##member_name(struct kobject *kobj, \
138+
struct kobj_attribute *attr, char *buf)\
139139
{ \
140140
struct uncore_data *data = container_of(attr, struct uncore_data,\
141-
member_name##_dev_attr);\
141+
member_name##_kobj_attr);\
142142
\
143143
return sysfs_emit(buf, "%u\n", \
144144
data->member_name); \
@@ -149,29 +149,29 @@ show_uncore_data(initial_max_freq_khz);
149149

150150
#define init_attribute_rw(_name) \
151151
do { \
152-
sysfs_attr_init(&data->_name##_dev_attr.attr); \
153-
data->_name##_dev_attr.show = show_##_name; \
154-
data->_name##_dev_attr.store = store_##_name; \
155-
data->_name##_dev_attr.attr.name = #_name; \
156-
data->_name##_dev_attr.attr.mode = 0644; \
152+
sysfs_attr_init(&data->_name##_kobj_attr.attr); \
153+
data->_name##_kobj_attr.show = show_##_name; \
154+
data->_name##_kobj_attr.store = store_##_name; \
155+
data->_name##_kobj_attr.attr.name = #_name; \
156+
data->_name##_kobj_attr.attr.mode = 0644; \
157157
} while (0)
158158

159159
#define init_attribute_ro(_name) \
160160
do { \
161-
sysfs_attr_init(&data->_name##_dev_attr.attr); \
162-
data->_name##_dev_attr.show = show_##_name; \
163-
data->_name##_dev_attr.store = NULL; \
164-
data->_name##_dev_attr.attr.name = #_name; \
165-
data->_name##_dev_attr.attr.mode = 0444; \
161+
sysfs_attr_init(&data->_name##_kobj_attr.attr); \
162+
data->_name##_kobj_attr.show = show_##_name; \
163+
data->_name##_kobj_attr.store = NULL; \
164+
data->_name##_kobj_attr.attr.name = #_name; \
165+
data->_name##_kobj_attr.attr.mode = 0444; \
166166
} while (0)
167167

168168
#define init_attribute_root_ro(_name) \
169169
do { \
170-
sysfs_attr_init(&data->_name##_dev_attr.attr); \
171-
data->_name##_dev_attr.show = show_##_name; \
172-
data->_name##_dev_attr.store = NULL; \
173-
data->_name##_dev_attr.attr.name = #_name; \
174-
data->_name##_dev_attr.attr.mode = 0400; \
170+
sysfs_attr_init(&data->_name##_kobj_attr.attr); \
171+
data->_name##_kobj_attr.show = show_##_name; \
172+
data->_name##_kobj_attr.store = NULL; \
173+
data->_name##_kobj_attr.attr.name = #_name; \
174+
data->_name##_kobj_attr.attr.mode = 0400; \
175175
} while (0)
176176

177177
static int create_attr_group(struct uncore_data *data, char *name)
@@ -186,21 +186,21 @@ static int create_attr_group(struct uncore_data *data, char *name)
186186

187187
if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) {
188188
init_attribute_root_ro(domain_id);
189-
data->uncore_attrs[index++] = &data->domain_id_dev_attr.attr;
189+
data->uncore_attrs[index++] = &data->domain_id_kobj_attr.attr;
190190
init_attribute_root_ro(fabric_cluster_id);
191-
data->uncore_attrs[index++] = &data->fabric_cluster_id_dev_attr.attr;
191+
data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr;
192192
init_attribute_root_ro(package_id);
193-
data->uncore_attrs[index++] = &data->package_id_dev_attr.attr;
193+
data->uncore_attrs[index++] = &data->package_id_kobj_attr.attr;
194194
}
195195

196-
data->uncore_attrs[index++] = &data->max_freq_khz_dev_attr.attr;
197-
data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr;
198-
data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr;
199-
data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr;
196+
data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr;
197+
data->uncore_attrs[index++] = &data->min_freq_khz_kobj_attr.attr;
198+
data->uncore_attrs[index++] = &data->initial_min_freq_khz_kobj_attr.attr;
199+
data->uncore_attrs[index++] = &data->initial_max_freq_khz_kobj_attr.attr;
200200

201201
ret = uncore_read_freq(data, &freq);
202202
if (!ret)
203-
data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr;
203+
data->uncore_attrs[index++] = &data->current_freq_khz_kobj_attr.attr;
204204

205205
data->uncore_attrs[index] = NULL;
206206

drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
* @instance_id: Unique instance id to append to directory name
2727
* @name: Sysfs entry name for this instance
2828
* @uncore_attr_group: Attribute group storage
29-
* @max_freq_khz_dev_attr: Storage for device attribute max_freq_khz
30-
* @mix_freq_khz_dev_attr: Storage for device attribute min_freq_khz
31-
* @initial_max_freq_khz_dev_attr: Storage for device attribute initial_max_freq_khz
32-
* @initial_min_freq_khz_dev_attr: Storage for device attribute initial_min_freq_khz
33-
* @current_freq_khz_dev_attr: Storage for device attribute current_freq_khz
34-
* @domain_id_dev_attr: Storage for device attribute domain_id
35-
* @fabric_cluster_id_dev_attr: Storage for device attribute fabric_cluster_id
36-
* @package_id_dev_attr: Storage for device attribute package_id
29+
* @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz
30+
* @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz
31+
* @initial_max_freq_khz_kobj_attr: Storage for kobject attribute initial_max_freq_khz
32+
* @initial_min_freq_khz_kobj_attr: Storage for kobject attribute initial_min_freq_khz
33+
* @current_freq_khz_kobj_attr: Storage for kobject attribute current_freq_khz
34+
* @domain_id_kobj_attr: Storage for kobject attribute domain_id
35+
* @fabric_cluster_id_kobj_attr: Storage for kobject attribute fabric_cluster_id
36+
* @package_id_kobj_attr: Storage for kobject attribute package_id
3737
* @uncore_attrs: Attribute storage for group creation
3838
*
3939
* This structure is used to encapsulate all data related to uncore sysfs
@@ -53,14 +53,14 @@ struct uncore_data {
5353
char name[32];
5454

5555
struct attribute_group uncore_attr_group;
56-
struct device_attribute max_freq_khz_dev_attr;
57-
struct device_attribute min_freq_khz_dev_attr;
58-
struct device_attribute initial_max_freq_khz_dev_attr;
59-
struct device_attribute initial_min_freq_khz_dev_attr;
60-
struct device_attribute current_freq_khz_dev_attr;
61-
struct device_attribute domain_id_dev_attr;
62-
struct device_attribute fabric_cluster_id_dev_attr;
63-
struct device_attribute package_id_dev_attr;
56+
struct kobj_attribute max_freq_khz_kobj_attr;
57+
struct kobj_attribute min_freq_khz_kobj_attr;
58+
struct kobj_attribute initial_max_freq_khz_kobj_attr;
59+
struct kobj_attribute initial_min_freq_khz_kobj_attr;
60+
struct kobj_attribute current_freq_khz_kobj_attr;
61+
struct kobj_attribute domain_id_kobj_attr;
62+
struct kobj_attribute fabric_cluster_id_kobj_attr;
63+
struct kobj_attribute package_id_kobj_attr;
6464
struct attribute *uncore_attrs[9];
6565
};
6666

0 commit comments

Comments
 (0)