spa: audioadapter: fix stack-use-after-scope when configuring format

It is not enough for `buffer` to be alive in its current
scope because when execution enters that branch, `format`
will be set to `fmt`, which points inside `buffer`. And
since `format` is used outside that scope, `buffer` must
live longer.

This was detected by ASAN when Audacity was starting up.

  ==25007==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffdbcfef560 at pc 0x7fe44ca95db3 bp 0x7ffdbcfeeda0 sp 0x7ffdbcfeed90
  READ of size 4 at 0x7ffdbcfef560 thread T0
      #0 0x7fe44ca95db2 in spa_pod_parser_pod ../spa/include/spa/pod/parser.h:67
      #1 0x7fe44ca9a805 in spa_format_parse ../spa/include/spa/param/format-utils.h:44
      #2 0x7fe44cad293a in port_set_format ../spa/plugins/audioconvert/audioconvert.c:1934
      #3 0x7fe44cadad14 in impl_node_port_set_param ../spa/plugins/audioconvert/audioconvert.c:2038
      #4 0x7fe44ca587e2 in configure_format ../spa/plugins/audioconvert/audioadapter.c:509
      #5 0x7fe44ca60dff in negotiate_format ../spa/plugins/audioconvert/audioadapter.c:822
      #6 0x7fe44ca62bbf in impl_node_send_command ../spa/plugins/audioconvert/audioadapter.c:846
      #7 0x7fe45ea1c2f1 in node_update_state ../src/pipewire/impl-node.c:407
      #8 0x7fe45ea5137e in pw_impl_node_set_state ../src/pipewire/impl-node.c:2251
      #9 0x7fe45eb3355f in pw_work_queue_destroy ../src/pipewire/work-queue.c:142
      #10 0x7fe45b2cd6f4 in source_event_func ../spa/plugins/support/loop.c:615
      #11 0x7fe45b2c634f in loop_iterate ../spa/plugins/support/loop.c:452
      #12 0x7fe45e9ebebc in spa_hook_list_clean ../spa/include/spa/utils/hook.h:395
      #13 0x5561e03dc722 in main ../src/daemon/pipewire.c:131
      #14 0x7fe45da3c28f  (/usr/lib/libc.so.6+0x2328f)
      #15 0x7fe45da3c349 in __libc_start_main (/usr/lib/libc.so.6+0x23349)
      #16 0x5561e03db2a4 in _start ../sysdeps/x86_64/start.S:115

  Address 0x7ffdbcfef560 is located in stack of thread T0 at offset 160 in frame
      #0 0x7fe44ca56fa9 in configure_format ../spa/plugins/audioconvert/audioadapter.c:475

    This frame has 4 object(s):
      [32, 36) 'state' (line 493)
      [48, 56) 'fmt' (line 494)
      [80, 128) 'b' (line 492)
      [160, 4256) 'buffer' (line 491) <== Memory access at offset 160 is inside this variable
This commit is contained in:
Barnabás Pőcze 2022-12-10 02:43:13 +01:00 committed by Wim Taymans
parent 3bdd2e01c5
commit 8c892443eb

View file

@ -473,6 +473,7 @@ static int negotiate_buffers(struct impl *this)
static int configure_format(struct impl *this, uint32_t flags, const struct spa_pod *format) static int configure_format(struct impl *this, uint32_t flags, const struct spa_pod *format)
{ {
uint8_t buffer[4096];
int res; int res;
if (format == NULL && !this->have_format) if (format == NULL && !this->have_format)
@ -487,14 +488,13 @@ static int configure_format(struct impl *this, uint32_t flags, const struct spa_
SPA_PARAM_Format, flags, SPA_PARAM_Format, flags,
format)) < 0) format)) < 0)
return res; return res;
if (res > 0) { if (res > 0) {
uint8_t buffer[4096]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
struct spa_pod_builder b = { 0 };
uint32_t state = 0; uint32_t state = 0;
struct spa_pod *fmt; struct spa_pod *fmt;
/* format was changed to nearest compatible format */ /* format was changed to nearest compatible format */
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_port_enum_params_sync(this->follower, if ((res = spa_node_port_enum_params_sync(this->follower,
this->direction, 0, this->direction, 0,