[cfe-dev] False positive null pointer analysis

Eric Blake eblake at redhat.com
Fri Jul 30 08:26:44 PDT 2010


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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100730/0ed7d5c6/attachment.sig>


More information about the cfe-dev mailing list