Skip to content

Commit 88c4bd9

Browse files
Michal Wilczynskistorulf
authored andcommitted
firmware: thead: Fix buffer overflow and use standard endian macros
Addresses two issues in the TH1520 AON firmware protocol driver: 1. Fix a potential buffer overflow where the code used unsafe pointer arithmetic to access the 'mode' field through the 'resource' pointer with an offset. This was flagged by Smatch static checker as: "buffer overflow 'data' 2 <= 3" 2. Replace custom RPC_SET_BE* and RPC_GET_BE* macros with standard kernel endianness conversion macros (cpu_to_be16, etc.) for better portability and maintainability. The functionality was re-tested with the GPU power-up sequence, confirming the GPU powers up correctly and the driver probes successfully. [ 12.702370] powervr ffef400000.gpu: [drm] loaded firmware powervr/rogue_36.52.104.182_v1.fw [ 12.711043] powervr ffef400000.gpu: [drm] FW version v1.0 (build 6645434 OS) [ 12.719787] [drm] Initialized powervr 1.0.0 for ffef400000.gpu on minor 0 Fixes: e4b3cbd ("firmware: thead: Add AON firmware protocol driver") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/17a0ccce-060b-4b9d-a3c4-8d5d5823b1c9@stanley.mountain/ Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com> Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org> Acked-by: Drew Fustini <fustini@kernel.org> Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 7aaa804 commit 88c4bd9

2 files changed

Lines changed: 3 additions & 78 deletions

File tree

drivers/firmware/thead,th1520-aon.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,9 @@ int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc,
170170
hdr->func = TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE;
171171
hdr->size = TH1520_AON_RPC_MSG_NUM;
172172

173-
RPC_SET_BE16(&msg.resource, 0, rsrc);
174-
RPC_SET_BE16(&msg.resource, 2,
175-
(power_on ? TH1520_AON_PM_PW_MODE_ON :
176-
TH1520_AON_PM_PW_MODE_OFF));
173+
msg.resource = cpu_to_be16(rsrc);
174+
msg.mode = cpu_to_be16(power_on ? TH1520_AON_PM_PW_MODE_ON :
175+
TH1520_AON_PM_PW_MODE_OFF);
177176

178177
ret = th1520_aon_call_rpc(aon_chan, &msg);
179178
if (ret)

include/linux/firmware/thead/thead,th1520-aon.h

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -97,80 +97,6 @@ struct th1520_aon_rpc_ack_common {
9797
#define RPC_GET_SVC_FLAG_ACK_TYPE(MESG) (((MESG)->svc & 0x40) >> 6)
9898
#define RPC_SET_SVC_FLAG_ACK_TYPE(MESG, ACK) ((MESG)->svc |= (ACK) << 6)
9999

100-
#define RPC_SET_BE64(MESG, OFFSET, SET_DATA) \
101-
do { \
102-
u8 *data = (u8 *)(MESG); \
103-
u64 _offset = (OFFSET); \
104-
u64 _set_data = (SET_DATA); \
105-
data[_offset + 7] = _set_data & 0xFF; \
106-
data[_offset + 6] = (_set_data & 0xFF00) >> 8; \
107-
data[_offset + 5] = (_set_data & 0xFF0000) >> 16; \
108-
data[_offset + 4] = (_set_data & 0xFF000000) >> 24; \
109-
data[_offset + 3] = (_set_data & 0xFF00000000) >> 32; \
110-
data[_offset + 2] = (_set_data & 0xFF0000000000) >> 40; \
111-
data[_offset + 1] = (_set_data & 0xFF000000000000) >> 48; \
112-
data[_offset + 0] = (_set_data & 0xFF00000000000000) >> 56; \
113-
} while (0)
114-
115-
#define RPC_SET_BE32(MESG, OFFSET, SET_DATA) \
116-
do { \
117-
u8 *data = (u8 *)(MESG); \
118-
u64 _offset = (OFFSET); \
119-
u64 _set_data = (SET_DATA); \
120-
data[_offset + 3] = (_set_data) & 0xFF; \
121-
data[_offset + 2] = (_set_data & 0xFF00) >> 8; \
122-
data[_offset + 1] = (_set_data & 0xFF0000) >> 16; \
123-
data[_offset + 0] = (_set_data & 0xFF000000) >> 24; \
124-
} while (0)
125-
126-
#define RPC_SET_BE16(MESG, OFFSET, SET_DATA) \
127-
do { \
128-
u8 *data = (u8 *)(MESG); \
129-
u64 _offset = (OFFSET); \
130-
u64 _set_data = (SET_DATA); \
131-
data[_offset + 1] = (_set_data) & 0xFF; \
132-
data[_offset + 0] = (_set_data & 0xFF00) >> 8; \
133-
} while (0)
134-
135-
#define RPC_SET_U8(MESG, OFFSET, SET_DATA) \
136-
do { \
137-
u8 *data = (u8 *)(MESG); \
138-
data[OFFSET] = (SET_DATA) & 0xFF; \
139-
} while (0)
140-
141-
#define RPC_GET_BE64(MESG, OFFSET, PTR) \
142-
do { \
143-
u8 *data = (u8 *)(MESG); \
144-
u64 _offset = (OFFSET); \
145-
*(u32 *)(PTR) = \
146-
(data[_offset + 7] | data[_offset + 6] << 8 | \
147-
data[_offset + 5] << 16 | data[_offset + 4] << 24 | \
148-
data[_offset + 3] << 32 | data[_offset + 2] << 40 | \
149-
data[_offset + 1] << 48 | data[_offset + 0] << 56); \
150-
} while (0)
151-
152-
#define RPC_GET_BE32(MESG, OFFSET, PTR) \
153-
do { \
154-
u8 *data = (u8 *)(MESG); \
155-
u64 _offset = (OFFSET); \
156-
*(u32 *)(PTR) = \
157-
(data[_offset + 3] | data[_offset + 2] << 8 | \
158-
data[_offset + 1] << 16 | data[_offset + 0] << 24); \
159-
} while (0)
160-
161-
#define RPC_GET_BE16(MESG, OFFSET, PTR) \
162-
do { \
163-
u8 *data = (u8 *)(MESG); \
164-
u64 _offset = (OFFSET); \
165-
*(u16 *)(PTR) = (data[_offset + 1] | data[_offset + 0] << 8); \
166-
} while (0)
167-
168-
#define RPC_GET_U8(MESG, OFFSET, PTR) \
169-
do { \
170-
u8 *data = (u8 *)(MESG); \
171-
*(u8 *)(PTR) = (data[OFFSET]); \
172-
} while (0)
173-
174100
/*
175101
* Defines for SC PM Power Mode
176102
*/

0 commit comments

Comments
 (0)