From: Joe Perches joe@perches.com
mainline inclusion from mainline-v5.10-rc1 commit 7981593bf083801035b1f1377661849805acb216 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5C32F CVE: CVE-2022-20166
--------------------------------------------------
Convert the unbound sprintf in hugetlb_report_node_meminfo to use sysfs_emit_at so that no possible overrun of a PAGE_SIZE buf can occur.
Signed-off-by: Joe Perches joe@perches.com Acked-by: Mike Kravetz mike.kravetz@oracle.com Link: https://lore.kernel.org/r/894b351b82da6013cde7f36ff4b5493cd0ec30d0.160028592... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Conflicts: drivers/base/node.c include/linux/hugetlb.h
Signed-off-by: Guo Mengqi guomengqi3@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- drivers/base/node.c | 2 +- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/base/node.c b/drivers/base/node.c index 89996ae43f4f..2e5e38e7bea7 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -453,7 +453,7 @@ static ssize_t node_read_meminfo(struct device *dev, #else nid, K(node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE))); #endif - len += hugetlb_report_node_meminfo(nid, buf + len); + len += hugetlb_report_node_meminfo(buf, len, nid); return len; }
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 588f9f2a44fc..2d2b06b36bd0 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -102,7 +102,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start, unsigned long end, struct page *ref_page); void hugetlb_report_meminfo(struct seq_file *); -int hugetlb_report_node_meminfo(int, char *); +int hugetlb_report_node_meminfo(char *buf, int len, int nid); void hugetlb_show_meminfo(void); unsigned long hugetlb_total_pages(void); vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, @@ -188,7 +188,7 @@ static inline void adjust_range_if_pmd_sharing_possible( static inline void hugetlb_report_meminfo(struct seq_file *m) { } -#define hugetlb_report_node_meminfo(n, buf) 0 +#define hugetlb_report_node_meminfo(buf, len, nid) 0 static inline void hugetlb_show_meminfo(void) { } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 5b6a050fd6c1..e8ef6c62da34 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3417,18 +3417,20 @@ void hugetlb_report_meminfo(struct seq_file *m) seq_printf(m, "Hugetlb: %8lu kB\n", total / 1024); }
-int hugetlb_report_node_meminfo(int nid, char *buf) +int hugetlb_report_node_meminfo(char *buf, int len, int nid) { struct hstate *h = &default_hstate; + if (!hugepages_supported()) return 0; - return sprintf(buf, - "Node %d HugePages_Total: %5u\n" - "Node %d HugePages_Free: %5u\n" - "Node %d HugePages_Surp: %5u\n", - nid, h->nr_huge_pages_node[nid], - nid, h->free_huge_pages_node[nid], - nid, h->surplus_huge_pages_node[nid]); + + return sysfs_emit_at(buf, len, + "Node %d HugePages_Total: %5u\n" + "Node %d HugePages_Free: %5u\n" + "Node %d HugePages_Surp: %5u\n", + nid, h->nr_huge_pages_node[nid], + nid, h->free_huge_pages_node[nid], + nid, h->surplus_huge_pages_node[nid]); }
void hugetlb_show_meminfo(void)