aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2025-02-22 14:31:39 +0100
committerdec05eba <dec05eba@protonmail.com>2025-02-22 14:31:39 +0100
commit8141550b47b7c364dea07c16d7e6264d0d90259c (patch)
tree09168a8155401341813c0bd4d104609138d23521
parent1b141d01b1a80387e5521886631bb54bf53aebf1 (diff)
Make sure to set file permission before capabilitiesHEADmaster
-rw-r--r--main.c121
1 files changed, 71 insertions, 50 deletions
diff --git a/main.c b/main.c
index bca38fc..8d0c1a3 100644
--- a/main.c
+++ b/main.c
@@ -5,6 +5,7 @@
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <sys/capability.h>
@@ -13,45 +14,45 @@
#define GSR_KMS_SERVER_FILEPATH "/var/lib/flatpak/app/com.dec05eba.gpu_screen_recorder/current/active/files/bin/gsr-kms-server"
#define GSR_GLOBAL_HOTKEYS_FILEPATH "/var/lib/flatpak/app/com.dec05eba.gpu_screen_recorder/current/active/files/bin/gsr-global-hotkeys"
-static int readlink_realpath(const char *filepath, char *buffer) {
+static bool readlink_realpath(const char *filepath, char *buffer) {
char symlinked_path[PATH_MAX];
ssize_t bytes_written = readlink(filepath, symlinked_path, sizeof(symlinked_path) - 1);
if(bytes_written == -1 && errno == EINVAL) {
/* Not a symlink */
strncpy(symlinked_path, filepath, sizeof(symlinked_path));
} else if(bytes_written == -1) {
- return 0;
+ return false;
} else {
symlinked_path[bytes_written] = '\0';
}
if(!realpath(symlinked_path, buffer))
- return 0;
+ return false;
- return 1;
+ return true;
}
-static int file_has_sys_admin_capability(const char *filepath) {
+static bool file_has_sys_admin_capability(const char *filepath) {
cap_t cap = cap_get_file(filepath);
if(!cap)
- return 0;
+ return false;
cap_flag_value_t res = CAP_CLEAR;
cap_get_flag(cap, CAP_SYS_ADMIN, CAP_PERMITTED, &res);
- int cap_set = res == CAP_SET;
+ bool cap_set = res == CAP_SET;
cap_free(cap);
return cap_set;
}
-static int file_set_capabilities(const char *filepath, const cap_value_t *caps_to_set, int num_caps_to_set) {
+static bool file_set_capabilities(const char *filepath, const cap_value_t *caps_to_set, int num_caps_to_set) {
cap_t cap = cap_get_file(filepath);
if(!cap && errno != ENODATA)
- return 0;
+ return false;
if(!cap) {
cap = cap_init();
if(!cap)
- return 0;
+ return false;
}
int res = 0;
@@ -63,7 +64,11 @@ static int file_set_capabilities(const char *filepath, const cap_value_t *caps_t
return res == 0;
}
-static int create_local_kms_server_proxy_directory(const char *home) {
+static bool file_set_permissions(const char *filepath, unsigned int permissions) {
+ return chmod(filepath, permissions) == 0;
+}
+
+static bool create_local_kms_server_proxy_directory(const char *home) {
char path[PATH_MAX];
int err;
@@ -73,16 +78,16 @@ static int create_local_kms_server_proxy_directory(const char *home) {
snprintf(path, sizeof(path), "%s/%s", home, path_part);
err = mkdir(path, S_IRWXU);
if(err == -1 && errno != EEXIST)
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int copy_file_atomic(const char *source_path, const char *dest_path) {
+static bool copy_file_atomic(const char *source_path, const char *dest_path) {
int in_fd = -1;
int out_fd = -1;
- int res = 0;
+ bool res = false;
char tmp_filepath[PATH_MAX];
snprintf(tmp_filepath, sizeof(tmp_filepath), "%s.tmp", dest_path);
@@ -101,7 +106,7 @@ static int copy_file_atomic(const char *source_path, const char *dest_path) {
if(sendfile(out_fd, in_fd, NULL, st.st_size) != st.st_size)
goto done;
- res = 1;
+ res = true;
done:
if(in_fd)
@@ -122,6 +127,48 @@ static void usage(void) {
exit(1);
}
+static bool set_kms_server_proxy_permissions_and_capabilities(const char *kms_server_proxy_filepath) {
+ /* owner: read/write/execute, group: read/execute, public: read/execute */
+ if(!file_set_permissions(kms_server_proxy_filepath, 0755)) {
+ fprintf(stderr, "Error: failed to set kms-server-proxy permissions\n");
+ return false;
+ }
+
+ if(!file_set_capabilities(kms_server_proxy_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP, CAP_SETUID }, 3)) {
+ fprintf(stderr, "Error: failed to set kms-server-proxy capabilities\n");
+ return false;
+ }
+
+ return true;
+}
+
+/* |gsr_global_hotkeys_local_filepath| can be NULL */
+static bool setup_local_files(const char *user_homepath, const char *kms_server_proxy_local_filepath, const char *gsr_kms_server_local_filepath, const char *gsr_global_hotkeys_local_filepath) {
+ if(!create_local_kms_server_proxy_directory(user_homepath)) {
+ fprintf(stderr, "Error: failed to create ~/.local/share/gpu-screen-recorder directory\n");
+ return false;
+ }
+
+ if(!copy_file_atomic(KMS_SERVER_PROXY_FILEPATH, kms_server_proxy_local_filepath)) {
+ fprintf(stderr, "Error: failed to copy kms-server-proxy to %s\n", kms_server_proxy_local_filepath);
+ return false;
+ }
+
+ if(!copy_file_atomic(GSR_KMS_SERVER_FILEPATH, gsr_kms_server_local_filepath)) {
+ fprintf(stderr, "Error: failed to copy gsr-kms-server to %s\n", gsr_kms_server_local_filepath);
+ return false;
+ }
+
+ if(gsr_global_hotkeys_local_filepath) {
+ if(!copy_file_atomic(GSR_GLOBAL_HOTKEYS_FILEPATH, gsr_global_hotkeys_local_filepath)) {
+ fprintf(stderr, "Error: failed to copy gsr-global-hotkeys to %s\n", gsr_global_hotkeys_local_filepath);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static int setup_gsr_ui(const char *user_homepath) {
char self_path[PATH_MAX];
if(!readlink_realpath("/proc/self/exe", self_path)) {
@@ -146,29 +193,13 @@ static int setup_gsr_ui(const char *user_homepath) {
snprintf(gsr_global_hotkeys_local_filepath, sizeof(gsr_global_hotkeys_local_filepath), "%s/.local/share/gpu-screen-recorder/gsr-global-hotkeys", user_homepath);
if(geteuid() == 0) { /* is current user root? */
- int success = 1;
- success &= (file_set_capabilities(kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP, CAP_SETUID }, 3) == 1);
- return success ? 0 : 1;
- } else {
- if(create_local_kms_server_proxy_directory(user_homepath) != 1) {
- fprintf(stderr, "Error: failed to create ~/.local/share/gpu-screen-recorder directory\n");
- return 1;
- }
-
- if(copy_file_atomic(KMS_SERVER_PROXY_FILEPATH, kms_server_proxy_local_filepath) != 1) {
- fprintf(stderr, "Error: failed to copy kms-server-proxy to %s\n", kms_server_proxy_local_filepath);
+ if(!set_kms_server_proxy_permissions_and_capabilities(kms_server_proxy_local_filepath))
return 1;
- }
-
- if(copy_file_atomic(GSR_KMS_SERVER_FILEPATH, gsr_kms_server_local_filepath) != 1) {
- fprintf(stderr, "Error: failed to copy gsr-kms-server to %s\n", gsr_kms_server_local_filepath);
- return 1;
- }
- if(copy_file_atomic(GSR_GLOBAL_HOTKEYS_FILEPATH, gsr_global_hotkeys_local_filepath) != 1) {
- fprintf(stderr, "Error: failed to copy gsr-global-hotkeys to %s\n", gsr_global_hotkeys_local_filepath);
+ return 0;
+ } else {
+ if(!setup_local_files(user_homepath, kms_server_proxy_local_filepath, gsr_kms_server_local_filepath, gsr_global_hotkeys_local_filepath))
return 1;
- }
const char *args[] = { "pkexec", kms_server_proxy_local_filepath, "setup-gsr-ui", user_homepath, NULL };
return execvp(args[0], (char *const*)args);
@@ -209,24 +240,14 @@ static int launch_gsr_kms_server(const char *initial_socket_path, const char *ca
const char *args[] = { "pkexec", gsr_kms_server_local_filepath, initial_socket_path, card_path, NULL };
return execvp(args[0], (char *const*)args);
} else if(geteuid() == 0) { /* is current user root? */
- file_set_capabilities(kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP, CAP_SETUID }, 3);
+ if(!set_kms_server_proxy_permissions_and_capabilities(kms_server_proxy_local_filepath))
+ return 1;
+
const char *args[] = { gsr_kms_server_local_filepath, initial_socket_path, card_path, NULL };
return execv(args[0], (char *const*)args);
} else {
- if(create_local_kms_server_proxy_directory(user_homepath) != 1) {
- fprintf(stderr, "Error: failed to create ~/.local/share/gpu-screen-recorder directory\n");
+ if(!setup_local_files(user_homepath, kms_server_proxy_local_filepath, gsr_kms_server_local_filepath, NULL))
return 1;
- }
-
- if(copy_file_atomic(KMS_SERVER_PROXY_FILEPATH, kms_server_proxy_local_filepath) != 1) {
- fprintf(stderr, "Error: failed to copy kms-server-proxy to %s\n", kms_server_proxy_local_filepath);
- return 1;
- }
-
- if(copy_file_atomic(GSR_KMS_SERVER_FILEPATH, gsr_kms_server_local_filepath) != 1) {
- fprintf(stderr, "Error: failed to copy gsr-kms-server to %s\n", gsr_kms_server_local_filepath);
- return 1;
- }
const char *args[] = { "pkexec", kms_server_proxy_local_filepath, initial_socket_path, card_path, user_homepath, NULL };
return execvp(args[0], (char *const*)args);