mirror of
https://github.com/FeralInteractive/gamemode.git
synced 2025-06-06 07:37:21 +02:00
daemon: use readlink not realpath to find the exe
The realpath(3) will fail if the target does not exist (internally realpath will stat all the components of the link target path). This is a problem in the case of sandbox applications where the exe points to the absolute path *inside* the sandbox, e.g. to /app/bin/<name> in the case of flatpak. For these cases realpath(3) will then fail. Therefore use readlink(3) instead.
This commit is contained in:
parent
0c778200ae
commit
70e601267b
@ -40,10 +40,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "helpers.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdatomic.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <systemd/sd-daemon.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* The GameModeClient encapsulates the remote connection, providing a list
|
||||
@ -650,15 +654,31 @@ static char *game_mode_context_find_exe(pid_t pid)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
char *proc_path = NULL, *wine_exe = NULL;
|
||||
autoclose_fd int pidfd = -1;
|
||||
ssize_t r;
|
||||
|
||||
if (!(proc_path = buffered_snprintf(buffer, "/proc/%d/exe", pid)))
|
||||
if (!(proc_path = buffered_snprintf(buffer, "/proc/%d", pid)))
|
||||
goto fail;
|
||||
|
||||
/* Allocate the realpath if possible */
|
||||
char *exe = realpath(proc_path, NULL);
|
||||
if (!exe)
|
||||
/* Translate /proc/<pid>/exe to the application binary */
|
||||
pidfd = openat(AT_FDCWD, proc_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
|
||||
if (pidfd == -1)
|
||||
goto fail;
|
||||
|
||||
r = readlinkat(pidfd, "exe", buffer, sizeof(buffer));
|
||||
|
||||
if (r == sizeof(buffer)) {
|
||||
errno = ENAMETOOLONG;
|
||||
r = -1;
|
||||
}
|
||||
|
||||
if (r == -1)
|
||||
goto fail;
|
||||
|
||||
buffer[r] = '\0';
|
||||
|
||||
char *exe = strdup(buffer);
|
||||
|
||||
/* Detect if the process is a wine loader process */
|
||||
if (game_mode_detect_wine_preloader(exe)) {
|
||||
LOG_MSG("Detected wine preloader for client %d [%s].\n", pid, exe);
|
||||
|
Loading…
x
Reference in New Issue
Block a user