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