[PATCH v1 3/4] powerpc/pseries: energy: bound H_BEST_ENERGY cnt and sysfs output

Xixin Liu <[email protected]>
Newsgroups org.ozlabs.lists.linuxppc-dev,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The H_BEST_ENERGY sysfs path takes cnt from the hypercall return buffer
and walks buf_page[2*i+1] without checking that cnt fits in the single
page allocated for the hcall, and sprintf()s into the PAGE_SIZE sysfs
buffer without remaining-space checks.

Clamp cnt to the number of u32 pairs that fit in the page, and stop
formatting before overflowing the sysfs page.

Signed-off-by: Xixin Liu <[email protected]>
---
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
index fdaf85ecd39b..8344f00656e5 100644
--- a/arch/powerpc/platforms/pseries/pseries_energy.c
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -209,16 +209,28 @@
 		return -EINVAL;
 	}
 
+	/*
+	 * Each entry occupies two u32s in buf_page. Never walk past the
+	 * page, and never sprintf past the PAGE_SIZE sysfs buffer.
+	 */
 	cnt = retbuf[0];
+	if (cnt > (PAGE_SIZE / sizeof(u32)) / 2)
+		cnt = (PAGE_SIZE / sizeof(u32)) / 2;
+
 	for (i = 0; i < cnt; i++) {
 		cpu = drc_index_to_cpu(buf_page[2*i+1]);
 		if ((cpu_online(cpu) && !activate) ||
-		    (!cpu_online(cpu) && activate))
+		    (!cpu_online(cpu) && activate)) {
+			if (s - page >= PAGE_SIZE - 16)
+				break;
 			s += sprintf(s, "%d,", cpu);
+		}
 	}
 	if (s > page) { /* Something to show */
 		s--; /* Suppress last comma */
-		s += sprintf(s, "\n");
+		/* sprintf needs room for '\n' and trailing NUL. */
+		if (s - page < PAGE_SIZE - 1)
+			s += sprintf(s, "\n");
 	}
 
 	free_page((unsigned long) buf_page);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.