Commit 98464c11 authored by Howard Chu's avatar Howard Chu Committed by Quanah Gibson-Mount

ITS#9202 limit depth of nested filters

Using a hardcoded limit for now; no reasonable apps
should ever run into it.
parent 9ab0dfdb
...@@ -37,11 +37,16 @@ ...@@ -37,11 +37,16 @@
const Filter *slap_filter_objectClass_pres; const Filter *slap_filter_objectClass_pres;
const struct berval *slap_filterstr_objectClass_pres; const struct berval *slap_filterstr_objectClass_pres;
#ifndef SLAPD_MAX_FILTER_DEPTH
#define SLAPD_MAX_FILTER_DEPTH 5000
#endif
static int get_filter_list( static int get_filter_list(
Operation *op, Operation *op,
BerElement *ber, BerElement *ber,
Filter **f, Filter **f,
const char **text ); const char **text,
int depth );
static int get_ssa( static int get_ssa(
Operation *op, Operation *op,
...@@ -80,12 +85,13 @@ filter_destroy( void ) ...@@ -80,12 +85,13 @@ filter_destroy( void )
return; return;
} }
int static int
get_filter( get_filter0(
Operation *op, Operation *op,
BerElement *ber, BerElement *ber,
Filter **filt, Filter **filt,
const char **text ) const char **text,
int depth )
{ {
ber_tag_t tag; ber_tag_t tag;
ber_len_t len; ber_len_t len;
...@@ -126,6 +132,11 @@ get_filter( ...@@ -126,6 +132,11 @@ get_filter(
* *
*/ */
if( depth > SLAPD_MAX_FILTER_DEPTH ) {
*text = "filter nested too deeply";
return SLAPD_DISCONNECT;
}
tag = ber_peek_tag( ber, &len ); tag = ber_peek_tag( ber, &len );
if( tag == LBER_ERROR ) { if( tag == LBER_ERROR ) {
...@@ -221,7 +232,7 @@ get_filter( ...@@ -221,7 +232,7 @@ get_filter(
case LDAP_FILTER_AND: case LDAP_FILTER_AND:
Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 ); Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
err = get_filter_list( op, ber, &f.f_and, text ); err = get_filter_list( op, ber, &f.f_and, text, depth+1 );
if ( err != LDAP_SUCCESS ) { if ( err != LDAP_SUCCESS ) {
break; break;
} }
...@@ -234,7 +245,7 @@ get_filter( ...@@ -234,7 +245,7 @@ get_filter(
case LDAP_FILTER_OR: case LDAP_FILTER_OR:
Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 ); Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
err = get_filter_list( op, ber, &f.f_or, text ); err = get_filter_list( op, ber, &f.f_or, text, depth+1 );
if ( err != LDAP_SUCCESS ) { if ( err != LDAP_SUCCESS ) {
break; break;
} }
...@@ -248,7 +259,7 @@ get_filter( ...@@ -248,7 +259,7 @@ get_filter(
case LDAP_FILTER_NOT: case LDAP_FILTER_NOT:
Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 ); Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
(void) ber_skip_tag( ber, &len ); (void) ber_skip_tag( ber, &len );
err = get_filter( op, ber, &f.f_not, text ); err = get_filter0( op, ber, &f.f_not, text, depth+1 );
if ( err != LDAP_SUCCESS ) { if ( err != LDAP_SUCCESS ) {
break; break;
} }
...@@ -311,10 +322,22 @@ get_filter( ...@@ -311,10 +322,22 @@ get_filter(
return( err ); return( err );
} }
int
get_filter(
Operation *op,
BerElement *ber,
Filter **filt,
const char **text )
{
return get_filter0( op, ber, filt, text, 0 );
}
static int static int
get_filter_list( Operation *op, BerElement *ber, get_filter_list( Operation *op, BerElement *ber,
Filter **f, Filter **f,
const char **text ) const char **text,
int depth )
{ {
Filter **new; Filter **new;
int err; int err;
...@@ -328,7 +351,7 @@ get_filter_list( Operation *op, BerElement *ber, ...@@ -328,7 +351,7 @@ get_filter_list( Operation *op, BerElement *ber,
tag != LBER_DEFAULT; tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) tag = ber_next_element( ber, &len, last ) )
{ {
err = get_filter( op, ber, new, text ); err = get_filter0( op, ber, new, text, depth );
if ( err != LDAP_SUCCESS ) if ( err != LDAP_SUCCESS )
return( err ); return( err );
new = &(*new)->f_next; new = &(*new)->f_next;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment