[mupen64plus-core] 90/310: Prevent data corruption with caller managed OSD text

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:57:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

ecsv-guest pushed a commit to branch armhf_test
in repository mupen64plus-core.

commit c8657cbfa4b746697400c45b8a67861e6080258f
Author: Sven Eckelmann <sven at narfation.org>
Date:   Sun Jul 24 12:31:00 2011 +0200

    Prevent data corruption with caller managed OSD text
    
    OSD text like the volume information is update by the caller in main.c, but the
    drawing function in osd.c maybe already deleted the corresponding data
    structure. The workaround was to check if the pointer to data structure could
    be found in the list. It could happen that another text was shown inbetween and
    the libc reused the old memory region for another text message. The
    osd_message_valid function would wrongly inform the caller that the OSD text
    wasn't deleted and the following osd_update_message would modify the wrong
    message.
    
    We must forbid that the messages is deleted by both the caller and the osd
    drawing mainloop. The mainloop restricts itself to removing it from the list
    when the caller marked it as user_managed directly after it was allocated. The
    caller has to remove it manually using osd_delete_message in that situation.
---
 debian/changelog                           |   2 +
 debian/patches/osd_memory_corruption.patch | 205 +++++++++++++++++++++++++++++
 debian/patches/series                      |   1 +
 3 files changed, 208 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 5705af3..8fbc186 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -20,6 +20,8 @@ mupen64plus-core (1.99.4-3) UNRELEASED; urgency=low
       core can not open config
     - Add conflicting_symbol.patch, Don't define variable isGoldeneyeRom in each
       file
+    - Add osd_memory_corruption.patch, Prevent data corruption with caller
+      managed OSD text
 
  -- Sven Eckelmann <sven at narfation.org>  Wed, 13 Jul 2011 08:38:54 +0200
 
