From 948b3edba8988306b635578a72b0dab6091a5eb0 Mon Sep 17 00:00:00 2001
From: Joe Perches <joe@perches.com>
Date: Wed, 16 Sep 2020 13:40:42 -0700
Subject: [PATCH] drivers core: Miscellaneous changes for sysfs_emit
Git-commit: 948b3edba8988306b635578a72b0dab6091a5eb0
Patch-mainline: v5.10-rc1
References: bsc#1200598 cve-2022-20166
Change additional instances that could use sysfs_emit and sysfs_emit_at
that the coccinelle script could not convert.
o macros creating show functions with ## concatenation
o unbound sprintf uses with buf+len for start of output to sysfs_emit_at
o returns with ?: tests and sprintf to sysfs_emit
o sysfs output with struct class * not struct device * arguments
Miscellanea:
o remove unnecessary initializations around these changes
o consistently use int len for return length of show functions
o use octal permissions and not S_<FOO>
o rename a few show function names so DEVICE_ATTR_<FOO> can be used
o use DEVICE_ATTR_ADMIN_RO where appropriate
o consistently use const char *output for strings
o checkpatch/style neatening
Signed-off-by: Joe Perches <joe@perches.com>
Link: https://lore.kernel.org/r/8bc24444fe2049a9b2de6127389b57edfdfe324d.1600285923.git.joe@perches.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Petr Mladek <pmladek@suse.com>
[ pmladek@suse.com: Removed changes when the buffer could never overflow.
Also removed cosmetic changes.
]
---
drivers/base/class.c | 2 -
drivers/base/core.c | 6 ++---
drivers/base/cpu.c | 41 ++++++++++++++++++------------------
drivers/base/node.c | 54 +++++++++++++++++++++---------------------------
drivers/base/platform.c | 4 ---
5 files changed, 50 insertions(+), 57 deletions(-)
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -477,7 +477,7 @@ ssize_t show_class_attr_string(struct cl
struct class_attribute_string *cs;
cs = container_of(attr, struct class_attribute_string, attr);
- return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
+ return sysfs_emit(buf, "%s\n", cs->str);
}
EXPORT_SYMBOL_GPL(show_class_attr_string);
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1201,7 +1201,7 @@ static ssize_t uevent_show(struct device
struct kset *kset;
struct kobj_uevent_env *env = NULL;
int i;
- size_t count = 0;
+ int len = 0;
int retval;
/* search the kset, the device belongs to */
@@ -1231,10 +1231,10 @@ static ssize_t uevent_show(struct device
/* copy keys to file */
for (i = 0; i < env->envp_idx; i++)
- count += sprintf(&buf[count], "%s\n", env->envp[i]);
+ len += sysfs_emit_at(buf, len, "%s\n", env->envp[i]);
out:
kfree(env);
- return count;
+ return len;
}
static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -241,37 +241,37 @@ unsigned int total_cpus;
static ssize_t print_cpus_offline(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int n = 0, len = PAGE_SIZE-2;
+ int len = 0;
cpumask_var_t offline;
/* display offline cpus < nr_cpu_ids */
if (!alloc_cpumask_var(&offline, GFP_KERNEL))
return -ENOMEM;
cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
- n = scnprintf(buf, len, "%*pbl", cpumask_pr_args(offline));
+ len += sysfs_emit_at(buf, len, "%*pbl", cpumask_pr_args(offline));
free_cpumask_var(offline);
/* display offline cpus >= nr_cpu_ids */
if (total_cpus && nr_cpu_ids < total_cpus) {
- if (n && n < len)
- buf[n++] = ',';
+ len += sysfs_emit_at(buf, len, ",");
if (nr_cpu_ids == total_cpus-1)
- n += snprintf(&buf[n], len - n, "%u", nr_cpu_ids);
+ len += sysfs_emit_at(buf, len, "%u", nr_cpu_ids);
else
- n += snprintf(&buf[n], len - n, "%u-%d",
- nr_cpu_ids, total_cpus-1);
+ len += sysfs_emit_at(buf, len, "%u-%d",
+ nr_cpu_ids, total_cpus - 1);
}
- n += snprintf(&buf[n], len - n, "\n");
- return n;
+ len += sysfs_emit_at(buf, len, "\n");
+
+ return len;
}
static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
static ssize_t print_cpus_isolated(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int n = 0;
+ int len = 0;
cpumask_var_t isolated;
if (!alloc_cpumask_var(&isolated, GFP_KERNEL))
@@ -279,17 +279,17 @@ static ssize_t print_cpus_isolated(struc
cpumask_andnot(isolated, cpu_possible_mask,
housekeeping_cpumask(HK_FLAG_DOMAIN));
- n = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated));
+ len = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated));
free_cpumask_var(isolated);
- return n;
+ return len;
}
static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);
#ifdef CONFIG_NO_HZ_FULL
static ssize_t print_cpus_nohz_full(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask));
}
@@ -320,22 +320,23 @@ static ssize_t print_cpu_modalias(struct
struct device_attribute *attr,
char *buf)
{
- ssize_t n;
+ int len = 0;
u32 i;
- n = sysfs_emit(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
- CPU_FEATURE_TYPEVAL);
+ len += sysfs_emit_at(buf, len,
+ "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
+ CPU_FEATURE_TYPEVAL);
for (i = 0; i < MAX_CPU_FEATURES; i++)
if (cpu_have_feature(i)) {
- if (PAGE_SIZE < n + sizeof(",XXXX\n")) {
+ if (len + sizeof(",XXXX\n") >= PAGE_SIZE) {
WARN(1, "CPU features overflow page\n");
break;
}
- n += sprintf(&buf[n], ",%04X", i);
+ len += sysfs_emit_at(buf, len, ",%04X", i);
}
- buf[n++] = '\n';
- return n;
+ len += sysfs_emit_at(buf, len, "\n");
+ return len;
}
static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -225,7 +225,8 @@ static ssize_t name##_show(struct device
struct device_attribute *attr, \
char *buf) \
{ \
- return sprintf(buf, fmt "\n", to_cache_info(dev)->cache_attrs.name);\
+ return sysfs_emit(buf, fmt "\n", \
+ to_cache_info(dev)->cache_attrs.name); \
} \
DEVICE_ATTR_RO(name);
@@ -361,7 +362,7 @@ static void node_remove_caches(struct no
static ssize_t node_read_meminfo(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int n;
+ int len = 0;
int nid = dev->id;
struct pglist_data *pgdat = NODE_DATA(nid);
struct sysinfo i;
@@ -370,7 +371,7 @@ static ssize_t node_read_meminfo(struct
si_meminfo_node(&i, nid);
sreclaimable = node_page_state(pgdat, NR_SLAB_RECLAIMABLE);
sunreclaimable = node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE);
- n = sysfs_emit(buf,
+ len = sysfs_emit(buf,
"Node %d MemTotal: %8lu kB\n"
"Node %d MemFree: %8lu kB\n"
"Node %d MemUsed: %8lu kB\n"
@@ -397,7 +398,7 @@ static ssize_t node_read_meminfo(struct
nid, K(sum_zone_node_page_state(nid, NR_MLOCK)));
#ifdef CONFIG_HIGHMEM
- n += sprintf(buf + n,
+ len += sysfs_emit_at(buf, len,
"Node %d HighTotal: %8lu kB\n"
"Node %d HighFree: %8lu kB\n"
"Node %d LowTotal: %8lu kB\n"
@@ -407,7 +408,7 @@ static ssize_t node_read_meminfo(struct
nid, K(i.totalram - i.totalhigh),
nid, K(i.freeram - i.freehigh));
#endif
- n += sprintf(buf + n,
+ len += sysfs_emit_at(buf, len,
"Node %d Dirty: %8lu kB\n"
"Node %d Writeback: %8lu kB\n"
"Node %d FilePages: %8lu kB\n"
@@ -455,12 +456,12 @@ static ssize_t node_read_meminfo(struct
HPAGE_PMD_NR)
#endif
);
- n += hugetlb_report_node_meminfo(nid, buf + n);
- return n;
+ len += hugetlb_report_node_meminfo(nid, buf + len);
+ return len;
}
#undef K
-static DEVICE_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
+static DEVICE_ATTR(meminfo, 0444, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -487,28 +488,28 @@ static ssize_t node_read_vmstat(struct d
int nid = dev->id;
struct pglist_data *pgdat = NODE_DATA(nid);
int i;
- int n = 0;
+ int len = 0;
for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
- n += sprintf(buf+n, "%s %lu\n", vmstat_text[i],
+ len += sysfs_emit_at(buf, len, "%s %lu\n", vmstat_text[i],
sum_zone_node_page_state(nid, i));
#ifdef CONFIG_NUMA
for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
- n += sprintf(buf+n, "%s %lu\n",
+ len += sysfs_emit_at(buf, len, "%s %lu\n",
vmstat_text[i + NR_VM_ZONE_STAT_ITEMS],
sum_zone_numa_state(nid, i));
#endif
for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
- n += sprintf(buf+n, "%s %lu\n",
+ len += sysfs_emit_at(buf, len, "%s %lu\n",
vmstat_text[i + NR_VM_ZONE_STAT_ITEMS +
NR_VM_NUMA_STAT_ITEMS],
node_page_state(pgdat, i));
- return n;
+ return len;
}
-static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
+static DEVICE_ATTR(vmstat, 0444, node_read_vmstat, NULL);
static ssize_t node_read_distance(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -523,13 +524,15 @@ static ssize_t node_read_distance(struct
*/
BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
- for_each_online_node(i)
- len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
+ for_each_online_node(i) {
+ len += sysfs_emit_at(buf, len, "%s%d",
+ i ? " " : "", node_distance(nid, i));
+ }
- len += sprintf(buf + len, "\n");
+ len += sysfs_emit_at(buf, len, "\n");
return len;
}
-static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
+static DEVICE_ATTR(distance, 0444, node_read_distance, NULL);
static struct attribute *node_dev_attrs[] = {
&dev_attr_cpumap.attr,
@@ -976,17 +979,6 @@ void unregister_one_node(int nid)
* node states attributes
*/
-static ssize_t print_nodes_state(enum node_states state, char *buf)
-{
- int n;
-
- n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
- nodemask_pr_args(&node_states[state]));
- buf[n++] = '\n';
- buf[n] = '\0';
- return n;
-}
-
struct node_attr {
struct device_attribute attr;
enum node_states state;
@@ -996,7 +988,9 @@ static ssize_t show_node_state(struct de
struct device_attribute *attr, char *buf)
{
struct node_attr *na = container_of(attr, struct node_attr, attr);
- return print_nodes_state(na->state, buf);
+
+ return sysfs_emit(buf, "%*pbl\n",
+ nodemask_pr_args(&node_states[na->state]));
}
#define _NODE_ATTR(name, state) \
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -975,9 +975,7 @@ static ssize_t modalias_show(struct devi
if (len != -ENODEV)
return len;
- len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
-
- return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+ return sysfs_emit(buf, "platform:%s\n", pdev->name);
}
static DEVICE_ATTR_RO(modalias);