From 58730845994a2727aa15df63db30119926a5a1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Mon, 14 Oct 2024 15:53:58 +0200 Subject: [PATCH] shmoverride: do not remove the shmid file if taking the lock fails If shmoverride init fails to take the lock, it likely means it is used by currently running process - do _not_ remove the file in such a case. This may happen if LD_PRELOAD leaks to child processes (which seems to happend on Xwayland when shmoverride is linked with -z initfirst). But also, if X server is started several times for some reason (for example user calls it manually), it will abort, but not early enough to skip shmoverride init. QubesOS/qubes-issues#8515 --- shmoverride/shmoverride.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shmoverride/shmoverride.c b/shmoverride/shmoverride.c index 3cd9536..ce71a29 100644 --- a/shmoverride/shmoverride.c +++ b/shmoverride/shmoverride.c @@ -533,24 +533,26 @@ static int try_init(void) fputs("snprintf() failed!\n", stderr); abort(); } - shmid_filename = __shmid_filename; - fprintf(stderr, "shmoverride: running with shm file %s\n", shmid_filename); + fprintf(stderr, "shmoverride: running with shm file %s\n", __shmid_filename); /* Try to lock the shm.id file (don't rely on whether it exists, a previous * process might have crashed). */ - idfd = open(shmid_filename, O_RDWR | O_CLOEXEC | O_CREAT | O_NOCTTY, 0600); + idfd = open(__shmid_filename, O_RDWR | O_CLOEXEC | O_CREAT | O_NOCTTY, 0600); if (idfd < 0) { fprintf(stderr, "shmoverride opening %s: %s\n", - shmid_filename, strerror(errno)); + __shmid_filename, strerror(errno)); goto cleanup; } if (flock(idfd, LOCK_EX | LOCK_NB) < 0) { fprintf(stderr, "shmoverride flock %s: %s\n", - shmid_filename, strerror(errno)); + __shmid_filename, strerror(errno)); /* There is probably an alive process holding the file, give up. */ goto cleanup; } + /* Save shmid file for cleanup only after taking the lock */ + shmid_filename = __shmid_filename; + if (ftruncate(idfd, SHM_ARGS_SIZE) < 0) { perror("shmoverride ftruncate"); goto cleanup;