CVE-2022-27819: Allocation of Resources Without Limits or Throttling (CWE-770)
value: SWHKD 1.1.5 allows unsafe parsing via the -c option. An information leak might occur but there is a simple denial of service (memory exhaustion) upon an attempt to parse a large or infinite file (such as a block or character device).
CWE description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
CVSS v3 base score: 5.3
Published: 2022-04-07T02:15Z
Repository: https://github.com/waycrate/swhkd
Language: Rust
Files changed: Cargo.lock, Cargo.toml, src/daemon.rs
Commit date: 2022-03-25 20:40:47 +0530
Commit message: [patch] CVE-2022-27819

Diff: diff --git a/Cargo.lock b/Cargo.lock
index 40d77ff..b5b8e08 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -102,13 +102,13 @@ version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.2"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
+checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
 ]
 
@@ -123,26 +123,27 @@ dependencies = [
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.7"
+version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9"
+checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
 dependencies = [
+ "autocfg",
  "cfg-if",
  "crossbeam-utils",
  "lazy_static",
  "memoffset",
  "scopeguard",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
+checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
 dependencies = [
  "cfg-if",
  "lazy_static",
 ]
 
@@ -236,13 +237,13 @@ version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.119"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
+checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
 
 [[package]]
 name = "lock_api"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -251,13 +252,13 @@ dependencies = [
  "scopeguard",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.14"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
@@ -275,13 +276,13 @@ dependencies = [
  "autocfg",
 ]
 
 [[package]]
 name = "mio"
-version = "0.8.1"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8"
+checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
 dependencies = [
  "libc",
  "log",
  "miow",
  "ntapi",
@@ -383,13 +384,13 @@ dependencies = [
  "unicode-xid",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.15"
+version = "1.0.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
+checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
@@ -423,13 +424,13 @@ dependencies = [
  "num_cpus",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.11"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
+checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
@@ -508,13 +509,13 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.86"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
+checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-xid",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 582e853..9503337 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,16 +21,16 @@ exclude = [
 
 [dependencies]
 clap = "3.1.6"
 env_logger = "0.9.0"
 evdev = { version = "0.11.4", features = ["tokio"] }
+itertools = "0.10.3"
 log = "0.4.14"
 nix = "0.23.1"
-sysinfo = "0.23.5"
-itertools = "0.10.3"
 signal-hook = "0.3.13"
 signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"] }
+sysinfo = "0.23.5"
 tokio = { version = "1.17.0", features = ["full"] }
 tokio-stream = "0.1.8"
 
 [[bin]]
 name = "swhkd"
diff --git a/src/daemon.rs b/src/daemon.rs
index ff21317..251e757 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -83,10 +83,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
     if check_user_permissions().is_err() {
         exit(1);
     }
 
     let load_config = || {
+        seteuid(env::var("PKEXEC_UID").unwrap().parse::<u32>().unwrap()); // Dropping privileges to invoking user.
         let config_file_path: std::path::PathBuf = if args.is_present("config") {
             Path::new(args.value_of("config").unwrap()).to_path_buf()
         } else {
             fetch_xdg_config_path()
         };
@@ -112,11 +113,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
 
         hotkeys
     };
 
     let mut hotkeys = load_config();
-
+    seteuid(0); // Escalating back to root after reading config file.
     log::trace!("Attempting to find all keyboard file descriptors.");
     let keyboard_devices: Vec<Device> =
         evdev::enumerate().filter(check_device_is_keyboard).collect();
 
     let mut uinput_device = match uinput::create_uinput_device() {
@@ -397,5 +398,16 @@ pub fn fetch_xdg_config_path() -> std::path::PathBuf {
             Path::new("/etc/swhkd/swhkdrc").to_path_buf()
         }
     };
     config_file_path
 }
+
+pub fn seteuid(uid: u32) {
+    let uid = nix::unistd::Uid::from_raw(uid);
+    match nix::unistd::seteuid(uid) {
+        Ok(_) => log::debug!("Dropping privileges..."),
+        Err(e) => {
+            log::error!("Failed to set UID: {:#?}", e);
+            exit(1);
+        }
+    }
+}

Vulnerable code: version = "0.5.2"
checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
version = "0.9.7"
checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9"
version = "0.8.7"
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
version = "0.2.119"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
version = "0.4.14"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
version = "0.8.1"
checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8"
version = "1.0.15"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
version = "0.2.11"
checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
version = "1.0.86"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
sysinfo = "0.23.5"
itertools = "0.10.3"

Fixed code: version = "0.5.4"
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
version = "0.9.8"
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
 "autocfg",
version = "0.8.8"
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
version = "0.2.121"
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
version = "0.4.16"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
version = "0.8.2"
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
version = "1.0.16"
checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57"
version = "0.2.12"
checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0"
version = "1.0.89"
checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54"
itertools = "0.10.3"
sysinfo = "0.23.5"
        seteuid(env::var("PKEXEC_UID").unwrap().parse::<u32>().unwrap()); // Dropping privileges to invoking user.
    seteuid(0); // Escalating back to root after reading config file.

pub fn seteuid(uid: u32) {
    let uid = nix::unistd::Uid::from_raw(uid);
    match nix::unistd::seteuid(uid) {
        Ok(_) => log::debug!("Dropping privileges..."),
        Err(e) => {
            log::error!("Failed to set UID: {:#?}", e);
            exit(1);
        }
    }
}