From: Xixin Liu <liuxixin@kylinos.cn>
To: linuxppc-dev@lists.ozlabs.org
Cc: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,
chleroy@kernel.org, linux-kernel@vger.kernel.org,
liuxixin@kylinos.cn
Subject: [PATCH v1 1/4] powerpc/perf: hv-gpci: bound sysfs hex formatting to PAGE_SIZE
Date: Fri, 07 Aug 2026 11:11:14 +0800 [thread overview]
Message-ID: <prpppc01hvgpc.1786072274.git.liuxixin@kylinos.cn> (raw)
In-Reply-To: <cover.1786072274.git.liuxixin@kylinos.cn>
hv-gpci sysfs show paths format hypervisor counter bytes with sprintf()
into a PAGE_SIZE buffer, and only sometimes check the length afterwards.
Each byte becomes two hex digits plus newlines, so the output can grow
past PAGE_SIZE. Checking after sprintf() is too late: the write already
overflowed the sysfs buffer. One path had no size check at all.
Use sysfs_emit_at() so formatting stays within the sysfs buffer. If a
field cannot fit completely, return -EFBIG rather than silently
truncating.
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
arch/powerpc/perf/hv-gpci.c | 77 +++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 25 deletions(-)
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 76495744f..14a4f414b 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -136,6 +136,7 @@ static unsigned long systeminfo_gpci_request(u32 req, u32 starting_index,
{
unsigned long ret;
size_t i, j;
+ int len;
arg->params.counter_request = cpu_to_be32(req);
arg->params.starting_index = cpu_to_be32(starting_index);
@@ -177,17 +178,23 @@ static unsigned long systeminfo_gpci_request(u32 req, u32 starting_index,
for (i = 0; i < be16_to_cpu(arg->params.returned_values); i++) {
j = i * be16_to_cpu(arg->params.cv_element_size);
- for (; j < (i + 1) * be16_to_cpu(arg->params.cv_element_size); j++)
- *n += sprintf(buf + *n, "%02x", (u8)arg->bytes[j]);
- *n += sprintf(buf + *n, "\n");
- }
-
- if (*n >= PAGE_SIZE) {
- pr_info("System information exceeds PAGE_SIZE\n");
- return -EFBIG;
+ for (; j < (i + 1) * be16_to_cpu(arg->params.cv_element_size); j++) {
+ len = sysfs_emit_at(buf, *n, "%02x", (u8)arg->bytes[j]);
+ if (len != 2)
+ goto emit_failed;
+ *n += len;
+ }
+ len = sysfs_emit_at(buf, *n, "\n");
+ if (len != 1)
+ goto emit_failed;
+ *n += len;
}
return ret;
+
+emit_failed:
+ pr_info("System information does not fit in sysfs buffer\n");
+ return -EFBIG;
}
static ssize_t processor_bus_topology_show(struct device *dev, struct device_attribute *attr,
@@ -470,12 +477,13 @@ static ssize_t affinity_domain_via_domain_show(struct device *dev, struct device
return ret;
}
-static void affinity_domain_via_partition_result_parse(int returned_values,
+static int affinity_domain_via_partition_result_parse(int returned_values,
int element_size, char *buf, size_t *last_element,
size_t *n, struct hv_gpci_request_buffer *arg)
{
size_t i = 0, j = 0;
size_t k, l, m;
+ int len;
uint16_t total_affinity_domain_ele, size_of_each_affinity_domain_ele;
/*
@@ -492,27 +500,44 @@ static void affinity_domain_via_partition_result_parse(int returned_values,
*/
while (i < returned_values) {
k = j;
- for (; k < j + element_size; k++)
- *n += sprintf(buf + *n, "%02x", (u8)arg->bytes[k]);
- *n += sprintf(buf + *n, "\n");
+ for (; k < j + element_size; k++) {
+ len = sysfs_emit_at(buf, *n, "%02x", (u8)arg->bytes[k]);
+ if (len != 2)
+ return -EFBIG;
+ *n += len;
+ }
+ len = sysfs_emit_at(buf, *n, "\n");
+ if (len != 1)
+ return -EFBIG;
+ *n += len;
total_affinity_domain_ele = (u8)arg->bytes[k - 2] << 8 | (u8)arg->bytes[k - 3];
size_of_each_affinity_domain_ele = (u8)arg->bytes[k] << 8 | (u8)arg->bytes[k - 1];
for (l = 0; l < total_affinity_domain_ele; l++) {
for (m = 0; m < size_of_each_affinity_domain_ele; m++) {
- *n += sprintf(buf + *n, "%02x", (u8)arg->bytes[k]);
+ len = sysfs_emit_at(buf, *n, "%02x", (u8)arg->bytes[k]);
+ if (len != 2)
+ return -EFBIG;
+ *n += len;
k++;
}
- *n += sprintf(buf + *n, "\n");
+ len = sysfs_emit_at(buf, *n, "\n");
+ if (len != 1)
+ return -EFBIG;
+ *n += len;
}
- *n += sprintf(buf + *n, "\n");
+ len = sysfs_emit_at(buf, *n, "\n");
+ if (len != 1)
+ return -EFBIG;
+ *n += len;
i++;
j = k;
}
*last_element = k;
+ return 0;
}
static ssize_t affinity_domain_via_partition_show(struct device *dev, struct device_attribute *attr,
@@ -555,12 +580,10 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev
* to buffer util we get all the information.
*/
while (ret == H_PARAMETER) {
- affinity_domain_via_partition_result_parse(
- be16_to_cpu(arg->params.returned_values) - 1,
- be16_to_cpu(arg->params.cv_element_size), buf,
- &last_element, &n, arg);
-
- if (n >= PAGE_SIZE) {
+ if (affinity_domain_via_partition_result_parse(
+ be16_to_cpu(arg->params.returned_values) - 1,
+ be16_to_cpu(arg->params.cv_element_size), buf,
+ &last_element, &n, arg)) {
put_cpu_var(hv_gpci_reqb);
pr_debug("System information does not fit in sysfs buffer\n");
return -EFBIG;
@@ -587,10 +610,14 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev
}
parse_result:
- affinity_domain_via_partition_result_parse(
- be16_to_cpu(arg->params.returned_values),
- be16_to_cpu(arg->params.cv_element_size),
- buf, &last_element, &n, arg);
+ if (affinity_domain_via_partition_result_parse(
+ be16_to_cpu(arg->params.returned_values),
+ be16_to_cpu(arg->params.cv_element_size),
+ buf, &last_element, &n, arg)) {
+ put_cpu_var(hv_gpci_reqb);
+ pr_debug("System information does not fit in sysfs buffer\n");
+ return -EFBIG;
+ }
put_cpu_var(hv_gpci_reqb);
return n;
--
2.43.0
next prev parent reply other threads:[~2026-08-07 3:31 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 3:11 [PATCH v1 0/4] powerpc: assorted fixes (gpci, imc, energy, iommu) Xixin Liu
2026-08-07 3:11 ` Xixin Liu [this message]
2026-08-07 3:11 ` [PATCH v1 2/4] powerpc/powernv: opal-imc: fix debugfs name buffer size Xixin Liu
2026-08-07 3:11 ` [PATCH v1 3/4] powerpc/pseries: energy: bound H_BEST_ENERGY cnt and sysfs output Xixin Liu
2026-08-07 3:11 ` [PATCH v1 4/4] powerpc/iommu: fix debugfs name buffer for 64-bit it_index Xixin Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=prpppc01hvgpc.1786072274.git.liuxixin@kylinos.cn \
--to=liuxixin@kylinos.cn \
--cc=chleroy@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox