s3:smbd: add vfs_valid_{pread,pwrite}_range() helper functions
authorStefan Metzmacher <metze@samba.org>
Mon, 11 May 2020 20:00:37 +0000 (22:00 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 12 May 2020 19:53:44 +0000 (19:53 +0000)
These implement the SMB2 visible behavior of the [MS-FSA]
2.1.5.2 Server Requests a Read and 2.1.5.3 Server Requests a Write
constraints. Note that offset < 0 is not allowed over SMB.

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/smbd/proto.h
source3/smbd/vfs.c

index 98eb2843c0702c9c6e6f6f1c11ca4d5e85e742c9..ba72fb94e0fc7dfee00fc7ac0bb4d44697e47e8a 100644 (file)
@@ -1295,6 +1295,8 @@ void sys_utmp_yield(const char *username, const char *hostname,
 bool vfs_init_custom(connection_struct *conn, const char *vfs_object);
 bool smbd_vfs_init(connection_struct *conn);
 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname);
+bool vfs_valid_pread_range(off_t offset, size_t length);
+bool vfs_valid_pwrite_range(off_t offset, size_t length);
 ssize_t vfs_pwrite_data(struct smb_request *req,
                        files_struct *fsp,
                        const char *buffer,
index 9c75ceed6aee8a4ffa473d05f0cd89ef6f0bf4bd..5141da728a78e39e774c886b57a0948cf4dec6f7 100644 (file)
@@ -32,6 +32,7 @@
 #include "ntioctl.h"
 #include "lib/util/tevent_unix.h"
 #include "lib/util/tevent_ntstatus.h"
+#include "lib/util/sys_rw.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -415,6 +416,37 @@ NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
+bool vfs_valid_pread_range(off_t offset, size_t length)
+{
+       return sys_valid_io_range(offset, length);
+}
+
+bool vfs_valid_pwrite_range(off_t offset, size_t length)
+{
+       /*
+        * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
+        */
+       static const uint64_t maxfilesize = 0xfffffff0000;
+       uint64_t last_byte_ofs;
+       bool ok;
+
+       ok = sys_valid_io_range(offset, length);
+       if (!ok) {
+               return false;
+       }
+
+       if (length == 0) {
+               return true;
+       }
+
+       last_byte_ofs = offset + length;
+       if (last_byte_ofs > maxfilesize) {
+               return false;
+       }
+
+       return true;
+}
+
 ssize_t vfs_pwrite_data(struct smb_request *req,
                        files_struct *fsp,
                        const char *buffer,