[SERVER-10747] $where operator can block all other operations Created: 10/Sep/13  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Concurrency
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Shubhang Mani Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 1
Labels: query-44-grooming
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System(s): Ubuntu 64bit Linux, Mac OS X 10.8.4
MongoDB version(s): 2.4.5, 2.4.6
Both in standalone and replica set configuration
Drivers used: node.js - 1.2.12, python - 2.6.2


Attachments: File testcase.py     File testsetup.py    
Issue Links:
Related
is related to SERVER-5326 Restructure MMAPV1 journaling to not ... Closed
is related to SERVER-25829 Don't run killop.js in mmapv1 shardin... Closed
Assigned Teams:
Query Execution
Operating System: ALL
Steps To Reproduce:

1. Run a find query with the following filter on any collection:
{ "$where": "function() { while(true) {} }" }
2. While this is running, try running another query against the same mongo instance (both queries can be against the same or different databases), this will block until the query in 1. is terminated by the server.

Participants:

 Description   

Malicious $where clauses for eg: containing an infinite loop, can cause all other operations to hang for 1 minute (as per SERVER-3 timeout on JS execution).

While the guard functionality that terminates the JS execution works, it's unacceptable for mongo to be unresponsive to all other operations during this interval. Also, the documentation states that, as part of the JS improvements in 2.4, mongo can handle multiple JS operations concurrently.

Steps to reproduce:
1. Run a find query with the following filter on any collection:
{ "$where": "function() { while(true) {} }" }
2. While this is running, try running another query against the same mongo instance (both queries can be against the same or different databases), this will block until the query in 1. is terminated by the server.

Attached is a python script (testcase.py) that demonstrates this using the python driver.

First, run the setup script:
python testsetup.py

Then, run 1 instance of the script providing a command line argument like so:
python testcase.py hang

Concurrently run another instance of the script without a command line arg:
python testcase.py



 Comments   
Comment by Matt Kangas [ 24/Sep/13 ]

We've determined that the root cause is an interaction between locks that the journaling system takes and this javascript operation that doesn't yield. We also have determined that it is "a bad query", in the sense that a malicious user has to authenticate successfully before using this method. It is not something an unauthenticated attacker can exploit.

Comment by Angshuman Bagchi (Inactive) [ 11/Sep/13 ]

Hey Shubhang,

After reproducing this, it looks like a bug and hence I have moved this to the Core Server project where server bugs are addressed.

Regards, Angshuman

Comment by Angshuman Bagchi (Inactive) [ 10/Sep/13 ]

Hey Shubhang,

Thanks for the test scripts. I was able to replicate the issue on 2.4.5 on Mac OS X 10.8.4 and are having an internal discussion about this.

Angshuman

Generated at Thu Feb 08 03:23:57 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.