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

ASoC: SOF: ipc-msg-injector: fix copy in sof_msg_inject_ipc4_dfs_write()

There are two bugs that have to do with when we copy the payload:

size = simple_write_to_buffer(ipc4_msg->data_ptr,
priv->max_msg_size, ppos, buffer,
count);

The value of "*ppos" was supposed to be zero but it is
sizeof(ipc4_msg->header_u64) so it will copy the data into the middle of
the "ipc4_msg->data_ptr" buffer instead of to the start. The second
problem is "buffer" should be "buffer + sizeof(ipc4_msg->header_u64)".

This function is used for fuzz testing so the data is normally random
and this bug likely does not affect anyone very much.

In this context, it's simpler and more appropriate to use copy_from_user()
instead of simple_write_to_buffer() so I have re-written the function.

Fixes: 066c67624d8c ("ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/Ysg1tB2FKLnRMsel@kili
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Dan Carpenter and committed by
Mark Brown
fa9b878f 09cf6054

+12 -17
+12 -17
sound/soc/sof/sof-client-ipc-msg-injector.c
··· 181 181 struct sof_client_dev *cdev = file->private_data; 182 182 struct sof_msg_inject_priv *priv = cdev->data; 183 183 struct sof_ipc4_msg *ipc4_msg = priv->tx_buffer; 184 - ssize_t size; 184 + size_t data_size; 185 185 int ret; 186 186 187 187 if (*ppos) ··· 191 191 return -EINVAL; 192 192 193 193 /* copy the header first */ 194 - size = simple_write_to_buffer(&ipc4_msg->header_u64, 195 - sizeof(ipc4_msg->header_u64), 196 - ppos, buffer, count); 197 - if (size < 0) 198 - return size; 199 - if (size != sizeof(ipc4_msg->header_u64)) 194 + if (copy_from_user(&ipc4_msg->header_u64, buffer, 195 + sizeof(ipc4_msg->header_u64))) 200 196 return -EFAULT; 201 197 202 - count -= size; 198 + data_size = count - sizeof(ipc4_msg->header_u64); 199 + if (data_size > priv->max_msg_size) 200 + return -EINVAL; 201 + 203 202 /* Copy the payload */ 204 - size = simple_write_to_buffer(ipc4_msg->data_ptr, 205 - priv->max_msg_size, ppos, buffer, 206 - count); 207 - if (size < 0) 208 - return size; 209 - if (size != count) 203 + if (copy_from_user(ipc4_msg->data_ptr, 204 + buffer + sizeof(ipc4_msg->header_u64), data_size)) 210 205 return -EFAULT; 211 206 212 - ipc4_msg->data_size = count; 207 + ipc4_msg->data_size = data_size; 213 208 214 209 /* Initialize the reply storage */ 215 210 ipc4_msg = priv->rx_buffer; ··· 216 221 217 222 /* return the error code if test failed */ 218 223 if (ret < 0) 219 - size = ret; 224 + return ret; 220 225 221 - return size; 226 + return count; 222 227 }; 223 228 224 229 static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file)