[cfe-dev] False positive null pointer analysis

Ted Kremenek kremenek at apple.com
Fri Jul 30 08:53:51 PDT 2010


Hi Eric,

Please file a bugzilla report.  Please attach to it the HTML file for the bug report and ideally the preprocessed file (preprocessed with clang) for the source the false positive appears.  That will allow us to reproduce the false positive (which really can depend on specific nuances of the analyzed code).

Cheers,
Ted

On Jul 30, 2010, at 8:26 AM, Eric Blake wrote:

> I believe I encountered a false positive null pointer report while
> compiling the libvirt project, using clang-2.7.5-fc13.i686 bundled with
> Fedora 13 (hopefully you can decipher the plain-text rendering of the
> html report):
> 
> enum {
>    VIR_CGROUP_CONTROLLER_CPU,
>    VIR_CGROUP_CONTROLLER_CPUACCT,
>    VIR_CGROUP_CONTROLLER_CPUSET,
>    VIR_CGROUP_CONTROLLER_MEMORY,
>    VIR_CGROUP_CONTROLLER_DEVICES,
>    VIR_CGROUP_CONTROLLER_FREEZER,
> 
>    VIR_CGROUP_CONTROLLER_LAST
> };
> 
> 478	static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group,
> 479	int create, bool_Bool memory_hierarchy)
> 480	{
> 481	int i;
> 482	int rc = 0;
> 483	
> 484	VIR_DEBUG("Make group %s", group->path)virLogMessage("file."
> "../../src/util/cgroup.c", VIR_LOG_DEBUG
> , __func__, 484, 0, "Make group %s", group->path);
> 485	for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
> 	
> 1
> 	Loop condition is true. Entering loop body
> 	
> 4
> 	Loop condition is true. Entering loop body
> 	
> 7
> 	Loop condition is true. Entering loop body
> 486	char *path = NULL((void*)0);
> 487	
> 488	/* Skip over controllers that aren't mounted */
> 489	if (!group->controllers[i].mountPoint)
> 	
> 2
> 	Taking true branch
> 	
> 5
> 	Taking true branch
> 	
> 8
> 	Taking false branch
> 490	continue;
> 	
> 3
> 	Execution continues on line 485
> 	
> 6
> 	Execution continues on line 485
> 491	
> 492	rc = virCgroupPathOfController(group, i, "", &path);
> 493	if (rc < 0)
> 	
> 9
> 	Taking false branch
> 494	return rc;
> 495	
> 496	VIR_DEBUG("Make controller %s", path)virLogMessage("file."
> "../../src/util/cgroup.c", VIR_LOG_DEBUG
> , __func__, 496, 0, "Make controller %s", path);
> 497	if (access(path, F_OK0) != 0) {
> 	
> 10
> 	Taking true branch
> 498	if (!create ||
> 	
> 11
> 	Taking false branch
> 499	mkdir(path, 0755) < 0) {
> 500	rc = -errno(*__errno_location ());
> 501	VIR_FREE(path)virFree(&(path));
> 502	break;
> 503	}
> 504	if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint !=
> NULL((void*)0) &&
> 	
> 12
> 	Assuming pointer value is null
> 	
> 13
> 	Taking false branch
> 505	(i == VIR_CGROUP_CONTROLLER_CPUSET ||
> 506	STREQ(group->controllers[i].mountPoint,
> group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint)(strcmp(group->controllers[i].mountPoint,group->controllers
> [VIR_CGROUP_CONTROLLER_CPUSET].mountPoint) == 0))) {
> 507	rc = virCgroupCpuSetInherit(parent, group);
> 508	if (rc != 0) {
> 509	VIR_FREE(path)virFree(&(path));
> 510	break;
> 511	}
> 512	}
> 513	/*
> 514	* Note that virCgroupSetMemoryUseHierarchy should always be
> 515	* called prior to creating subcgroups and attaching tasks.
> 516	*/
> 517	if (memory_hierarchy &&
> 518	group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint !=
> NULL((void*)0) &&
> 519	(i == VIR_CGROUP_CONTROLLER_MEMORY ||
> 520	STREQ(group->controllers[i].mountPoint,
> group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint)(strcmp(group->controllers[i].mountPoint,group->controllers
> [VIR_CGROUP_CONTROLLER_MEMORY].mountPoint) == 0))) {
> 	
> 14
> 	Within the expansion of the macro 'STREQ':
> a
> 	Null pointer passed as an argument to a 'nonnull' parameter
> 521	rc = virCgroupSetMemoryUseHierarchy(group);
> 522	if (rc != 0) {
> 523	VIR_FREE(path)virFree(&(path));
> 524	break;
> 525	}
> 526	}
> 527	}
> 528	
> 529	VIR_FREE(path)virFree(&(path));
> 530	}
> 531	
> 532	return rc;
> 533	}
> 
> 
> But the complaint at point 14 is invalid - it is calling strcmp on
> group->controllers[i].mountPoint (guaranteed non-NULL, due to line
> 489-490 earlier in the function) and on group->controllers
> [VIR_CGROUP_CONTROLLER_MEMORY].mountPoint (guaranteed non-NULL, due to
> line 518 earlier in the conditional).
> 
> I'm thinking that the clang analyzer is getting confused when the
> iteration hits i == 3 == VIR_CGROUP_CONTROLLER_CPUSET, and failing to
> realize that the assumption of point 12 of the analysis (assuming that
> group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint is NULL) was
> already disproved at point 8; once you re-introduce a bogus assumption
> at point 12, that would explain the complaint at point 14.
> 
> -- 
> Eric Blake   eblake at redhat.com    +1-801-349-2682
> Libvirt virtualization library http://libvirt.org
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev





More information about the cfe-dev mailing list