nvadsp: Fix UBSAN array-index-out-of-bounds in msgq

Replace struct hack pattern with flexible array members in msgq_t
and msgq_message_t to resolve UBSAN warnings.

The message queue implementation was using the old "struct hack"
pattern with single-element arrays (int32_t queue[1] and
int32_t payload[1]) to create variable-length structures. While
functionally correct, this triggers UBSAN array-index-out-of-bounds
errors when accessing elements beyond index 0, even though the
memory is properly allocated.

UBSAN errors observed:
- msgq.c:64: index 2045 out of range for type 'int32_t [1]'
- msgq.c:69: index 153 out of range for type 'int32_t [1]'
- msgq.c:124: index 53 out of range for type 'int32_t [1]'
- msgq.c:148: index 53 out of range for type 'int32_t [1]'
- msgq.c:149: index 2045 out of range for type 'int32_t [1]'

Changes:
1. Convert queue[1] to queue[] in msgq_t structure
2. Convert payload[1] to payload[] in msgq_message_t structure
3. Update MSGQ_HEADER_SIZE and MSGQ_MESSAGE_HEADER_SIZE macros
   to use sizeof() directly, as flexible array members have zero
   size and cannot be used with sizeof()

The flexible array member (FAM) approach is:
- C99 standard compliant
- Linux kernel best practice for variable-length structures
- Binary compatible with the previous implementation
- Eliminates UBSAN false positives without functional changes

Bug 4831393

Change-Id: I243d4a1b1f091bf17cfc10337e75dbd1b878042f
Signed-off-by: Asha Talambedu <atalambedu@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3464624
Reviewed-by: Mohan kumar <mkumard@nvidia.com>
Reviewed-by: Viswanath L <viswanathl@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Asha Talambedu
2025-10-07 04:36:49 +00:00
committed by mobile promotions
parent 12c09aa934
commit eb29d03e62

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/** /**
* Copyright (c) 2014-2024, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2025, NVIDIA CORPORATION. All rights reserved.
*/ */
#ifndef __LINUX_TEGRA_NVADSP_H #ifndef __LINUX_TEGRA_NVADSP_H
@@ -90,11 +90,11 @@ struct nvadsp_mbox {
*/ */
typedef struct _msgq_message_t { typedef struct _msgq_message_t {
int32_t size; /* size of payload in words */ int32_t size; /* size of payload in words */
int32_t payload[1]; /* variable length payload */ int32_t payload[]; /* variable length payload */
} msgq_message_t; } msgq_message_t;
#define MSGQ_MESSAGE_HEADER_SIZE \ #define MSGQ_MESSAGE_HEADER_SIZE \
(sizeof(msgq_message_t) - sizeof(((msgq_message_t *)0)->payload)) (sizeof(msgq_message_t))
#define MSGQ_MESSAGE_HEADER_WSIZE \ #define MSGQ_MESSAGE_HEADER_WSIZE \
(MSGQ_MESSAGE_HEADER_SIZE / sizeof(int32_t)) (MSGQ_MESSAGE_HEADER_SIZE / sizeof(int32_t))
@@ -102,10 +102,10 @@ typedef struct _msgq_t {
int32_t size; /* queue size in words */ int32_t size; /* queue size in words */
int32_t write_index; /* queue write index */ int32_t write_index; /* queue write index */
int32_t read_index; /* queue read index */ int32_t read_index; /* queue read index */
int32_t queue[1]; /* variable length queue */ int32_t queue[]; /* variable length queue */
} msgq_t; } msgq_t;
#define MSGQ_HEADER_SIZE (sizeof(msgq_t) - sizeof(((msgq_t *)0)->queue)) #define MSGQ_HEADER_SIZE (sizeof(msgq_t))
#define MSGQ_HEADER_WSIZE (MSGQ_HEADER_SIZE / sizeof(int32_t)) #define MSGQ_HEADER_WSIZE (MSGQ_HEADER_SIZE / sizeof(int32_t))
#define MSGQ_MAX_QUEUE_WSIZE (8192 - MSGQ_HEADER_WSIZE) #define MSGQ_MAX_QUEUE_WSIZE (8192 - MSGQ_HEADER_WSIZE)
#define MSGQ_MSG_WSIZE(x) \ #define MSGQ_MSG_WSIZE(x) \