From: Stefan Metzmacher Date: Mon, 11 May 2020 20:00:37 +0000 (+0200) Subject: s3:smbd: add vfs_valid_{pread,pwrite}_range() helper functions X-Git-Tag: ldb-2.2.0~544 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=70fa4b884d2c22669984c25fe757c2fc528f7331;p=thirdparty%2Fsamba.git s3:smbd: add vfs_valid_{pread,pwrite}_range() helper functions 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 Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 98eb2843c07..ba72fb94e0f 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -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, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 9c75ceed6ae..5141da728a7 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -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,