io_uring/net.c:206:25: sparse: sparse: incorrect type in assignment (different address spaces)

From: kernel test robot
Date: Tue Jun 20 2023 - 18:05:49 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 692b7dc87ca6d55ab254f8259e6f970171dc9d01
commit: cac9e4418f4cbd548ccb065b3adcafe073f7f7d2 io_uring/net: save msghdr->msg_control for retries
date: 7 days ago
config: i386-randconfig-s001-20230620 (https://download.01.org/0day-ci/archive/20230621/202306210654.mDMcyMuB-lkp@xxxxxxxxx/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230621/202306210654.mDMcyMuB-lkp@xxxxxxxxx/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306210654.mDMcyMuB-lkp@xxxxxxxxx/

sparse warnings: (new ones prefixed by >>)
io_uring/net.c: note: in included file (through io_uring/io_uring.h):
include/linux/io_uring_types.h:179:37: sparse: sparse: array of flexible structures
>> io_uring/net.c:206:25: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected void [noderef] __user *msg_control @@ got void *msg_control @@
io_uring/net.c:206:25: sparse: expected void [noderef] __user *msg_control
io_uring/net.c:206:25: sparse: got void *msg_control
>> io_uring/net.c:305:39: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected void *msg_control @@ got void [noderef] __user *msg_control @@
io_uring/net.c:305:39: sparse: expected void *msg_control
io_uring/net.c:305:39: sparse: got void [noderef] __user *msg_control

vim +206 io_uring/net.c

194
195 static int io_sendmsg_copy_hdr(struct io_kiocb *req,
196 struct io_async_msghdr *iomsg)
197 {
198 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
199 int ret;
200
201 iomsg->msg.msg_name = &iomsg->addr;
202 iomsg->free_iov = iomsg->fast_iov;
203 ret = sendmsg_copy_msghdr(&iomsg->msg, sr->umsg, sr->msg_flags,
204 &iomsg->free_iov);
205 /* save msg_control as sys_sendmsg() overwrites it */
> 206 sr->msg_control = iomsg->msg.msg_control;
207 return ret;
208 }
209
210 int io_send_prep_async(struct io_kiocb *req)
211 {
212 struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
213 struct io_async_msghdr *io;
214 int ret;
215
216 if (!zc->addr || req_has_async_data(req))
217 return 0;
218 io = io_msg_alloc_async_prep(req);
219 if (!io)
220 return -ENOMEM;
221 ret = move_addr_to_kernel(zc->addr, zc->addr_len, &io->addr);
222 return ret;
223 }
224
225 static int io_setup_async_addr(struct io_kiocb *req,
226 struct sockaddr_storage *addr_storage,
227 unsigned int issue_flags)
228 {
229 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
230 struct io_async_msghdr *io;
231
232 if (!sr->addr || req_has_async_data(req))
233 return -EAGAIN;
234 io = io_msg_alloc_async(req, issue_flags);
235 if (!io)
236 return -ENOMEM;
237 memcpy(&io->addr, addr_storage, sizeof(io->addr));
238 return -EAGAIN;
239 }
240
241 int io_sendmsg_prep_async(struct io_kiocb *req)
242 {
243 int ret;
244
245 if (!io_msg_alloc_async_prep(req))
246 return -ENOMEM;
247 ret = io_sendmsg_copy_hdr(req, req->async_data);
248 if (!ret)
249 req->flags |= REQ_F_NEED_CLEANUP;
250 return ret;
251 }
252
253 void io_sendmsg_recvmsg_cleanup(struct io_kiocb *req)
254 {
255 struct io_async_msghdr *io = req->async_data;
256
257 kfree(io->free_iov);
258 }
259
260 int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
261 {
262 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
263
264 if (req->opcode == IORING_OP_SEND) {
265 if (READ_ONCE(sqe->__pad3[0]))
266 return -EINVAL;
267 sr->addr = u64_to_user_ptr(READ_ONCE(sqe->addr2));
268 sr->addr_len = READ_ONCE(sqe->addr_len);
269 } else if (sqe->addr2 || sqe->file_index) {
270 return -EINVAL;
271 }
272
273 sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
274 sr->len = READ_ONCE(sqe->len);
275 sr->flags = READ_ONCE(sqe->ioprio);
276 if (sr->flags & ~IORING_RECVSEND_POLL_FIRST)
277 return -EINVAL;
278 sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL;
279 if (sr->msg_flags & MSG_DONTWAIT)
280 req->flags |= REQ_F_NOWAIT;
281
282 #ifdef CONFIG_COMPAT
283 if (req->ctx->compat)
284 sr->msg_flags |= MSG_CMSG_COMPAT;
285 #endif
286 sr->done_io = 0;
287 return 0;
288 }
289
290 int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
291 {
292 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
293 struct io_async_msghdr iomsg, *kmsg;
294 struct socket *sock;
295 unsigned flags;
296 int min_ret = 0;
297 int ret;
298
299 sock = sock_from_file(req->file);
300 if (unlikely(!sock))
301 return -ENOTSOCK;
302
303 if (req_has_async_data(req)) {
304 kmsg = req->async_data;
> 305 kmsg->msg.msg_control = sr->msg_control;
306 } else {
307 ret = io_sendmsg_copy_hdr(req, &iomsg);
308 if (ret)
309 return ret;
310 kmsg = &iomsg;
311 }
312
313 if (!(req->flags & REQ_F_POLLED) &&
314 (sr->flags & IORING_RECVSEND_POLL_FIRST))
315 return io_setup_async_msg(req, kmsg, issue_flags);
316
317 flags = sr->msg_flags;
318 if (issue_flags & IO_URING_F_NONBLOCK)
319 flags |= MSG_DONTWAIT;
320 if (flags & MSG_WAITALL)
321 min_ret = iov_iter_count(&kmsg->msg.msg_iter);
322
323 ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags);
324
325 if (ret < min_ret) {
326 if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
327 return io_setup_async_msg(req, kmsg, issue_flags);
328 if (ret > 0 && io_net_retry(sock, flags)) {
329 sr->done_io += ret;
330 req->flags |= REQ_F_PARTIAL_IO;
331 return io_setup_async_msg(req, kmsg, issue_flags);
332 }
333 if (ret == -ERESTARTSYS)
334 ret = -EINTR;
335 req_set_fail(req);
336 }
337 /* fast path, check for non-NULL to avoid function call */
338 if (kmsg->free_iov)
339 kfree(kmsg->free_iov);
340 req->flags &= ~REQ_F_NEED_CLEANUP;
341 io_netmsg_recycle(req, issue_flags);
342 if (ret >= 0)
343 ret += sr->done_io;
344 else if (sr->done_io)
345 ret = sr->done_io;
346 io_req_set_res(req, ret, 0);
347 return IOU_OK;
348 }
349

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki