The Linux Kernel Mailing List
 help / color / mirror / Atom feed
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


  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