From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12BBF263F44 for ; Fri, 7 Aug 2026 03:31:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786073503; cv=none; b=H4N17cLyagCFxjZ/vH+VghB++qmUIDOi71ZlBVq7rB+KeOGBWYqcNeCatY9C8p9eW0cvSBtiQQOxJgDB0+LGqN4v67Hus/cHIujgbsaw10hw9wa77HLzTCxOCW5oYqZ7EattPMZnEOswenSwDBZPPE02mLwm/eEKnhdjgxV4/B0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786073503; c=relaxed/simple; bh=AUCj77nd839IO1AtSrGW53q3BaVZ2JW4ivhVLiYeOrg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CiJYjJUdW+fF9UoEhCkOlUkk7VmYuKJKAMjJGPzvnRlS9fk624y9usbcv+GQ8KTdHBDpn9cjChuMBJr8ZulWI7OMkFDkbpuFn9U/b0PnaUJ5y5Q5AfbKOfsvPMrofnIJB9pv4Wxv+b27TmUmWLLaLtggM7MebX5v+BkL8F+uE5c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: 7bdf7e04921011f1aa26b74ffac11d73-20260807 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.12,REQID:f61ed87a-0635-4b1b-a825-fb1b5a117086,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:e7bac3a,CLOUDID:f03fcac0b6e1544fac7e5a23d12f90c7,BulkI D:nil,BulkQuantity:0,Recheck:0,SF:81|82|102|865|898,TC:nil,Content:0|15|50 ,EDM:-3,IP:nil,URL:0,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,O SA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 7bdf7e04921011f1aa26b74ffac11d73-20260807 X-User: liuxixin@kylinos.cn Received: from [127.0.1.1] [(10.44.16.150)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA with TLSv1.3 TLS_AES_256_GCM_SHA384 256/256) with ESMTP id 132895520; Fri, 07 Aug 2026 11:31:32 +0800 From: Xixin Liu 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 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Mailer: patches/scripts/send-local.py 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 --- 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