2.b) The `-c` Daemon Command Line Parameter Allows for Arbitrary File Existence Tests (CVE-2022-27814)
------------------------------------------------------------------------------------------------------
Example exploitation:
$ pkexec /usr/bin/swhkd -d -c /root/.somefile
[2022-03-22T12:32:25Z ERROR swhkd] "/root/.somefile" doesn't exist
$ pkexec /usr/bin/swhkd -d -c /root/.bash_history
[...] (daemon starts "normal" operation)
2.c) The `-c` Daemon Command Line Parameter Allows to Parse Arbitrary Files (CVE-2022-27819)
--------------------------------------------------------------------------------------------
The file passed to `swhkd` via `-c` will be completely read in by
`swhkd`. Any privileged file can thus also be processed. The daemon only
outputs the contents if something that looks like a hotkey definition is
found in the file, however. Since this syntax is pretty complex the
involved information leak is rather hard to exploit. Something like
$ pkexec /usr/bin/swhkd -d -c /dev/sda
causes the daemon to "parse" the complete block device, exhausting
memory and causing high I/O load.
I've made two functions drop_privileges and raise_privileges that manipulate the program's initgroups, uid and gid. All three are necessary to modify the program's privileges. Functions relating to permissions are in the new perms.rs module.
daemon.rs now calls these two functions, so the machine will deny the config parser access to any files/directories the invoking non-root user doesn't have access to.
pub fn drop_privileges(user_uid: u32) {
let user_uid = Uid::from_raw(user_uid);
let user = User::from_uid(user_uid).unwrap().unwrap();
set_initgroups(&user, user_uid.as_raw());
set_egid(user_uid.as_raw());
set_euid(user_uid.as_raw());
}
pub fn raise_privileges(resgid: ResGid, resuid: ResUid) {
let root_user = User::from_uid(resuid.real).unwrap().unwrap();
let resgid = resgid.effective.as_raw();
let resuid = resuid.effective.as_raw();
set_egid(resgid);
set_euid(resuid);
set_initgroups(&root_user, resgid);
}
Descriptions of the two CVEs (source):
I've made two functions
drop_privileges
andraise_privileges
that manipulate the program'sinitgroups
,uid
andgid
. All three are necessary to modify the program's privileges. Functions relating to permissions are in the newperms.rs
module.daemon.rs
now calls these two functions, so the machine will deny the config parser access to any files/directories the invoking non-root user doesn't have access to.