Skip to content

Comparison conditionals crash pipelines opaquely when field on event is not correct value type #16007

@yaauie

Description

@yaauie

Logstash information:

Please include the following information:

  1. Logstash version: main, 8.x, 7.x`
  2. Logstash installation source: any
  3. How is Logstash being run: any

Plugins installed: default

JVM (e.g. java -version): any

OS version (uname -a if on a Unix-like system): any

Description of the problem including expected versus actual behavior:

When a field reference is provided as a value-source in a conditional clause with a comparator operator (e.g., >, >=, <=, <), and the conditional encounters an event whose value at that field reference is not comparable to the constant-value on the other side of that comparator, the conditional crashes opaquely, propagating up to crash the pipeline.

Steps to reproduce:

input { stdin { codec => json_lines } }

filter {
  if [path][to][value] > 100 {
    mutate { add_tag => "hit" }
  } else {
    mutate { add_tag => "miss" }
  }
}

output { stdout { codec => json_lines } }

any of the following inputs will crash the pipeline, some with more-opaque messages than others:

  • String value in field
    {"path":{"to":{"value":"101"}}}
    {"path":{"to":{"value":"string"}}}
    [2024-03-13T17:40:53,216][ERROR][logstash.javapipeline    ][main][[main]>worker0] Pipeline worker error, the pipeline will be stopped {:pipeline_id=>"main", :error=>"(TypeError) no implicit conversion of nil into Integer", :exception=>Java::OrgJrubyExceptions::TypeError, :backtrace=>["RUBY.start_workers(${LOGSTASH_HOME}/logstash-core/lib/logstash/java_pipeline.rb:304)"], :thread=>"#<Thread:0x61e445ff ${LOGSTASH_HOME}/logstash-core/lib/logstash/java_pipeline.rb:134 sleep>"}
    
  • Array value in field
    {"path":{"to":{"value":[101]}}}
    {"path":{"to":{"value":["101"]}}}
    {"path":{"to":{"value":[101, 102]}}}
    [2024-03-13T17:42:26,296][ERROR][logstash.javapipeline    ][main][[main]>worker0] Pipeline worker error, the pipeline will be stopped {:pipeline_id=>"main", :error=>"Unexpected input type combination left class org.logstash.ConvertedList:ConvertedList{delegate=[101]}, right class org.jruby.RubyFixnum:399", :exception=>Java::OrgLogstashConfigIrCompiler::EventCondition::Compiler::UnexpectedTypeException, :backtrace=>["org.logstash.config.ir.compiler.EventCondition$Compiler.compare(EventCondition.java:458)", "org.logstash.config.ir.compiler.EventCondition$Compiler.lambda$compareFieldToConstant$11(EventCondition.java:449)", "org.logstash.config.ir.compiler.Utils.filterEvents(Utils.java:47)", "org.logstash.generated.CompiledDataset2.compute(Unknown Source)", "org.logstash.generated.CompiledDataset3.compute(Unknown Source)", "org.logstash.generated.CompiledDataset4.compute(Unknown Source)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution._compute(CompiledPipeline.java:331)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution.compute(CompiledPipeline.java:317)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution.compute(CompiledPipeline.java:306)", "org.logstash.execution.ObservedExecution.lambda$compute$0(ObservedExecution.java:17)", "org.logstash.execution.WorkerObserver.lambda$observeExecutionComputation$0(WorkerObserver.java:39)", "org.logstash.instrument.metrics.timer.ConcurrentLiveTimerMetric.time(ConcurrentLiveTimerMetric.java:47)", "org.logstash.execution.WorkerObserver.lambda$executeWithTimers$1(WorkerObserver.java:50)", "org.logstash.instrument.metrics.timer.ConcurrentLiveTimerMetric.time(ConcurrentLiveTimerMetric.java:47)", "org.logstash.execution.WorkerObserver.executeWithTimers(WorkerObserver.java:50)", "org.logstash.execution.WorkerObserver.observeExecutionComputation(WorkerObserver.java:38)", "org.logstash.execution.ObservedExecution.compute(ObservedExecution.java:17)", "org.logstash.execution.WorkerLoop.abortableCompute(WorkerLoop.java:113)", "org.logstash.execution.WorkerLoop.run(WorkerLoop.java:86)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)", "java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)", "java.base/java.lang.reflect.Method.invoke(Method.java:566)", "org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:300)", "org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:164)", "org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:32)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:456)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:195)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:346)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:118)", "org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:136)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:66)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:58)", "org.jruby.runtime.Block.call(Block.java:144)", "org.jruby.RubyProc.call(RubyProc.java:352)", "org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:111)", "java.base/java.lang.Thread.run(Thread.java:829)"], :thread=>"#<Thread:0x11a40a8a ${LOGSTASH_HOME}/logstash-core/lib/logstash/java_pipeline.rb:134 sleep>"}
    
  • Key/Value map value in field
    {"path":{"to":{"value":{"key":101}}}}
    [2024-03-13T17:45:03,339][ERROR][logstash.javapipeline    ][main][[main]>worker0] Pipeline worker error, the pipeline will be stopped {:pipeline_id=>"main", :error=>"Unexpected input type combination left class org.logstash.ConvertedMap:{key=101}, right class org.jruby.RubyFixnum:399", :exception=>Java::OrgLogstashConfigIrCompiler::EventCondition::Compiler::UnexpectedTypeException, :backtrace=>["org.logstash.config.ir.compiler.EventCondition$Compiler.compare(EventCondition.java:458)", "org.logstash.config.ir.compiler.EventCondition$Compiler.lambda$compareFieldToConstant$11(EventCondition.java:449)", "org.logstash.config.ir.compiler.Utils.filterEvents(Utils.java:47)", "org.logstash.generated.CompiledDataset2.compute(Unknown Source)", "org.logstash.generated.CompiledDataset3.compute(Unknown Source)", "org.logstash.generated.CompiledDataset4.compute(Unknown Source)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution._compute(CompiledPipeline.java:331)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution.compute(CompiledPipeline.java:317)", "org.logstash.config.ir.CompiledPipeline$CompiledOrderedExecution.compute(CompiledPipeline.java:306)", "org.logstash.execution.ObservedExecution.lambda$compute$0(ObservedExecution.java:17)", "org.logstash.execution.WorkerObserver.lambda$observeExecutionComputation$0(WorkerObserver.java:39)", "org.logstash.instrument.metrics.timer.ConcurrentLiveTimerMetric.time(ConcurrentLiveTimerMetric.java:47)", "org.logstash.execution.WorkerObserver.lambda$executeWithTimers$1(WorkerObserver.java:50)", "org.logstash.instrument.metrics.timer.ConcurrentLiveTimerMetric.time(ConcurrentLiveTimerMetric.java:47)", "org.logstash.execution.WorkerObserver.executeWithTimers(WorkerObserver.java:50)", "org.logstash.execution.WorkerObserver.observeExecutionComputation(WorkerObserver.java:38)", "org.logstash.execution.ObservedExecution.compute(ObservedExecution.java:17)", "org.logstash.execution.WorkerLoop.abortableCompute(WorkerLoop.java:113)", "org.logstash.execution.WorkerLoop.run(WorkerLoop.java:86)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)", "java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)", "java.base/java.lang.reflect.Method.invoke(Method.java:566)", "org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:300)", "org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:164)", "org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:32)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:456)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:195)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:346)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:118)", "org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:136)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:66)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:58)", "org.jruby.runtime.Block.call(Block.java:144)", "org.jruby.RubyProc.call(RubyProc.java:352)", "org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:111)", "java.base/java.lang.Thread.run(Thread.java:829)"], :thread=>"#<Thread:0x3978ce2d ${LOGSTASH_HOME}/logstash-core/lib/logstash/java_pipeline.rb:134 sleep>"}
    

While some comparisons don't make sense to make,

  • individual events shouldn't crash pipelines
  • comparing a constant integer to a field containing a string-value-that-looks-like-an-integer should coerce the field's value

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions