Fix UOE on search requests that match a sparse role query (#43668)

Search requests executed through the SecurityIndexSearcherWrapper throw
an UnsupportedOperationException if they match a sparse role query.
When low level cancellation is activated (which is the default since #42857),
the context index searcher creates a weight that doesn't handle #scorer.
This change fixes this bug and adds a test to ensure that we check this case.
This commit is contained in:
Jim Ferenczi 2019-06-27 16:56:15 +02:00 committed by jimczi
parent cd4f81e15e
commit 329d05f61e
2 changed files with 11 additions and 4 deletions

View File

@ -152,13 +152,14 @@ public class ContextIndexSearcher extends IndexSearcher implements Releasable {
}
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
public boolean isCacheable(LeafReaderContext ctx) {
throw new UnsupportedOperationException();
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
throw new UnsupportedOperationException();
public Scorer scorer(LeafReaderContext context) throws IOException {
// in case the wrapped searcher (in) uses the scorer directly
return weight.scorer(context);
}
@Override

View File

@ -43,6 +43,7 @@ import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
@ -52,6 +53,7 @@ import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.aggregations.LeafBucketCollector;
import org.elasticsearch.search.internal.ContextIndexSearcher;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
import org.elasticsearch.xpack.core.security.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader;
@ -537,7 +539,11 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase {
}
DocumentSubsetDirectoryReader filteredReader = DocumentSubsetReader.wrap(reader, cache, roleQuery);
IndexSearcher searcher = new SecurityIndexSearcherWrapper.IndexSearcherWrapper(filteredReader);
IndexSearcher wrapSearcher = new SecurityIndexSearcherWrapper.IndexSearcherWrapper(filteredReader);
Engine.Searcher engineSearcher = new Engine.Searcher("test", wrapSearcher, () -> {});
ContextIndexSearcher searcher = new ContextIndexSearcher(engineSearcher,
wrapSearcher.getQueryCache(), wrapSearcher.getQueryCachingPolicy());
searcher.setCheckCancelled(() -> {});
// Searching a non-existing term will trigger a null scorer
assertEquals(0, searcher.count(new TermQuery(new Term("non_existing_field", "non_existing_value"))));