mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
A bug was introduced with the refactoring in da26563. In arm_init,
the buffer passed to spa_cpu_read_file is allocated and it is just
going to return that. So cpuinfo will actually point to buffer on
the stack, which need not be freed with a call to free.
The crash resulting with the incorrect free.
root@dragonboard-845c:~# pipewire --version
munmap_chunk(): invalid pointer
[ 185.037284] audit: type=1701 audit(1659949975.843:14): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=2243 comm="pipewire" exe="/usr/bin/pipewire" sig=6 res=1
Aborted
root@dragonboard-845c:~# wireplumber --version
munmap_chunk(): invalid pointer
[ 193.453693] audit: type=1701 audit(1659949984.255:15): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=2244 comm="wireplumber" exe="/usr/bin/wireplumber" sig=6 res=1
Aborted
Backtrace from the crash
(gdb) bt
!0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
!1 0x0000fffff7d8edd8 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
!2 0x0000fffff7d4a390 in __GI_raise (sig=sig@entry=6) at /usr/src/debug/glibc/2.36-r0/sysdeps/posix/raise.c:26
!3 0x0000fffff7d37498 in __GI_abort () at abort.c:79
!4 0x0000fffff7d83374 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0xfffff7e5fc20 "%s\n") at /usr/src/debug/glibc/2.36-r0/sysdeps/posix/libc_fatal.c:155
!5 0x0000fffff7d988c0 in malloc_printerr (str=str@entry=0xfffff7e5a7f0 "munmap_chunk(): invalid pointer") at malloc.c:5660
!6 0x0000fffff7d98aac in munmap_chunk (p=p@entry=0xffffffffd258) at malloc.c:3054
!7 0x0000fffff7d9d068 in __GI___libc_free (mem=mem@entry=0xffffffffd268) at malloc.c:3375
!8 0x0000fffff7cd36cc in arm_init (impl=impl@entry=0xaaaaaaac8c48) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c:97
!9 0x0000fffff7cd391c in impl_init (factory=<optimized out>, handle=0xaaaaaaac8c48, info=0xffffffffe548, support=<optimized out>, n_support=<optimized out>) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu.c:264
!10 0x0000fffff7f3a234 in load_spa_handle (lib=<optimized out>, factory_name=factory_name@entry=0xfffff7f6d768 "support.cpu", info=info@entry=0xffffffffe548, n_support=1,
support=support@entry=0xfffff7fb0488 <global_support+88>) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:280
!11 0x0000fffff7f3a5b0 in add_interface (factory_name=factory_name@entry=0xfffff7f6d768 "support.cpu", type=type@entry=0xfffff7f62310 "Spa:Pointer:Interface:CPU", info=info@entry=0xffffffffe548,
support=0xfffff7fb0430 <global_support>) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:358
!12 0x0000fffff7f3b3f8 in pw_init (argc=argc@entry=0xffffffffea5c, argv=argv@entry=0xffffffffea50) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:661
!13 0x0000aaaaaaaa1104 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pipewire/1.0-r0/src/daemon/pipewire.c:79
(gdb) f 8
!8 0x0000fffff7cd36cc in arm_init (impl=impl@entry=0xaaaaaaac8c48) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c:97
97 /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c: No such file or directory.
(gdb) info locals
flags = 122
cpuinfo = 0xffffffffd268 "processor\t: 0\nBogoMIPS\t: 38.40\nFeatures\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop\nCPU implementer\t: 0x51\nCPU architecture: 8\nCPU variant\t.
line = 0xaaaaaaac8ce0 "\310\252\252\252\n"
buffer = "processor\t: 0\nBogoMIPS\t: 38.40\nFeatures\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop\nCPU implementer\t: 0x51\nCPU architecture: 8\nCPU variant\t: 0x7\nCPU pa"...
arch = <optimized out>
__func__ = "arm_init"
137 lines
3.4 KiB
C
137 lines
3.4 KiB
C
/* Spa
|
|
*
|
|
* Copyright © 2019 Wim Taymans
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <spa/utils/string.h>
|
|
|
|
#define MAX_BUFFER 4096
|
|
|
|
static char *get_cpuinfo_line(char *cpuinfo, const char *tag)
|
|
{
|
|
char *line, *end, *colon;
|
|
|
|
if (!(line = strstr(cpuinfo, tag)))
|
|
return NULL;
|
|
|
|
if (!(end = strchr(line, '\n')))
|
|
return NULL;
|
|
|
|
if (!(colon = strchr(line, ':')))
|
|
return NULL;
|
|
|
|
if (++colon >= end)
|
|
return NULL;
|
|
|
|
return strndup(colon, end - colon);
|
|
}
|
|
|
|
static int
|
|
arm_init(struct impl *impl)
|
|
{
|
|
uint32_t flags = 0;
|
|
char *cpuinfo, *line, buffer[MAX_BUFFER];
|
|
int arch;
|
|
|
|
if (!(cpuinfo = spa_cpu_read_file("/proc/cpuinfo", buffer, sizeof(buffer)))) {
|
|
spa_log_warn(impl->log, "%p: Can't read cpuinfo", impl);
|
|
return 1;
|
|
}
|
|
|
|
if ((line = get_cpuinfo_line(cpuinfo, "CPU architecture"))) {
|
|
arch = strtoul(line, NULL, 0);
|
|
if (arch >= 6)
|
|
flags |= SPA_CPU_FLAG_ARMV6;
|
|
if (arch >= 8)
|
|
flags |= SPA_CPU_FLAG_ARMV8;
|
|
|
|
free(line);
|
|
}
|
|
|
|
if ((line = get_cpuinfo_line(cpuinfo, "Features"))) {
|
|
char *state = NULL;
|
|
char *current = strtok_r(line, " ", &state);
|
|
|
|
do {
|
|
#if defined (__aarch64__)
|
|
if (spa_streq(current, "asimd"))
|
|
flags |= SPA_CPU_FLAG_NEON;
|
|
else if (spa_streq(current, "fp"))
|
|
flags |= SPA_CPU_FLAG_VFPV3 | SPA_CPU_FLAG_VFP;
|
|
#else
|
|
if (spa_streq(current, "vfp"))
|
|
flags |= SPA_CPU_FLAG_VFP;
|
|
else if (spa_streq(current, "neon"))
|
|
flags |= SPA_CPU_FLAG_NEON;
|
|
else if (spa_streq(current, "vfpv3"))
|
|
flags |= SPA_CPU_FLAG_VFPV3;
|
|
#endif
|
|
} while ((current = strtok_r(NULL, " ", &state)));
|
|
|
|
free(line);
|
|
}
|
|
|
|
impl->flags = flags;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int arm_zero_denormals(void *object, bool enable)
|
|
{
|
|
#if defined(__aarch64__)
|
|
uint64_t cw;
|
|
if (enable)
|
|
__asm__ __volatile__(
|
|
"mrs %0, fpcr \n"
|
|
"orr %0, %0, #0x1000000 \n"
|
|
"msr fpcr, %0 \n"
|
|
"isb \n"
|
|
: "=r"(cw)::"memory");
|
|
else
|
|
__asm__ __volatile__(
|
|
"mrs %0, fpcr \n"
|
|
"and %0, %0, #~0x1000000 \n"
|
|
"msr fpcr, %0 \n"
|
|
"isb \n"
|
|
: "=r"(cw)::"memory");
|
|
#elif (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
|
uint32_t cw;
|
|
if (enable)
|
|
__asm__ __volatile__(
|
|
"vmrs %0, fpscr \n"
|
|
"orr %0, %0, #0x1000000 \n"
|
|
"vmsr fpscr, %0 \n"
|
|
: "=r"(cw)::"memory");
|
|
else
|
|
__asm__ __volatile__(
|
|
"vmrs %0, fpscr \n"
|
|
"and %0, %0, #~0x1000000 \n"
|
|
"vmsr fpscr, %0 \n"
|
|
: "=r"(cw)::"memory");
|
|
#endif
|
|
return 0;
|
|
}
|