diff --git a/debian/patches/osd_memory_corruption.patch b/debian/patches/osd_memory_corruption.patch
new file mode 100644
index 0000000..4c4d410
--- /dev/null
+++ b/debian/patches/osd_memory_corruption.patch
@@ -0,0 +1,205 @@
+Description: Prevent data corruption with caller managed OSD text
+ OSD text like the volume information is update by the caller in main.c, but
+ the drawing function in osd.c maybe already deleted the corresponding data
+ structure. The workaround was to check if the pointer to data structure could
+ be found in the list. It could happen that another text was shown inbetween
+ and the libc reused the old memory region for another text message. The
+ osd_message_valid function would wrongly inform the caller that the OSD text
+ wasn't deleted and the following osd_update_message would modify the wrong
+ message.
+ .
+ We must forbid that the messages is deleted by both the caller and the osd
+ drawing mainloop. The mainloop restricts itself to removing it from the list
+ when the caller marked it as user_managed directly after it was allocated. The
+ caller has to remove it manually using osd_delete_message in that situation.
+Origin: upstream, https://bitbucket.org/richard42/mupen64plus-core/changeset/c1e0be49ef63
+Author: Sven Eckelmann <sven at narfation.org>
+
+---
+diff --git a/src/main/main.c b/src/main/main.c
+index 0aadb400cb716e9b5b9c23e3fc578f36b5d48707..25fe9acc443c9e858200dfa1ba68ea880a5f6855 100644
+--- a/src/main/main.c
++++ b/src/main/main.c
+@@ -210,6 +210,7 @@ void main_set_fastforward(int enable)
+         // set fast-forward indicator
+         l_msgFF = osd_new_message(OSD_TOP_RIGHT, "Fast Forward");
+         osd_message_set_static(l_msgFF);
++	osd_message_set_user_managed(l_msgFF);
+     }
+     else if (!enable && ff_state)
+     {
+@@ -252,6 +253,7 @@ void main_toggle_pause(void)
+         DebugMessage(M64MSG_STATUS, "Emulation paused.");
+         l_msgPause = osd_new_message(OSD_MIDDLE_CENTER, "Paused");
+         osd_message_set_static(l_msgPause);
++	osd_message_set_user_managed(l_msgPause);
+         StateChanged(M64CORE_EMU_STATE, M64EMU_PAUSED);
+     }
+ 
+@@ -271,10 +273,6 @@ void main_draw_volume_osd(void)
+     char msgString[64];
+     const char *volString;
+ 
+-    // if we had a volume message, make sure that it's still in the OSD list, or set it to NULL
+-    if (l_msgVol != NULL && !osd_message_valid(l_msgVol))
+-        l_msgVol = NULL;
+-
+     // this calls into the audio plugin
+     volString = volumeGetString();
+     if (volString == NULL)
+@@ -291,8 +289,10 @@ void main_draw_volume_osd(void)
+     // create a new message or update an existing one
+     if (l_msgVol != NULL)
+         osd_update_message(l_msgVol, "%s", msgString);
+-    else
++    else {
+         l_msgVol = osd_new_message(OSD_MIDDLE_CENTER, "%s", msgString);
++        osd_message_set_user_managed(l_msgVol);
++    }
+ }
+ 
+ /* this function could be called as a result of a keypress, joystick/button movement,
+@@ -590,6 +590,11 @@ void main_stop(void)
+         osd_delete_message(l_msgFF);
+         l_msgFF = NULL;
+     }
++    if(l_msgVol)
++    {
++        osd_delete_message(l_msgVol);
++        l_msgVol = NULL;
++    }
+     if (rompause)
+     {
+         rompause = 0;
+diff --git a/src/osd/osd.cpp b/src/osd/osd.cpp
+index d6775c6a9d45a17a1f0b2728060bed3c564e4491..29bea2d2475e91a51e79c37a2876d0f040e09fdd 100644
+--- a/src/osd/osd.cpp
++++ b/src/osd/osd.cpp
+@@ -50,6 +50,8 @@ static float l_fLineHeight = -1.0;
+ 
+ static void animation_none(osd_message_t *);
+ static void animation_fade(osd_message_t *);
++static void osd_remove_message(osd_message_t *msg);
++static osd_message_t * osd_message_valid(osd_message_t *testmsg);
+ 
+ static float fCornerScroll[OSD_NUM_CORNERS]; 
+ 
+@@ -350,7 +352,10 @@ void osd_render()
+         // if previous message was marked for deletion, delete it
+         if(msg_to_delete)
+         {
+-            osd_delete_message(msg_to_delete);
++            if (msg_to_delete->user_managed)
++                osd_remove_message(msg_to_delete);
++            else
++                osd_delete_message(msg_to_delete);
+             msg_to_delete = NULL;
+         }
+ 
+@@ -394,7 +399,13 @@ void osd_render()
+ 
+     // if last message was marked for deletion, delete it
+     if(msg_to_delete)
+-        osd_delete_message(msg_to_delete);
++    {
++        if (msg_to_delete->user_managed)
++            osd_remove_message(msg_to_delete);
++        else
++            osd_delete_message(msg_to_delete);
++        msg_to_delete = NULL;
++    }
+ 
+     // restore the matrices
+     glMatrixMode(GL_MODELVIEW);
+@@ -448,6 +459,7 @@ osd_message_t * osd_new_message(enum osd_corner eCorner, const char *fmt, ...)
+     // set default values
+     memset(msg, 0, sizeof(osd_message_t));
+     msg->text = strdup(buf);
++    msg->user_managed = 0;
+     // default to white
+     msg->color[R] = 1.;
+     msg->color[G] = 1.;
+@@ -516,25 +528,38 @@ void osd_update_message(osd_message_t *msg, const char *fmt, ...)
+         msg->state = OSD_DISPLAY;
+         msg->frames = 0;
+     }
++    
++    if (!osd_message_valid(msg))
++        list_prepend(&l_messageQueue, msg);
+ 
+ }
+ 
+ // remove message from message queue
+-extern "C"
+-void osd_delete_message(osd_message_t *msg)
++static void osd_remove_message(osd_message_t *msg)
+ {
+     list_node_t *node;
+ 
+     if (!l_OsdInitialized || !msg) return;
+ 
+-    if (msg->text)
++    if (msg->text) {
+         free(msg->text);
++	msg->text = NULL;
++    }
+ 
+     node = list_find_node(l_messageQueue, msg);
+-    free(msg);
+     list_node_delete(&l_messageQueue, node);
+ }
+ 
++// remove message from message queue and free it
++extern "C"
++void osd_delete_message(osd_message_t *msg)
++{
++    if (!l_OsdInitialized || !msg) return;
++
++    osd_remove_message(msg);
++    free(msg);
++}
++
+ // set "corner" of the screen that message appears in.
+ extern "C"
+ void osd_message_set_corner(osd_message_t *msg, enum osd_corner corner)
+@@ -555,9 +580,17 @@ void osd_message_set_static(osd_message_t *msg)
+     msg->frames = 0;
+ }
+ 
++// set message so it doesn't automatically get freed when finished transition.
++extern "C"
++void osd_message_set_user_managed(osd_message_t *msg)
++{
++    if (!l_OsdInitialized || !msg) return;
++
++    msg->user_managed = 1;
++}
++
+ // return message pointer if valid (in the OSD list), otherwise return NULL
+-extern "C"
+-osd_message_t * osd_message_valid(osd_message_t *testmsg)
++static osd_message_t * osd_message_valid(osd_message_t *testmsg)
+ {
+     if (!l_OsdInitialized || !testmsg) return NULL;
+ 
+diff --git a/src/osd/osd.h b/src/osd/osd.h
+index b331201f5e726665aee8c4a211e12cb0841b5ec8..547712ae03a94a127b86ca9ed7447f54707e9b14 100644
+--- a/src/osd/osd.h
++++ b/src/osd/osd.h
+@@ -75,6 +75,7 @@ typedef struct {
+     unsigned int timeout[OSD_NUM_STATES]; // timeouts for each display state
+ #define OSD_INFINITE_TIMEOUT 0xffffffff
+     unsigned int frames; // number of frames in this state
++    int user_managed; // structure managed by caller and not to be freed by us
+ } osd_message_t;
+ 
+ enum { R, G, B }; // for referencing color array
+@@ -91,7 +92,7 @@ void osd_update_message(osd_message_t *, const char *, ...) __attribute__ ((form
+ void osd_delete_message(osd_message_t *);
+ void osd_message_set_corner(osd_message_t *, enum osd_corner);
+ void osd_message_set_static(osd_message_t *);
+-osd_message_t * osd_message_valid(osd_message_t *);
++void osd_message_set_user_managed(osd_message_t *);
+ 
+ #ifdef __cplusplus
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 89263a9..44c395e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,4 @@ big_endian_conflict.patch
 privilege_segfault.patch
 info_configuration_failure.patch
 conflicting_symbol.patch
+osd_memory_corruption.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus-core.git



More information about the Pkg-games-commits mailing list