Bug 200489

Summary: Potential NULL pointer dereference when kzalloc() fails
Product: Platform Specific/Hardware Reporter: Jason Wood (jasonwood2031)
Component: x86-64Assignee: platform_x86_64 (platform_x86_64)
Status: RESOLVED PATCH_ALREADY_AVAILABLE    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: v4.18-rc4 Subsystem:
Regression: No Bisected commit-id:

Description Jason Wood 2018-07-14 07:52:18 UTC
Function init_per_cpu() defined in arch/x86/platform/uv/tlb_uv.c calls kzalloc() to allocate memory for variable uvhub_mask which is used in function get_cpu_topology() and function summarize_uvhub_sockets() later. However, none of the 3 functions mentioned above checks whether uvhub_mask is NULL. As kzalloc() may return NULL, when get_cpu_topology() and summarize_uvhub_sockets() tries to dereference this pointer, it may cause NULL pointer dereference bug. Codes related to this bug are shown as follows.

arch/x86/platform/uv/tlb_uv.c:
 2146  	uvhub_descs = (struct uvhub_desc *)vp;
 2147  	memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
 2148: 	uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
 2149  
 2150  	if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask))
 2151		goto fail;
 2152
 2153	if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask))
 2154		goto fail;

---
arch/x86/platform/uv/tlb_uv.c:
 1951   /*
 1952   * Scan all cpus to collect blade and socket summaries.
 1953   */
 1954: static int __init get_cpu_topology(int base_pnode,
 1955  					struct uvhub_desc *uvhub_descs,
 1956  					unsigned char *uvhub_mask)
		// first usage of uvhub_mask
 1982		uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
 1983		*(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8));
 1984		bdp = &uvhub_descs[uvhub];

---
arch/x86/platform/uv/tlb_uv.c:
 2095   /*
 2096   * Summarize the blade and socket topology into the per_cpu structures.
 2097   */
 2098: static int __init summarize_uvhub_sockets(int nuvhubs,
 2099  			struct uvhub_desc *uvhub_descs,
 2100  			unsigned char *uvhub_mask)
		// first usage of uvhub_mask
 2111		if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
 2112			continue;

Thanks for attention!
Comment 1 Jason Wood 2018-08-06 07:13:28 UTC
Created a pull request on GitHub: https://github.com/torvalds/linux/pull/576
Comment 2 Jason Wood 2018-09-13 10:35:10 UTC
We have sent the patch to the developers. Currently, we're formatting the patch according to the Linux development documentation.