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!
Created a pull request on GitHub: https://github.com/torvalds/linux/pull/576
We have sent the patch to the developers. Currently, we're formatting the patch according to the Linux development documentation.