Bug 1581853 - Using database wildcard `%25` in VM queries causes exception, returns 500 to client
Summary: Using database wildcard `%25` in VM queries causes exception, returns 500 to ...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat CloudForms Management Engine
Classification: Red Hat
Component: API
Version: 5.9.0
Hardware: Unspecified
OS: Unspecified
high
medium
Target Milestone: GA
: 5.10.0
Assignee: Yuri Rudman
QA Contact: Niyaz Akhtar Ansari
URL:
Whiteboard:
Depends On:
Blocks: 1595269 1615465
TreeView+ depends on / blocked
 
Reported: 2018-05-23 19:15 UTC by Robb Manes
Modified: 2021-09-09 14:12 UTC (History)
6 users (show)

Fixed In Version: 5.10.0.11
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
: 1615465 (view as bug list)
Environment:
Last Closed: 2019-02-11 14:02:29 UTC
Category: ---
Cloudforms Team: CFME Core
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Knowledge Base (Solution) 3541071 0 None None None 2018-07-23 18:34:07 UTC

Description Robb Manes 2018-05-23 19:15:37 UTC
Description of problem:
Doing queries to the CFME API utilizing filters for sets of VM resources results in errors, specifically when `%25` is used as the database wildcard character:

Quering without quotes in the `name` portion of the query does a literal search against the filter for `testvm%` instead of `testvm*`:

