Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: meson-sm: Check for buffer output size

After the data is read by the secure monitor driver it is being copied
in the output buffer checking only the size of the bounce buffer but not
the size of the output buffer.

Fix this in the secure monitor driver slightly changing the API. Fix
also the efuse driver that it is the only driver using this API to not
break bisectability.

Signed-off-by: Carlo Caione <carlo@endlessm.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> # for nvmem
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>

authored by

Carlo Caione and committed by
Kevin Hilman
83e007a0 c1ae3cfa

+10 -6
+7 -3
drivers/firmware/meson/meson_sm.c
··· 127 127 * meson_sm_call_read - retrieve data from secure-monitor 128 128 * 129 129 * @buffer: Buffer to store the retrieved data 130 + * @bsize: Size of the buffer 130 131 * @cmd_index: Index of the SMC32 function ID 131 132 * @arg0: SMC32 Argument 0 132 133 * @arg1: SMC32 Argument 1 ··· 137 136 * 138 137 * Return: size of read data on success, a negative value on error 139 138 */ 140 - int meson_sm_call_read(void *buffer, unsigned int cmd_index, u32 arg0, 141 - u32 arg1, u32 arg2, u32 arg3, u32 arg4) 139 + int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 140 + u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 142 141 { 143 142 u32 size; 144 143 ··· 148 147 if (!fw.chip->cmd_shmem_out_base) 149 148 return -EINVAL; 150 149 150 + if (bsize > fw.chip->shmem_size) 151 + return -EINVAL; 152 + 151 153 if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) 152 154 return -EINVAL; 153 155 154 - if (!size || size > fw.chip->shmem_size) 156 + if (!size || size > bsize) 155 157 return -EINVAL; 156 158 157 159 if (buffer)
+1 -1
drivers/nvmem/meson-efuse.c
··· 27 27 u8 *buf = val; 28 28 int ret; 29 29 30 - ret = meson_sm_call_read(buf, SM_EFUSE_READ, offset, 30 + ret = meson_sm_call_read(buf, bytes, SM_EFUSE_READ, offset, 31 31 bytes, 0, 0, 0); 32 32 if (ret < 0) 33 33 return ret;
+2 -2
include/linux/firmware/meson/meson_sm.h
··· 25 25 u32 arg2, u32 arg3, u32 arg4); 26 26 int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index, 27 27 u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 28 - int meson_sm_call_read(void *buffer, unsigned int cmd_index, u32 arg0, u32 arg1, 29 - u32 arg2, u32 arg3, u32 arg4); 28 + int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 29 + u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 30 30 31 31 #endif /* _MESON_SM_FW_H_ */