]> uap-core.de Git - uwplayer.git/commitdiff
fix use after free default
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 24 Sep 2025 15:49:03 +0000 (17:49 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 24 Sep 2025 15:49:03 +0000 (17:49 +0200)
application/atomic.h [new file with mode: 0644]
application/main.c
application/player.c
application/player.h
application/window.c
application/window.h

diff --git a/application/atomic.h b/application/atomic.h
new file mode 100644 (file)
index 0000000..ab684e1
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ATOMIC_H
+#define        ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __gnu_linux__
+
+#define ws_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
+#define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1) - 1
+#define ws_atomic_add32(intptr, val) __sync_fetch_and_add(intptr, val)
+#define ws_atomic_sub32(intptr, val) __sync_fetch_and_sub(intptr, val)
+
+#elif defined(OSX)
+#include <libkern/OSAtomic.h>
+
+#define ws_atomic_inc32(intptr) OSAtomicIncrement32((volatile int32_t *)intptr)
+#define ws_atomic_dec32(intptr) OSAtomicDecrement32((volatile int32_t *)intptr)
+
+#elif defined(BSD)   
+#define ws_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
+#define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1) - 1
+#define ws_atomic_add32(intptr, val) __sync_fetch_and_add(intptr, val)
+#define ws_atomic_sub32(intptr, val) __sync_fetch_and_sub(intptr, va
+#else
+// use atomic.h
+#include <atomic.h>
+
+#define ws_atomic_inc32(intptr) atomic_inc_32_nv(intptr)
+#define ws_atomic_dec32(intptr) atomic_dec_32_nv(intptr)
+// TODO
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ATOMIC_H */
+
index 8cf02c45f686ca95d034187e4725376f90f05d35..1205d4dc8b128f22412d2c7a38e49d997775860e 100644 (file)
@@ -222,7 +222,7 @@ int main(int argc, char** argv) {
         // and enable the single instance mode if possible
         XmToggleButtonGadgetSetState(window->prefSingleInstanceButton, True, True);
     }
-    
+      
     WindowShow(window);
     AppMainLoop(app);
     
index 0eced5fdc575aacc9754a5903f1e0f2cf28c4cf0..6ff7377bfaaf2ad4e641e1df238ebf4447216f26 100644 (file)
@@ -43,6 +43,8 @@
 #include "settings.h"
 #include "playlist.h"
 
+#include "atomic.h"
+
 extern char **environ;
 
 #define STR_BUFSIZE 512
@@ -112,9 +114,11 @@ static void* wait_for_process(void *data) {
     
     printf("waitpid: %d\n", status);
 
+    printf("wait_for_process player: %p\n", player);
     player->isactive = FALSE;
     player->status = status;
     SetPlayerWindow(0);
+    PlayerUnref(player);
     
     return NULL;
 }
@@ -170,9 +174,11 @@ static int start_player_process(Player *player, MainWindow *win) {
     player->process = player_pid;
     player->isactive = TRUE;
     
+    player->ref++;
     pthread_t tid;
     if(pthread_create(&tid, NULL, wait_for_process, player)) {
         perror("pthread_create");
+        player->ref--;
     }
     
     return 0;
@@ -253,28 +259,29 @@ static void* start_player(void *data) {
     
     Player *player = malloc(sizeof(Player));
     memset(player, 0, sizeof(Player));
+    player->ref = 1;
     
     // start mpv
     if(start_player_process(player, win)) {
-        PlayerDestroy(player);
+        PlayerUnref(player);
         return NULL;
     } 
     
     // wait until IPC socket is ready
     if(wait_for_ipc(player)) {
-        PlayerDestroy(player);
+        PlayerUnref(player);
         return NULL;
     }
     //close(player->log);
      
     if(connect_to_ipc(player)) {
-        PlayerDestroy(player);
+        PlayerUnref(player);
         return NULL;
     }
     
     // set player in main window
     if(win->player) {
-        PlayerDestroy(win->player);
+        PlayerUnref(win->player);
     }
     win->player = player;
     
@@ -495,23 +502,28 @@ static void handle_json_rpc_event(Player *p, JSONValue *v, JSONValue *event) {
     }
 }
 
-void PlayerDestroy(Player *p) {
+void PlayerUnref(Player *p) {
     if(p->log >= 0) {
         close(p->log);
+        p->log = -1;
     }
     if(p->ipc >= 0) {
         close(p->ipc);
-    }
-    
-    if(p->tmp) {
-        free(p->tmp);
+        p->ipc = -1;
     }
     
     if(p->isactive) {
         kill(p->process, SIGTERM);
     }
+    if(ws_atomic_dec32(&p->ref) > 0) {
+        return;
+    }
     
-    SetPlayerWindow(0);
+    if(p->tmp) {
+        free(p->tmp);
+    }
+    
+    SetPlayerWindow(0); 
     free(p);
 }
 
index 8f47e83164c5128c11ee9cc458b92b9ca2aa5f1e..4fd05f829898a3ccd19fa132d3a7f6a656246146 100644 (file)
@@ -40,7 +40,7 @@ extern "C" {
     
 void PlayerOpenFile(MainWindow *win);
 
-void PlayerDestroy(Player *p);
+void PlayerUnref(Player *p);
 
 void PlayerEOF(Player *p);
 
index 4adac0eb71dbf76f677e9ed535765581c463b9c3..5777c8f10f8a96560995b4c835469686a0919323 100644 (file)
@@ -761,7 +761,7 @@ void WindowAdjustAspectRatio(MainWindow *win) {
 
 void WindowClosePlayer(MainWindow *win) {
     if(win->player) {
-        PlayerDestroy(win->player);
+        PlayerUnref(win->player);
     }
     win->player = NULL;
     WindowShowPlayerCursor(win);
index dd7d3fe58e4ea61adb41b7cff4c9a769677cdd04..7df9825231a4ffed0ee01377e9107ba443240e0b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <Xm/XmAll.h>
 #include <stdbool.h>
+#include <inttypes.h>
 #include <unistd.h>
 #include <cx/list.h>
 #include <cx/linked_list.h>
@@ -55,6 +56,7 @@ typedef struct Player {
     int width;
     int height;
     int osd_height;
+    uint32_t ref;
 } Player;
 
 typedef struct {