[----] I, [2018-05-10T15:29:49.465988 #745:1183764]  INFO -- : Started GET "/api/vms?filter[]=name=testvm%25" for 127.0.0.1 at 2018-05-10 15:29:49 -0400
[----] I, [2018-05-10T15:29:50.887608 #745:1183764]  INFO -- : Processing by Api::VmsController#index as JSON
[----] I, [2018-05-10T15:29:50.887708 #745:1183764]  INFO -- :   Parameters: {"filter"=>["name=testvm%"]}
[----] I, [2018-05-10T15:29:51.235563 #745:1183764]  INFO -- : Completed 200 OK in 348ms (Views: 0.4ms | ActiveRecord: 58.0ms)

If quotes are used, like in the example at https://access.redhat.com/documentation/en-us/red_hat_cloudforms/4.5/html-single/red_hat_cloudforms_rest_api/index#filtering then we except causing a 500 to the client (still looking for literal `testvm%` it seems as well):

[----] I, [2018-05-10T15:30:00.748901 #754:11a7e34]  INFO -- : Started GET "/api/vms?filter[]=name='testvm%25'" for 127.0.0.1 at 2018-05-10 15:30:00 -0400
[----] I, [2018-05-10T15:30:02.167746 #754:11a7e34]  INFO -- : Processing by Api::VmsController#index as JSON
[----] I, [2018-05-10T15:30:02.167832 #754:11a7e34]  INFO -- :   Parameters: {"filter"=>["name='testvm%'"]}
[----] I, [2018-05-10T15:30:06.737824 #754:11a7e34]  INFO -- : Completed 500 Internal Server Error in 4570ms (ActiveRecord: 180.4ms)
[----] F, [2018-05-10T15:30:06.738415 #754:11a7e34] FATAL -- :
[----] F, [2018-05-10T15:30:06.738467 #754:11a7e34] FATAL -- : LoadError (Unable to autoload constant VM, expected /var/www/miq/vmdb/app/models/vm.rb to define it):
[----] F, [2018-05-10T15:30:06.738503 #754:11a7e34] FATAL -- :
[----] F, [2018-05-10T15:30:06.738563 #754:11a7e34] FATAL -- : activesupport (5.0.3) lib/active_support/dependencies.rb:512:in `load_missing_constant'
activesupport (5.0.3) lib/active_support/dependencies.rb:203:in `const_missing'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:268:in `const_get'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:268:in `block in constantize'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:266:in `each'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:266:in `inject'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:266:in `constantize'
activesupport (5.0.3) lib/active_support/inflector/methods.rb:311:in `safe_constantize'
activesupport (5.0.3) lib/active_support/core_ext/string/inflections.rb:77:in `safe_constantize'
lib/miq_expression/field.rb:25:in `is_field?'
lib/miq_expression.rb:998:in `quote'
app/models/condition.rb:123:in `_subst'
app/models/condition.rb:103:in `block in subst'
app/models/condition.rb:103:in `gsub!'
app/models/condition.rb:103:in `subst'
app/models/condition.rb:86:in `subst_matches?'
lib/miq_expression.rb:826:in `lenient_evaluate'
lib/rbac/filterer.rb:637:in `matches_search_filters?'
lib/rbac/filterer.rb:257:in `block in search'
activerecord (5.0.3) lib/active_record/relation/delegation.rb:40:in `each'
activerecord (5.0.3) lib/active_record/relation/delegation.rb:40:in `each'
lib/rbac/filterer.rb:257:in `reject'
lib/rbac/filterer.rb:257:in `search'
lib/rbac/filterer.rb:124:in `search'
lib/rbac.rb:3:in `search'
lib/rbac/filterer.rb:298:in `filtered'
lib/rbac/filterer.rb:128:in `filtered'
lib/rbac.rb:11:in `filtered'
app/controllers/api/base_controller/renderer.rb:165:in `collection_search'
app/controllers/api/base_controller/generic.rb:10:in `index'
actionpack (5.0.3) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.3) lib/abstract_controller/base.rb:188:in `process_action'
actionpack (5.0.3) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.3) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (5.0.3) lib/active_support/callbacks.rb:126:in `call'
activesupport (5.0.3) lib/active_support/callbacks.rb:506:in `block (2 levels) in compile'
activesupport (5.0.3) lib/active_support/callbacks.rb:455:in `call'
activesupport (5.0.3) lib/active_support/callbacks.rb:101:in `__run_callbacks__'
activesupport (5.0.3) lib/active_support/callbacks.rb:750:in `_run_process_action_callbacks'
activesupport (5.0.3) lib/active_support/callbacks.rb:90:in `run_callbacks'
actionpack (5.0.3) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.0.3) lib/action_controller/metal/rescue.rb:20:in `process_action'
actionpack (5.0.3) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.0.3) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (5.0.3) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.0.3) lib/active_support/notifications.rb:164:in `instrument'
actionpack (5.0.3) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.0.3) lib/action_controller/metal/params_wrapper.rb:248:in `process_action'
activerecord (5.0.3) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (5.0.3) lib/abstract_controller/base.rb:126:in `process'
actionview (5.0.3) lib/action_view/rendering.rb:30:in `process'
- - - - - 8< - - - - - 

The exception occurs as part of MiqExpression, method `.quote`:

class Condition < ApplicationRecord
  include UuidMixin
- - - - - 8< - - - - - 
  def self._subst(rec, opts, tag, mode)
    ohash, ref, _object = options2hash(opts, rec)

    case mode.downcase
    when "exist"
      ref.nil? ? value = false : value = ref.is_tagged_with?(tag, :ns => "*")
    when "value"
      if ref.kind_of?(Hash)
        value = ref.fetch(tag, "")
      else
        value = ref.nil? ? "" : Tag.list(ref, :ns => tag)
      end
      value = MiqExpression.quote(value, ohash[:type] || "string")
- - - - - 8< - - - - - 

As mentioned, I can't seem to reproduce this on a similar appliance.

Version-Release number of selected component (if applicable):
Occurs in one specific 5.8.3.5 environment - but not in another similar environment.  This leads me to believe something is wrong concerning data consistency, db entries, etc.

How reproducible:
In one specific environment, every time - in an environment with the same version, not at all.

Steps to Reproduce:
1. Attempt to query a VM using a database wildcard.
2. Watch it fail.

Actual results:
Attempting to use database wildcard causes an exception, or doesn't utilize the wildcard.

Expected results:
Database wildcard should A) work and be included in the query B) not except and traceback.

Comment 9 Yuri Rudman 2018-06-21 10:17:29 UTC
I've re-created "Internal Server Error" on latest 5.9.

------------------------------------------------------------------------
F, [2018-06-21T12:00:59.722924 #24106] FATAL -- : SyntaxError ((eval):1: syntax error, unexpected '<'
<value ref=lan, type=string>/virtual/sw</value> =~ /\Abwoolf.*\z/
 ^
(eval):1: unknown regexp option - w
(eval):1: syntax error, unexpected $undefined, expecting end-of-input
<value ref=lan, type=string>/virtual/sw</value> =~ /\Abwoolf.*\z/
                                                     ^):
F, [2018-06-21T12:00:59.722991 #24106] FATAL -- :   
F, [2018-06-21T12:00:59.723074 #24106] FATAL -- : (eval):1: syntax error, unexpected '<'
<value ref=lan, type=string>/virtual/sw</value> =~ /\Abwoolf.*\z/
 ^
(eval):1: unknown regexp option - w
(eval):1: syntax error, unexpected $undefined, expecting end-of-input
<value ref=lan, type=string>/virtual/sw</value> =~ /\Abwoolf.*\z/
                                                     ^
app/models/condition.rb:89:in `eval'
app/models/condition.rb:89:in `do_eval'
app/models/condition.rb:85:in `subst_matches?'
lib/miq_expression.rb:491:in `lenient_evaluate'
---------------------------------------------------------------------------


Error raised in different place than originally reported, but has the same root as in https://bugzilla.redhat.com/show_bug.cgi?id=1522846:
If string representing virtual machine name follow special pattern (starting with capital letter and having '-' in the middle) than MiqExpression engine trying to evaluate this string as field.

This PR https://github.com/ManageIQ/manageiq/pull/16608 only fixed cases when string before "-" does not match any existing model. 

Looking at attached log, looks like there is vm named "Lan-sw" which cause error since have "Lan" model. To resolve issue without code change - rename vm to something  like "lan-sw" or "Lan_sw"

Comment 12 CFME Bot 2018-08-09 13:41:30 UTC
New commit detected on ManageIQ/manageiq/master:

https://github.com/ManageIQ/manageiq/commit/4dc6d1892f93494e46e429b3c5d67c1ce95cb5ce
commit 4dc6d1892f93494e46e429b3c5d67c1ce95cb5ce
Author:     Keenan Brock <keenan>
AuthorDate: Fri Aug  3 16:48:23 2018 -0400
Commit:     Keenan Brock <keenan>
CommitDate: Fri Aug  3 16:48:23 2018 -0400

    New and improved Field.is_field?()

    Fixes issue when MiqExpression engine is a regular expression
    and the field looks like "Model-field" but the attribute doesn't exist

    Example: if there is vm named "Lan-yuri" than this expression
    Virtual Machine : Name REGULAR EXPRESSION MATCHES "L+" triggers error

    https://bugzilla.redhat.com/show_bug.cgi?id=1581853
 lib/miq_expression/field.rb | 15 +-
 lib/miq_expression/target.rb | 7 +-
 spec/lib/miq_expression/field_spec.rb | 6 +-
 3 files changed, 14 insertions(+), 14 deletions(-)

Comment 14 Niyaz Akhtar Ansari 2018-10-03 14:43:14 UTC
It works fine with no error.
Verified in Version 5.10.0.17.20180927011235_1b5cf54


Note You need to log in before you can comment on or make changes to this bug.