vfs_io_uring: protect vfs_io_uring_pread_completion() against invalid results
authorStefan Metzmacher <metze@samba.org>
Fri, 8 May 2020 09:38:56 +0000 (11:38 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 12 May 2020 19:53:45 +0000 (19:53 +0000)
We should never get back more than we asked for.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14361

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_io_uring.c

index 3e004f48aa0c4090a29444f9b711728dcd68792a..46fab116e9de5cd80d34232eea4bbac8a4a7186b 100644 (file)
@@ -26,6 +26,7 @@
 #include "smbd/globals.h"
 #include "lib/util/tevent_unix.h"
 #include "lib/util/sys_rw.h"
+#include "lib/util/iov_buf.h"
 #include "smbprofile.h"
 #include <liburing.h>
 
@@ -472,6 +473,9 @@ static void vfs_io_uring_pread_completion(struct vfs_io_uring_request *cur,
 {
        struct vfs_io_uring_pread_state *state = tevent_req_data(
                cur->req, struct vfs_io_uring_pread_state);
+       struct iovec *iov = &state->iov;
+       int num_iov = 1;
+       bool ok;
 
        /*
         * We rely on being inside the _send() function
@@ -485,6 +489,16 @@ static void vfs_io_uring_pread_completion(struct vfs_io_uring_request *cur,
                return;
        }
 
+       ok = iov_advance(&iov, &num_iov, cur->cqe.res);
+       if (!ok) {
+               /* This is not expected! */
+               DBG_ERR("iov_advance() failed cur->cqe.res=%d > iov_len=%d\n",
+                       (int)cur->cqe.res,
+                       (int)state->iov.iov_len);
+               tevent_req_error(cur->req, EIO);
+               return;
+       }
+
        state->nread = state->ur.cqe.res;
        tevent_req_done(cur->req);
 }