aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-04-09 16:06:39 +0200
committerdec05eba <dec05eba@protonmail.com>2023-04-09 16:06:39 +0200
commit7dcf3a68cc8027bfa0d865e8a33566b4ae431618 (patch)
tree9d770edd2920f16d4e9649f5dc126a5279508dc5
parentcb82677ae8e7b3d5ef35a36b7c6d88020959864c (diff)
Use /usr/bin/gsr-kms-server constant path for pkexec
-rw-r--r--include/capture/kms_vaapi.h1
-rw-r--r--kms/client/kms_client.c65
-rw-r--r--kms/client/kms_client.h2
-rw-r--r--src/capture/kms_vaapi.c2
-rw-r--r--src/main.cpp8
5 files changed, 37 insertions, 41 deletions
diff --git a/include/capture/kms_vaapi.h b/include/capture/kms_vaapi.h
index 5cf8606..ba5763b 100644
--- a/include/capture/kms_vaapi.h
+++ b/include/capture/kms_vaapi.h
@@ -10,7 +10,6 @@ typedef struct _XDisplay Display;
typedef struct {
Display *dpy;
const char *display_to_capture; /* if this is "screen", then the entire x11 screen is captured (all displays). A copy is made of this */
- const char *program_dir; /* ref */
} gsr_capture_kms_vaapi_params;
gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c
index 2b59836..6730318 100644
--- a/kms/client/kms_client.c
+++ b/kms/client/kms_client.c
@@ -63,7 +63,7 @@ static int recv_msg_from_server(int server_fd, gsr_kms_response *response) {
return res;
}
-int gsr_kms_client_init(gsr_kms_client *self, const char *card_path, const char *program_dir) {
+int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) {
self->kms_server_pid = -1;
self->card_path = NULL;
self->socket_fd = -1;
@@ -72,37 +72,42 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path, const char
struct sockaddr_un local_addr = {0};
struct sockaddr_un remote_addr = {0};
+ // This doesn't work on nixos, but we dont want to use $PATH because we want to make this as safe as possible by running pkexec
+ // on a path that only root can modify. If we use "gsr-kms-server" instead then $PATH can be modified in ~/.bashrc for example
+ // which will overwrite the path to gsr-kms-server and the user can end up running a malicious program that pretends to be gsr-kms-server.
+ // If there is a safe way to do this on nixos, then please tell me; or use gpu-screen-recorder flatpak instead.
+ const char *server_filepath = "/usr/bin/gsr-kms-server";
+ bool has_perm = 0;
bool inside_flatpak = is_inside_flatpak();
- char server_filepath[PATH_MAX];
- snprintf(server_filepath, sizeof(server_filepath), "%s/%s", program_dir, "gsr-kms-server");
- if(access(server_filepath, F_OK) != 0 || inside_flatpak)
- snprintf(server_filepath, sizeof(server_filepath), "gsr-kms-server"); // Assume gsr-kms-server is in $PATH
+ if(!inside_flatpak) {
+ if(access("/usr/bin/gsr-kms-server", F_OK) != 0) {
+ fprintf(stderr, "gsr error: gsr_kms_client_init: /usr/bin/gsr-kms-server not found, please install gpu-screen-recorder first\n");
+ return -1;
+ }
- bool has_perm = 0;
- if(geteuid() == 0) {
- has_perm = true;
- } else {
- cap_t kms_server_cap = cap_get_file(server_filepath);
- if(kms_server_cap) {
- cap_flag_value_t res = 0;
- cap_get_flag(kms_server_cap, CAP_SYS_ADMIN, CAP_PERMITTED, &res);
- if(res == CAP_SET) {
- //fprintf(stderr, "has permission!\n");
- has_perm = true;
+ if(geteuid() == 0) {
+ has_perm = true;
+ } else {
+ cap_t kms_server_cap = cap_get_file(server_filepath);
+ if(kms_server_cap) {
+ cap_flag_value_t res = 0;
+ cap_get_flag(kms_server_cap, CAP_SYS_ADMIN, CAP_PERMITTED, &res);
+ if(res == CAP_SET) {
+ //fprintf(stderr, "has permission!\n");
+ has_perm = true;
+ } else {
+ //fprintf(stderr, "No permission:(\n");
+ }
+ cap_free(kms_server_cap);
} else {
- //fprintf(stderr, "No permission:(\n");
+ if(errno == ENODATA)
+ fprintf(stderr, "gsr info: gsr_kms_client_init: gsr-kms-server is missing sys_admin cap and will require root authentication. To bypass this automatically, run: sudo setcap cap_sys_admin+ep '%s'\n", server_filepath);
+ else
+ fprintf(stderr, "gsr info: gsr_kms_client_init: failed to get cap\n");
}
- cap_free(kms_server_cap);
- } else {
- if(errno == ENODATA)
- fprintf(stderr, "gsr info: gsr_kms_client_init: gsr-kms-server is missing sys_admin cap and will require root authentication. To bypass this automatically, run: sudo setcap cap_sys_admin+ep '%s'\n", server_filepath);
- else
- fprintf(stderr, "gsr info: gsr_kms_client_init: failed to get cap\n");
}
}
- fprintf(stderr, "gsr info: gsr server path: %s, exists: %s\n", server_filepath, access(server_filepath, F_OK) == 0 ? "yes" : "no");
-
self->card_path = strdup(card_path);
if(!self->card_path) {
fprintf(stderr, "gsr error: gsr_kms_client_init: failed to duplicate card_path\n");
@@ -138,17 +143,17 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path, const char
fprintf(stderr, "gsr error: gsr_kms_client_init: fork failed, error: %s\n", strerror(errno));
goto err;
} else if(pid == 0) { /* child */
- if(has_perm) {
- const char *args[] = { server_filepath, self->socket_path, NULL };
+ if(inside_flatpak) {
+ const char *args[] = { "flatpak-spawn", "--host", "pkexec", "flatpak", "run", "--command=gsr-kms-server", "com.dec05eba.gpu_screen_recorder", self->socket_path, NULL };
execvp(args[0], (char *const*)args);
- } else if(inside_flatpak) {
- const char *args[] = { "flatpak-spawn", "--host", "pkexec", server_filepath, self->socket_path, NULL };
+ } else if(has_perm) {
+ const char *args[] = { server_filepath, self->socket_path, NULL };
execvp(args[0], (char *const*)args);
} else {
const char *args[] = { "pkexec", server_filepath, self->socket_path, NULL };
execvp(args[0], (char *const*)args);
}
- perror("execvp");
+ fprintf(stderr, "gsr error: gsr_kms_client_init: execvp failed, error: %s\n", strerror(errno));
_exit(127);
} else { /* parent */
self->kms_server_pid = pid;
diff --git a/kms/client/kms_client.h b/kms/client/kms_client.h
index 59d3cb3..a15d869 100644
--- a/kms/client/kms_client.h
+++ b/kms/client/kms_client.h
@@ -13,7 +13,7 @@ typedef struct {
} gsr_kms_client;
/* |card_path| should be a path to card, for example /dev/dri/card0 */
-int gsr_kms_client_init(gsr_kms_client *self, const char *card_path, const char *program_dir);
+int gsr_kms_client_init(gsr_kms_client *self, const char *card_path);
void gsr_kms_client_deinit(gsr_kms_client *self);
int gsr_kms_client_get_kms(gsr_kms_client *self, gsr_kms_response *response);
diff --git a/src/capture/kms_vaapi.c b/src/capture/kms_vaapi.c
index 2e970a3..a369765 100644
--- a/src/capture/kms_vaapi.c
+++ b/src/capture/kms_vaapi.c
@@ -98,7 +98,7 @@ static int gsr_capture_kms_vaapi_start(gsr_capture *cap, AVCodecContext *video_c
gsr_capture_kms_vaapi *cap_kms = cap->priv;
// TODO: Allow specifying another card, and in other places (TODO: Use /dev/dri/renderD128?)
- if(gsr_kms_client_init(&cap_kms->kms_client, "/dev/dri/card0", cap_kms->params.program_dir) != 0) {
+ if(gsr_kms_client_init(&cap_kms->kms_client, "/dev/dri/card0") != 0) {
return -1;
}
diff --git a/src/main.cpp b/src/main.cpp
index 9e4ae4e..489f800 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,8 +19,6 @@ extern "C" {
#include <signal.h>
#include <sys/stat.h>
-#include <libgen.h>
-
#include "../include/sound.hpp"
extern "C" {
@@ -1111,11 +1109,6 @@ int main(int argc, char **argv) {
if(argc == 0)
usage();
- char *program_dir = dirname(argv[0]);
- char program_dir_full[PATH_MAX];
- program_dir_full[0] = '\0';
- realpath(program_dir, program_dir_full);
-
//av_log_set_level(AV_LOG_TRACE);
std::map<std::string, Arg> args = {
@@ -1397,7 +1390,6 @@ int main(int argc, char **argv) {
gsr_capture_kms_vaapi_params kms_params;
kms_params.dpy = dpy;
kms_params.display_to_capture = capture_target;
- kms_params.program_dir = program_dir_full;
capture = gsr_capture_kms_vaapi_create(&kms_params);
if(!capture)
return 1;