[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: sprintf segv in ldapsearch (ITS#274)



Hi Kurt,


I see that you avoid sprintf if filtpatt is NULL.  However, you're
still vulnerable to sprintf % escapes if it isn't.

    ldapsearch -f file attr='*%f %s*'

will try to cast the arg as a float, then put random stack data at
%s.  Yikes!  How about doing %s by hand?  Here is some clunky and
untested code:

    char *p, *q, *end;

    end = filter + FILTER_BUF_SIZE;
    for(p=filter, q=filtpat; p<end && *q; ) {
	if( *q == '%' ) {
	    q++;
	    if( *q == 0 ) {
		/* a % at end of string?  just copy it and quit */
		*p++ = '%';
		break;
	    }
	    else if( *q == 's' ) {
		/* insert value at %s */
		strncpy(p, value, end-p);
		p += strlen(p);
	    } 
	    else if( *q == '%' ) {
		/* map %% to % */
		*p++ = *q++;
	    }
	    else {
		/* unrecognized %x.  copy it verbatim */
		*p++ = '%';
		*p++ = *q++;
	    }
	}
	else {
	    *p++ = *q++;
	}
    }
    if( p>=end ) { p = end-1; }
    *p++ = 0;

--Noel

> 
> Thanks,  I applied a fix to OPENLDAP_REL_ENG_1_2.  Please test.
> 
> At 11:43 PM 8/25/99 GMT, you wrote:
> >
> >Try this for a segfault:
> >
> >    ldapsearch 'any_attr=%1000000s'
> >
> >It comes from passing the search filter directly to sprintf at line
> >354 of ldapsearch.c:
> >
> >    static int dosearch(
> >	    LDAP    *ld,
> >	char        *base,
> >	int         scope,
> >	char        **attrs,
> >	int         attrsonly,
> >	char        *filtpatt,
> >	char        *value)
> >    {
> >	char                filter[ BUFSIZ ];
> >	int                 rc, first, matches;
> >	LDAPMessage         *res, *e;
> >
> >	sprintf( filter, filtpatt, value );
> >
> >	...
> >
> >Now, few people are going to type in the search filter above, but I
> >did run into problems searching for values which contained a '%'
> >char.  The man page states:
> >
> >       -f file
> >              Read a series of lines from  file,  performing  one
> >              LDAP  search for each line.  In this case, the fil-
> >              ter given on the command line is treated as a  pat-
> >              tern  where  the first occurrence of %s is replaced
> >              with a line from file.  If file is a single - char-
> >              acter, then the lines are read from standard input.
> >
> >I would interpret that to mean that if the -f flag is not set, then
> >'%' should not be interpreted by sprintf.
> >
> >--Noel
> >
> >
> >
> >
> >
>