⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uno_lts.c

📁 C程序漏洞检查
💻 C
📖 第 1 页 / 共 5 页
字号:
	safe_stack = d;	return any_added;}static voiddfs_pop(void){	DfStack *d;	SymRef *r, *n;	uno_assert((int) (dfstack && safe_stack), "no dfstack or safe_stack");	for (r = dfstack->symrefs; r; r = n)	/* free stack items */	{	n = r->nxt;		r->nxt = dfs_free;		dfs_free = r;	}	for (r = dfstack->globrefs; r; r = n)	{	n = r->nxt;		r->nxt = dfs_free;		dfs_free = r;	}	d = dfstack;	dfstack = dfstack->nxt;	d->nxt = dfs_frame;			/* free stackframe */	dfs_frame = d;	for (r = safe_stack->symrefs; r; r = n)	/* free sym refs */	{	n = r->nxt;		r->nxt = dfs_free;		dfs_free = r;	}	d = safe_stack;	safe_stack = safe_stack->nxt;	d->nxt = dfs_frame;			/* free stackframe */	dfs_frame = d;}static voidglobal_var(SymList *s, treenode *n)	/* track global, default-initialized, pointers */{	leafnode *l;	int extra = 0;	if (s->mark & DECL)	{	l = leftmost(n);		extra = (s->mark & (DEF|ARRAY_DECL))? 8 : 0;		if ((s->mark & PARAM)		&&  (s->mark & USE))	/* it came from a prototype decl or an enum */			extra |= 1;	/* suppress complaints */		if  (s->mark & UNO_CONST)	/* enum constant */			extra |= 8;		/* suppress complaints about lack of def */		if (l)		{	if (l->hdr.tok == STATIC)				mark_guse(s->sm, n, 2|extra);	/* static global */			else if (l->hdr.tok == EXTRN)				mark_guse(s->sm, n, 4|extra);	/* extern global */			else				mark_guse(s->sm, n, extra);	/* normal global  */		} else			mark_guse(s->sm, n, extra);	/* global declared - see if used */		if ((s->mark & DEREF)			/* pointer */		&& !(s->mark & ARRAY_DECL))		/* not an array */		{	if (!(s->mark & DEF))		/* uninitialized */				add_glob(s->sm, n, 0);	/* an interesting global */			else				add_defs(s->sm, n);	/* def_b4_use of global ptr */		}	} else	/* not a declaration */	{		if ((s->mark & USE) && is_constant(s->sm->nme->str))			s->mark |= UNO_CONST;	/* was s->mark |= DEF; */		if ((s->mark & (USE|USEafterdef|REF0|REF1))		||  (s->mark & DEREF))		{	mark_guse(s->sm, n, 1);		/* at least one USE */			add_gstack(s->sm, n, USE);	/* global used in this procedure */		}		if (s->mark & ALIAS)	/* address taken - def could happen via ptr */		{	mark_guse(s->sm, n, 32);	/* flag to void global checks on this var */			add_gstack(s->sm, n, ALIAS);	/* mark it as aliased */		}		if ((s->mark & (DEF|UNO_CONST)) && !(s->mark & DEREF))		{	mark_guse(s->sm, n, 8);		/* at least one DEF */			add_gstack(s->sm, n, DEF);	/* global set in this procedure */		}		if (on_glob(s->sm)	/* of interest: an uninitialized global ptr */		&& !on_safe(s->sm))	/* not already declared moot on this path */		{	if (((s->mark & (DEF|UNO_CONST))	/* defined */			&& !(s->mark & REF0)			&& !(s->mark & DEREF))			||   (s->mark & ALIAS))		/* or address taken */			{	add_defs(s->sm, n);	/* record def of global ptr */				add_safe(s->sm, n);	/* moot in remainder of path */			}			if (s->mark & USE)		/* direct use */			{				if (checkpathcond(s->sm, n, 1))	/* unless value known */					add_uses(s->sm, n);	/* use_b4_def in fct */			}			if ((s->mark & REF0)		/* ref0->x */			|| ((s->mark & DEREF) && (s->mark & (USE|DEF|FCALL))))	/* ptr deref */			{				if (checkpathcond(s->sm, n, 2))	/* unless known value */					add_derefs(s->sm, n);	/* use_b4_def in fct */				else if (0) printf("check %s - %d - <%s>\n",					s->sm->nme->str,					checkpathcond(s->sm, n, 3),					x_stmnt(n));	}	}	}}static voidlocal_var(SymList *s, treenode *n)	/* track local, uninitialized non-array objects */{	leafnode *l;	if (s->mark & DECL)			/* declaration */	{	l = leftmost(n);		if (l && l->hdr.tok == EXTRN)	/* extern declared locally */		{	s->sm->decl_level = FILE_SCOPE;	/* fix */			global_var(s, n);	/* global in disguise */			return;		}		if (!(s->mark & (USE | USEafterdef)))		{	add_locs(s->sm, n);	/* check if this local can remain un-used */			if (s->mark & PARAM)				mark_locs(s->sm, n, PARAM|(s->mark&FCALL));			if (s->mark & DEREF)			/* it's a local pointer variable */				mark_locs(s->sm, n, DEREF);	/* remember that */		}		if ((!l || l->hdr.tok != STATIC || (s->mark & DEREF))	/* not static, unless ptr */		&&  !(s->mark & DEF)		/* not initialized in decl */		&&  !(s->mark & ARRAY_DECL)	/* arraynames are initialized ptrs */		&&  !(s->mark & USEafterdef))	/* a USEafterdef implies a DEF */			add_stack(s->sm, n);	/* track this local */	} else	{		if (s->mark & PARAM)			mark_locs(s->sm, n, PARAM);	/* means: used in sizeof operation */		if (s->mark & ALIAS)	/* address taken - def could happen via ptr */		{	mark_locs(s->sm, n, ALIAS|(s->mark&FCALL));			del_stack(s->sm);	/* no point in keeping track */		}		if ((s->mark & (USE|USEafterdef|REF0|REF1))		||  (s->mark & DEREF))			/* deref counts as use */			mark_locs(s->sm, n, USE|(s->mark&FCALL));	/* no longer un-used */		if (n && n->hdr.tok == RETURN)		{	extern int err_path;			int x = is_local(s->sm);			x = (x & ~DEREF);			if (x != 0 && !(x&PARAM)			&& !(s->mark & DEREF|REF0)			&&  (s->mark & ALIAS)		/* taking address */			&& !has_fctcalls(n->hdr.defuse))			{	err_path++;	/* print fct args as well */				fprintf(stdout, "uno: %s:%d: fct %s, returning address of local '%s' in <%s>\n",					n->hdr.fnm, n->hdr.line,					curgraph?curgraph->fctnm:"-",					s->sm->nme->str, x_stmnt(n));				err_path--;				if (debug || Verbose) {				fprintf(stdout, "s\t"); dflow_mark(stdout, s->mark); fprintf(stdout, "\n");				fprintf(stdout, "x\t"); dflow_mark(stdout, x); fprintf(stdout, "\n");				fprintf(stdout, "d\t"); dump_defuse(n->hdr.defuse, stdout); fprintf(stdout, "\n");				}			}	/* should also complain about basnames of arrays */		}	}	if (on_stack(s->sm))				/* seen local decl */	{	if (!(s->mark & USEafterdef)		&&  (((s->mark & (USE|REF0))		||   ((s->mark & DEREF) && !(s->mark & DECL)))))		{	mark_locs(s->sm, n, USEbeforedef|(s->mark&FCALL));			del_stack(s->sm);		} else if (s->mark & (DEF|UNO_CONST))		{	mark_locs(s->sm, n, DEF|(s->mark&FCALL));	/* def before use */			del_stack(s->sm);	}	}}static voidana_work(DefUse *d, SymList *s, treenode *n){	if (debug)	{	printf("\tanawork: %s: ", s->sm->nme->str);		dump_defuse(d, stdout);		printf("\n");	}	if (0)	{	printf("%s:%d: %s here: %d <<%s>>\t<%u>\n\t",		n->hdr.fnm, n->hdr.line, s->sm->nme->str, s->mark, x_stmnt(n), s->sm);		dump_defuse(d, stdout);		printf("\n");	}	if (uno_ignore(s->sm)		/* symbol declared in "/usr/include/*" */	||  (s->mark & REF2))		/* x->ref2 or x.ref2 -- compounds not yet   */		return;	if (uno == 4)	/* -local */		uno_bounds(s, d->aio, n);	/* array bounds */	if (s->mark & FCALL)	{	if (debug) printf("anawork->add_fcall\n");		add_fcall(s->sm, n, (s->mark&USE)?USE:DEF);#if 1		/* collect all places where a fct is called thru a ptr */		/* and remember in which fct this happens... */		if (s->mark & DEREF)		{	Gst *g;			if (Verbose)				printf("%s:%d fct %s calls another fct via a ptr: %s...\n",				n->hdr.fnm, n->hdr.line, curgraph->fctnm, s->sm->nme->str);			g = (Gst *) emalloc(sizeof(Gst));			g->gnm = curgraph;			g->nxt = grst;			grst = g;		}#endif		return;	} else		if (debug) printf("\tnot a fcall...\n");	if (s->sm->decl_level < FUNCTION_SCOPE)		global_var(s, n);	else		local_var(s, n);}static voidana_reversed(DefUse *d, SymList *s, treenode *n){	if (!s)	return;	ana_reversed(d, s->nxt, n);	ana_work(d, s, n);	/* last entry checked first */}static voidana_defuse(treenode *n){	DefUse *d;	SymList *e;	if (!n) return;	if (n->hdr.type == TN_IF)	{	d = ((if_node *)n)->cond->hdr.defuse;		if (lintlike && d)		{	if (has_node_type(((if_node *)n)->cond, TN_ASSIGN)			&& !v_reported(n))				fprintf(stdout, "uno: warning, %s:%d: assignment in condition <%s>\n",					n->hdr.fnm, n->hdr.line, x_stmnt(((if_node *)n)->cond));			else			for (e = d->other; e; e = e->nxt)			if ((e->mark & DEF)			&&  !(e->mark & UNO_CONST)			&&  !v_reported(n))				fprintf(stdout, "uno: warning, %s:%d: condition has side effect on '%s'\n",					n->hdr.fnm, n->hdr.line, e->sm->nme->str);		}	} else		d = n->hdr.defuse;	if (debug && d)	{	printf("uno: ==> ");		dump_defuse(d, stdout);		printf("\n");	}	if (d) ana_reversed(d, d->other, n);}static PathCond *getpathframe(void){	PathCond *np;	if (pathfree)	{	np = pathfree;		pathfree = pathfree->nxt;	} else		np = (PathCond *) emalloc(sizeof(PathCond));	return np;}static voidnewpathcond(treenode *exp, treenode *val){	PathCond *np;	if (debug) printf("New Pathcondition <%s>\n", x_stmnt(exp));	np = getpathframe();	np->exp = exp;	np->val = val;	np->nxt = pathcond;	pathcond = np;}static voidprevpathcond(void){	PathCond *np;	np = pathcond;	pathcond = pathcond->nxt;	/* uno cannot exclude nill-deref here */	np->nxt = pathfree;	pathfree = np;}static inthas_symbol(symentry_t *s, treenode *n){	if (!n) return 0;	if (n->syment == s)		return 1;	if (n->hdr.which == LEAF_T)		return 0;	return has_symbol(s, n->lnode) || has_symbol(s, n->rnode);}intinfeasible(treenode *e, treenode *v){	int w;	char *s;	if (!e || !v) return 0;	if (e->hdr.type == TN_INT	&&  v->hdr.tok  == IDENT)	{	w = ((leafnode *)e)->data.ival;		/* could use const_expr evaluator here */		s = ((leafnode *)v)->data.sval->str;		if ((w != 0 && strcmp(s, "_false_") == 0)		||  (w == 0 && strcmp(s,  "_true_") == 0))			return 1;	}	return 0;}static intis_zero_val(treenode *n){	if (!n) return 0;	if (n->hdr.type == TN_CAST)		return is_zero_val(n->rnode);	return (n->hdr.type == TN_INT		&&  ((leafnode *)n)->data.ival == 0);}static intsimple_zero(symentry_t *s, treenode *ex){	if (!ex) return 0;	if (debug)	printf("SZ %s, %s <%s>\n", s->nme->str, name_of_node(ex->hdr.type), x_stmnt(ex));	if (ex->hdr.type == TN_IDENT	&&  ex->syment == s)		return 0;	/* s */	if (ex->hdr.type != TN_EXPR)		return 0;	if (ex->hdr.tok == AND)		return simple_zero(s, ex->lnode)		||     simple_zero(s, ex->rnode);	if (ex->hdr.tok == OR)		return simple_zero(s, ex->lnode)		&&     simple_zero(s, ex->rnode);	if (ex->hdr.tok == NOT	&&  ex->lnode == ZT	&&  ex->rnode->hdr.type == TN_IDENT	&&  ex->rnode->syment == s)		return 1;	/* !s */	if (ex->hdr.tok == NOT	&&  ex->lnode == ZT	&&  ex->rnode->hdr.type == TN_EXPR	&&  ex->rnode->hdr.tok == NOT_EQ	&&  ex->rnode->lnode->hdr.type == TN_IDENT	&&  ex->rnode->lnode->syment == s	&&  is_zero_val(ex->rnode->rnode))		return 1;	/* !(s != 0) */	if (ex->hdr.tok == EQUAL	&&  ex->lnode->hdr.type == TN_IDENT	&&  ex->lnode->syment == s	&&  is_zero_val(ex->rnode))		return 1;	/* (s == 0) */	return 0;}static intsimple_nonzero(symentry_t *s, treenode *ex){	if (!ex) return 0;	if (debug)	printf("SNZ %s, %s <%s>\n", s->nme->str, name_of_node(ex->hdr.type), x_stmnt(ex));	if (ex->hdr.type == TN_IDENT	&&  ex->syment == s)	{	if (debug) printf("	s -- pattern matches\n");		return 1;	/* s */	}	if (ex->hdr.type != TN_EXPR)		return 0;	if (ex->hdr.tok == AND)		return simple_nonzero(s, ex->lnode)		||     simple_nonzero(s, ex->rnode);	if (ex->hdr.tok == OR)		return simple_nonzero(s, ex->lnode)		&&     simple_nonzero(s, ex->rnode);	if (ex->hdr.tok == NOT	&&  ex->lnode == ZT	&&  ex->rnode->hdr.type == TN_EXPR	&&  ex->rnode->hdr.tok == EQUAL	&&  ex->rnode->lnode->hdr.type == TN_IDENT	&&  ex->rnode->lnode->syment == s	&&  is_zero_val(ex->rnode->rnode))	{	if (debug) printf("	!(s == 0) -- pattern matches\n");		return 1;	/* !(s == 0) */	}	if (ex->hdr.tok == NOT_EQ	&&  ex->lnode->hdr.type == TN_IDENT	&&  ex->lnode->syment == s	&&  is_zero_val(ex->rnode))	{	if (debug) printf("	(s != 0) -- pattern matches\n");		return 1;	/* (s != 0) */	}	if (debug) printf("	nonoftheabove (%d %u)\n", ex->hdr.tok, ex->lnode);	return 0;}static intsimple_form(symentry_t *s, PathCond *np)	/* can we deduce that s is nonzero from np */{	treenode *ex = np->exp;	if (!((leafnode *)np->val)->data.sval) return 0;	if (debug) printf("\t\tsimpleform: %s\n", ((leafnode *)np->val)->data.sval->str);	if (strcmp(((leafnode *)np->val)->data.sval->str, "_true_") == 0)		return simple_nonzero(s, ex);	if (strcmp(((leafnode *)np->val)->data.sval->str, "_false_") == 0)		return simple_zero(s, ex);	return 0;}static intcheckpathcond(symentry_t *s, treenode *n, int callpt){	PathCond *np;	if (debug) printf("%s:%d, CPC: symbol %s %s -- callpt %d\n",		n->hdr.fnm, n->hdr.line, s->nme->str,		name_of_node(n->hdr.type), callpt);	if (n	&&  n->hdr.type == TN_IF	/* current statement is conditional */	&&  simple_nonzero(s, ((if_node *)n)->cond))	{	if (debug)		printf("CPC: symbol %s in cond, known nonzero <%s>\n",			s->nme->str, x_stmnt(n));		return 0;	} else	{	if (debug)		printf("CPC: not known nonzero <%s>\n", x_stmnt(n));	}	for (np = pathcond; np; np = np->nxt)	{		if (debug)		{	printf("\tcheckpathcond: val=%s exp=%s (%s)",				toksym(np->val->hdr.tok, 1),				x_stmnt(np->exp),				name_of_node(np->exp->hdr.type));			printf("\tval=%s\n", x_stmnt(np->val));		}		if (has_symbol(s, np->exp))		{	if (debug) printf("	1\n");			if (np->val->hdr.tok == IDENT			&&  simple_form(s, np))			{	if (debug) printf("	2\n");				return 0;	/* voids insertion */			}			if (debug) printf("	3\n");			continue;	/* can't tell from this condition */		}		if (has_symbol(s, np->val))		{	if (debug) printf("	4\n");			break;	/* can't tell -- and this may change the value */		}	}	if (debug) printf("	5\n");	return 1;}#if 0voiddebug_node(treenode *n, int tabs, char *p){	int i;	if (!n) return;	printf(p);	for (i = 0; i < tabs; i++)		fprintf(stdout, "   ");	printf("%s\n", name_of_node(n->hdr.type));	if (n->hdr.which == NODE_T)	{	debug_node(n->lnode, tabs+1, "L");		debug_node(n->rnode, tabs+1, "R");	}}static voidputpathcond(symentry_t *s){	PathCond *np;	for (np = pathcond; np; np = np->nxt)	{		fprintf(stderr, "checkpathcond: val=%s exp=%s %s  ==  ",			toksym(np->val->hdr.tok, 1),			name_of_node(np->exp->hdr.type),			x_stmnt(np->exp));		fprintf(stderr, "%s\n", x_stmnt(np->val));		if (has_symbol(s, np->exp))		{	fprintf(stderr, "	1\n");			if (np->val->hdr.tok == IDENT			&&  simple_form(s, np))			{	fprintf(stderr, "	2\n");				return;			}			fprintf(stderr, "	3\n");			debug_node(np->exp, 0, "");			return;		}		if (has_symbol(s, np->val))		{	fprintf(stderr, "	4\n");			return;		}	}	fprintf(stderr, "	5\n");}#endifstatic voidsetknownzeros(treenode *n, Trans *t, PathCond *np){	DefUse *d;	SymList *s;	SymRef *r;	if (!n) return;	if (n->hdr.type == TN_IF)		d = ((if_node *)n)->cond->hdr.defuse;	else		d = n->hdr.defuse;	if (d)	for (s = d->other; s; s = s->nxt)		if (s->sm->decl_level < FUNCTION_SCOPE	/* global */		&&  (s->mark & USE))			if (simple_form(s->sm, np))			{	/* s known nonzero */				r = uno_getref(s->sm);				r->nxt = t->knz;				t->knz = r;			}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -