Use /usr/bin/gsr-kms-server constant path for pkexec
This commit is contained in:
parent
cb82677ae8
commit
7dcf3a68cc
@ -10,7 +10,6 @@ typedef struct _XDisplay Display;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
Display *dpy;
|
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 *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_kms_vaapi_params;
|
||||||
|
|
||||||
gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
|
gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
|
||||||
|
@ -63,7 +63,7 @@ static int recv_msg_from_server(int server_fd, gsr_kms_response *response) {
|
|||||||
return res;
|
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->kms_server_pid = -1;
|
||||||
self->card_path = NULL;
|
self->card_path = NULL;
|
||||||
self->socket_fd = -1;
|
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 local_addr = {0};
|
||||||
struct sockaddr_un remote_addr = {0};
|
struct sockaddr_un remote_addr = {0};
|
||||||
|
|
||||||
bool inside_flatpak = is_inside_flatpak();
|
// 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
|
||||||
char server_filepath[PATH_MAX];
|
// on a path that only root can modify. If we use "gsr-kms-server" instead then $PATH can be modified in ~/.bashrc for example
|
||||||
snprintf(server_filepath, sizeof(server_filepath), "%s/%s", program_dir, "gsr-kms-server");
|
// 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(access(server_filepath, F_OK) != 0 || inside_flatpak)
|
// If there is a safe way to do this on nixos, then please tell me; or use gpu-screen-recorder flatpak instead.
|
||||||
snprintf(server_filepath, sizeof(server_filepath), "gsr-kms-server"); // Assume gsr-kms-server is in $PATH
|
const char *server_filepath = "/usr/bin/gsr-kms-server";
|
||||||
|
|
||||||
bool has_perm = 0;
|
bool has_perm = 0;
|
||||||
if(geteuid() == 0) {
|
bool inside_flatpak = is_inside_flatpak();
|
||||||
has_perm = true;
|
if(!inside_flatpak) {
|
||||||
} else {
|
if(access("/usr/bin/gsr-kms-server", F_OK) != 0) {
|
||||||
cap_t kms_server_cap = cap_get_file(server_filepath);
|
fprintf(stderr, "gsr error: gsr_kms_client_init: /usr/bin/gsr-kms-server not found, please install gpu-screen-recorder first\n");
|
||||||
if(kms_server_cap) {
|
return -1;
|
||||||
cap_flag_value_t res = 0;
|
}
|
||||||
cap_get_flag(kms_server_cap, CAP_SYS_ADMIN, CAP_PERMITTED, &res);
|
|
||||||
if(res == CAP_SET) {
|
if(geteuid() == 0) {
|
||||||
//fprintf(stderr, "has permission!\n");
|
has_perm = true;
|
||||||
has_perm = true;
|
|
||||||
} else {
|
|
||||||
//fprintf(stderr, "No permission:(\n");
|
|
||||||
}
|
|
||||||
cap_free(kms_server_cap);
|
|
||||||
} else {
|
} else {
|
||||||
if(errno == ENODATA)
|
cap_t kms_server_cap = cap_get_file(server_filepath);
|
||||||
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);
|
if(kms_server_cap) {
|
||||||
else
|
cap_flag_value_t res = 0;
|
||||||
fprintf(stderr, "gsr info: gsr_kms_client_init: failed to get cap\n");
|
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 {
|
||||||
|
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);
|
self->card_path = strdup(card_path);
|
||||||
if(!self->card_path) {
|
if(!self->card_path) {
|
||||||
fprintf(stderr, "gsr error: gsr_kms_client_init: failed to duplicate card_path\n");
|
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));
|
fprintf(stderr, "gsr error: gsr_kms_client_init: fork failed, error: %s\n", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
} else if(pid == 0) { /* child */
|
} else if(pid == 0) { /* child */
|
||||||
if(has_perm) {
|
if(inside_flatpak) {
|
||||||
const char *args[] = { server_filepath, self->socket_path, NULL };
|
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);
|
execvp(args[0], (char *const*)args);
|
||||||
} else if(inside_flatpak) {
|
} else if(has_perm) {
|
||||||
const char *args[] = { "flatpak-spawn", "--host", "pkexec", server_filepath, self->socket_path, NULL };
|
const char *args[] = { server_filepath, self->socket_path, NULL };
|
||||||
execvp(args[0], (char *const*)args);
|
execvp(args[0], (char *const*)args);
|
||||||
} else {
|
} else {
|
||||||
const char *args[] = { "pkexec", server_filepath, self->socket_path, NULL };
|
const char *args[] = { "pkexec", server_filepath, self->socket_path, NULL };
|
||||||
execvp(args[0], (char *const*)args);
|
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);
|
_exit(127);
|
||||||
} else { /* parent */
|
} else { /* parent */
|
||||||
self->kms_server_pid = pid;
|
self->kms_server_pid = pid;
|
||||||
|
@ -13,7 +13,7 @@ typedef struct {
|
|||||||
} gsr_kms_client;
|
} gsr_kms_client;
|
||||||
|
|
||||||
/* |card_path| should be a path to card, for example /dev/dri/card0 */
|
/* |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);
|
void gsr_kms_client_deinit(gsr_kms_client *self);
|
||||||
|
|
||||||
int gsr_kms_client_get_kms(gsr_kms_client *self, gsr_kms_response *response);
|
int gsr_kms_client_get_kms(gsr_kms_client *self, gsr_kms_response *response);
|
||||||
|
@ -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;
|
gsr_capture_kms_vaapi *cap_kms = cap->priv;
|
||||||
|
|
||||||
// TODO: Allow specifying another card, and in other places (TODO: Use /dev/dri/renderD128?)
|
// 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ extern "C" {
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <libgen.h>
|
|
||||||
|
|
||||||
#include "../include/sound.hpp"
|
#include "../include/sound.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -1111,11 +1109,6 @@ int main(int argc, char **argv) {
|
|||||||
if(argc == 0)
|
if(argc == 0)
|
||||||
usage();
|
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);
|
//av_log_set_level(AV_LOG_TRACE);
|
||||||
|
|
||||||
std::map<std::string, Arg> args = {
|
std::map<std::string, Arg> args = {
|
||||||
@ -1397,7 +1390,6 @@ int main(int argc, char **argv) {
|
|||||||
gsr_capture_kms_vaapi_params kms_params;
|
gsr_capture_kms_vaapi_params kms_params;
|
||||||
kms_params.dpy = dpy;
|
kms_params.dpy = dpy;
|
||||||
kms_params.display_to_capture = capture_target;
|
kms_params.display_to_capture = capture_target;
|
||||||
kms_params.program_dir = program_dir_full;
|
|
||||||
capture = gsr_capture_kms_vaapi_create(&kms_params);
|
capture = gsr_capture_kms_vaapi_create(&kms_params);
|
||||||
if(!capture)
|
if(!capture)
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user