]> code.delx.au - pulseaudio/blobdiff - src/pulse/ext-stream-restore.c
core: Fix uninit pointer read in protocol-native
[pulseaudio] / src / pulse / ext-stream-restore.c
index 469c822a74fc1103ed6115d44e9ea961ef04e897..3362a5f515462c5139724a9e95278843c7a50487 100644 (file)
@@ -5,7 +5,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #endif
 
 #include <pulse/context.h>
 #endif
 
 #include <pulse/context.h>
-#include <pulse/gccmacro.h>
+#include <pulse/fork-detect.h>
+#include <pulse/operation.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
 
 #include <pulsecore/macro.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-#include "operation.h"
-
 #include "ext-stream-restore.h"
 
 enum {
 #include "ext-stream-restore.h"
 
 enum {
@@ -55,7 +54,7 @@ static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint3
         goto finish;
 
     if (command != PA_COMMAND_REPLY) {
         goto finish;
 
     if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+        if (pa_context_handle_error(o->context, command, t, false) < 0)
             goto finish;
 
     } else if (pa_tagstruct_getu32(t, &version) < 0 ||
             goto finish;
 
     } else if (pa_tagstruct_getu32(t, &version) < 0 ||
@@ -87,6 +86,7 @@ pa_operation *pa_ext_stream_restore_test(
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
@@ -114,7 +114,7 @@ static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint3
         goto finish;
 
     if (command != PA_COMMAND_REPLY) {
         goto finish;
 
     if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+        if (pa_context_handle_error(o->context, command, t, false) < 0)
             goto finish;
 
         eol = -1;
             goto finish;
 
         eol = -1;
@@ -122,7 +122,7 @@ static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint3
 
         while (!pa_tagstruct_eof(t)) {
             pa_ext_stream_restore_info i;
 
         while (!pa_tagstruct_eof(t)) {
             pa_ext_stream_restore_info i;
-            pa_bool_t mute = FALSE;
+            bool mute = false;
 
             memset(&i, 0, sizeof(i));
 
 
             memset(&i, 0, sizeof(i));
 
@@ -167,6 +167,7 @@ pa_operation *pa_ext_stream_restore_read(
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
@@ -200,6 +201,7 @@ pa_operation *pa_ext_stream_restore_write(
     pa_assert(mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE || mode == PA_UPDATE_SET);
     pa_assert(data);
 
     pa_assert(mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE || mode == PA_UPDATE_SET);
     pa_assert(data);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
@@ -235,13 +237,10 @@ pa_operation *pa_ext_stream_restore_write(
     return o;
 
 fail:
     return o;
 
 fail:
-    if (o) {
-        pa_operation_cancel(o);
-        pa_operation_unref(o);
-    }
+    pa_operation_cancel(o);
+    pa_operation_unref(o);
 
 
-    if (t)
-        pa_tagstruct_free(t);
+    pa_tagstruct_free(t);
 
     pa_context_set_error(c, PA_ERR_INVALID);
     return NULL;
 
     pa_context_set_error(c, PA_ERR_INVALID);
     return NULL;
@@ -262,6 +261,7 @@ pa_operation *pa_ext_stream_restore_delete(
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     pa_assert(s);
 
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     pa_assert(s);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
@@ -285,13 +285,10 @@ pa_operation *pa_ext_stream_restore_delete(
     return o;
 
 fail:
     return o;
 
 fail:
-    if (o) {
-        pa_operation_cancel(o);
-        pa_operation_unref(o);
-    }
+    pa_operation_cancel(o);
+    pa_operation_unref(o);
 
 
-    if (t)
-        pa_tagstruct_free(t);
+    pa_tagstruct_free(t);
 
     pa_context_set_error(c, PA_ERR_INVALID);
     return NULL;
 
     pa_context_set_error(c, PA_ERR_INVALID);
     return NULL;
@@ -310,6 +307,7 @@ pa_operation *pa_ext_stream_restore_subscribe(
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
 
@@ -334,6 +332,9 @@ void pa_ext_stream_restore_set_subscribe_cb(
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    if (pa_detect_fork())
+        return;
+
     c->ext_stream_restore.callback = cb;
     c->ext_stream_restore.userdata = userdata;
 }
     c->ext_stream_restore.callback = cb;
     c->ext_stream_restore.userdata = userdata;
 }