From bb19d024ea1e5e0c9a3d75a9ee58ff03c70c7e5d Mon Sep 17 00:00:00 2001
From: Sayan Nandan <nandansayan@outlook.com>
Date: Thu, 5 Aug 2021 02:52:16 -0700
Subject: [PATCH] Ignore errors in run loop

This fixes CVE-2021-37625
---
 CHANGELOG.md               |  7 +++++++
 server/src/dbnet/macros.rs | 34 ++++++++++++++++++++++++++++++++++
 server/src/dbnet/mod.rs    |  2 ++
 server/src/dbnet/tcp.rs    | 10 +++++++++-
 server/src/dbnet/tls.rs    | 11 ++++++++++-
 5 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 server/src/dbnet/macros.rs

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07dce31..8f7f770 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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]
 
diff --git a/server/src/dbnet/macros.rs b/server/src/dbnet/macros.rs
new file mode 100644
index 0000000..64faab2
--- /dev/null
+++ b/server/src/dbnet/macros.rs
@@ -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,
+        }
+    };
+}
diff --git a/server/src/dbnet/mod.rs b/server/src/dbnet/mod.rs
index 936dee3..c15783e 100644
--- a/server/src/dbnet/mod.rs
+++ b/server/src/dbnet/mod.rs
@@ -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;
 
diff --git a/server/src/dbnet/tcp.rs b/server/src/dbnet/tcp.rs
index 59b97cb..a7b1395 100644
--- a/server/src/dbnet/tcp.rs
+++ b/server/src/dbnet/tcp.rs
@@ -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),
diff --git a/server/src/dbnet/tls.rs b/server/src/dbnet/tls.rs
index 77c6199..0727700 100644
--- a/server/src/dbnet/tls.rs
+++ b/server/src/dbnet/tls.rs
@@ -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);
                 }
