From abcf70538d55b81288968f84d8d1b44fc928ce40 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 30 Jul 2025 18:10:09 +0200 Subject: [PATCH] pod: add barrier around memcpy We need to be sure that the compiler does not perform invented loads after we checked the pod size. Otherwise we could have found that the size was ok, only to be overwritten by an invalid size. One way of avoiding this is to surround the memcpy with a barrier. See #4822 --- spa/include/spa/pod/parser.h | 5 +++++ spa/include/spa/utils/defs.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/spa/include/spa/pod/parser.h b/spa/include/spa/pod/parser.h index e01bf91aa..909431e1c 100644 --- a/spa/include/spa/pod/parser.h +++ b/spa/include/spa/pod/parser.h @@ -90,7 +90,12 @@ spa_pod_parser_read_header(struct spa_pod_parser *parser, uint32_t offset, uint3 /* Cast to uint64_t to avoid wraparound. */ const uint64_t long_offset = (uint64_t)offset + header_size; if (long_offset <= size && (offset & 7) == 0) { + /* a barrier around the memcpy to make sure it is not moved around or + * duplicated after the size check below. We need to to work on shared + * memory while there could be updates happening while we read. */ + SPA_BARRIER; memcpy(header, SPA_PTROFF(parser->data, offset, void), header_size); + SPA_BARRIER; struct spa_pod *pod = SPA_PTROFF(header, pod_offset, struct spa_pod); /* Check that the size (rounded to the next multiple of 8) is in bounds. */ if (long_offset + SPA_ROUND_UP_N((uint64_t)pod->size, SPA_POD_ALIGN) <= size) { diff --git a/spa/include/spa/utils/defs.h b/spa/include/spa/utils/defs.h index 55bf9ad97..371b1e658 100644 --- a/spa/include/spa/utils/defs.h +++ b/spa/include/spa/utils/defs.h @@ -242,6 +242,7 @@ struct spa_fraction { #define SPA_UNUSED __attribute__ ((unused)) #define SPA_NORETURN __attribute__ ((noreturn)) #define SPA_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#define SPA_BARRIER __asm__ __volatile__("": : :"memory") #else #define SPA_PRINTF_FUNC(fmt, arg1) #define SPA_FORMAT_ARG_FUNC(arg1) @@ -252,6 +253,7 @@ struct spa_fraction { #define SPA_UNUSED #define SPA_NORETURN #define SPA_WARN_UNUSED_RESULT +#define SPA_BARRIER #endif #ifndef SPA_API_IMPL