CVE-2021-37625 (published 2021-08-05T18:15Z)

Skytable is an open source NoSQL database. In versions prior to 0.6.4 an incorrect check of return value of the accept function in the run-loop for a TCP socket/TLS socket/TCP+TLS multi-socket causes an early exit from the run loop that should continue infinitely unless terminated by a local user, effectively causing the whole database server to shut down. This has severe impact and can be used to easily cause DoS attacks without the need to use much bandwidth. The attack vectors include using an incomplete TLS connection for example by not providing the certificate for the connection and using a specially crafted TCP packet that triggers the application layer backoff algorithm.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-252
cwe_name: Unchecked Return Value
description: The product does not check the return value from a method or function, which can prevent it from detecting unexpected states and conditions.
extended_description: Two common programmer assumptions are "this function call can never fail" and "it doesn't matter if this function call fails". If an attacker can force the function to fail or otherwise return a value that is not expected, then the subsequent program logic could lead to a vulnerability, because the product is not in a state that the programmer assumes. For example, if the program calls a function to drop privileges but does not check the return code to ensure that privileges were successfully dropped, then the program will continue to operate with the higher privileges.
         

Fix information:
repo_url: https://github.com/skytable/skytable
commit_details: repo_url: https://github.com/skytable/skytable
author: Sayan Nandan
author_date: 2021-08-05 02:52:16-07:00
msg: Ignore errors in run loop

This fixes CVE-2021-37625
repository: repo_url: https://github.com/skytable/skytable
repo_name: skytable/skytable
description: Skytable is a modern scalable NoSQL database with BlueQL, designed for performance, scalability and flexibility. Skytable gives you spaces, models, data types, complex collections and more to build powerful experiences
repo_language: Rust
owner: skytable
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -116,6 +116,13 @@ All changes in this project will be noted in this file.
   under the `default` keyspace
 - Fix log output in `sky-bench` even if the `--json` flag was passed
 - Use flocks to enable auto release of pid file, even if process is forcefully terminated
+- Fixes [CVE-2021-37625](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-37625)
+
+## Version 0.6.4 [2021-08-05]
+
+### Fixes
+
+- Fixes [CVE-2021-37625](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-37625) (backport)
 
 ## Version 0.6.3 [2021-06-27]
 

programming_language: Markdown
filename: macros.rs
change_type: ModificationType.ADD
diff: @@ -0,0 +1,34 @@
+/*
+ * Created on Thu Aug 05 2021
+ *
+ * This file is a part of Skytable
+ * Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
+ * NoSQL database written by Sayan Nandan ("the Author") with the
+ * vision to provide flexibility in data modelling without compromising
+ * on performance, queryability or scalability.
+ *
+ * Copyright (c) 2021, Sayan Nandan <ohsayan@outlook.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+*/
+
+macro_rules! skip_loop_err {
+    ($expr:expr) => {
+        match $expr {
+            Ok(ret) => ret,
+            Err(_) => continue,
+        }
+    };
+}

programming_language: Scala
filename: mod.rs
change_type: ModificationType.MODIFY
diff: @@ -52,6 +52,8 @@ use tokio::net::TcpListener;
 use tokio::sync::Semaphore;
 use tokio::sync::{broadcast, mpsc};
 pub mod connection;
+#[macro_use]
+mod macros;
 mod tcp;
 mod tls;
 

programming_language: Rust
filename: tcp.rs
change_type: ModificationType.MODIFY
diff: @@ -103,7 +103,15 @@ impl Listener {
             // Take the permit first, but we won't use it right now
             // that's why we will forget it
             self.base.climit.acquire().await.unwrap().forget();
-            let stream = self.accept().await?;
+            /*
+             SECURITY: Ignore any errors that may arise in the accept
+             loop. If we apply the try operator here, we will immediately
+             terminate the run loop causing the entire server to go down.
+             Also, do not log any errors because many connection errors
+             can arise and it will flood the log and might also result
+             in a crash
+            */
+            let stream = skip_loop_err!(self.accept().await);
             let mut chandle = ConnectionHandler::new(
                 self.base.db.clone(),
                 Connection::new(stream),

programming_language: Rust
filename: tls.rs
change_type: ModificationType.MODIFY
diff: @@ -114,7 +114,15 @@ impl SslListener {
             // Take the permit first, but we won't use it right now
             // that's why we will forget it
             self.base.climit.acquire().await.unwrap().forget();
-            let stream = self.accept().await?;
+            /*
+             SECURITY: Ignore any errors that may arise in the accept
+             loop. If we apply the try operator here, we will immediately
+             terminate the run loop causing the entire server to go down.
+             Also, do not log any errors because many connection errors
+             can arise and it will flood the log and might also result
+             in a crash
+            */
+            let stream = skip_loop_err!(self.accept().await);
             let mut sslhandle = ConnectionHandler::new(
                 self.base.db.clone(),
                 Connection::new(stream),
@@ -123,6 +131,7 @@ impl SslListener {
                 self.base.terminate_tx.clone(),
             );
             tokio::spawn(async move {
+                log::debug!("Spawned listener task");
                 if let Err(e) = sslhandle.run().await {
                     log::error!("Error: {}", e);
                 }

programming_language: Rust