Skip to content

Commit

Permalink
smb3: fix ksmbd bigendian bug in oplock break, and move its struct to…
Browse files Browse the repository at this point in the history
… smbfs_common

Fix an endian bug in ksmbd for one remaining use of
Persistent/VolatileFid that unnecessarily converted it (it is an
opaque endian field that does not need to be and should not
be converted) in oplock_break for ksmbd, and move the definitions
for the oplock and lease break protocol requests and responses
to fs/smbfs_common/smb2pdu.h

Also move a few more definitions for various protocol requests
that were duplicated (in fs/cifs/smb2pdu.h and fs/ksmbd/smb2pdu.h)
into fs/smbfs_common/smb2pdu.h including:

- various ioctls and reparse structures
- validate negotiate request and response structs
- duplicate extents structs

Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Steve French committed Mar 31, 2022
1 parent fdf59eb commit c7803b0
Showing 5 changed files with 119 additions and 191 deletions.
112 changes: 0 additions & 112 deletions fs/cifs/smb2pdu.h
Original file line number Diff line number Diff line change
@@ -229,12 +229,6 @@ struct copychunk_ioctl {
__u32 Reserved2;
} __packed;

/* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */
struct file_zero_data_information {
__le64 FileOffset;
__le64 BeyondFinalZero;
} __packed;

struct copychunk_ioctl_rsp {
__le32 ChunksWritten;
__le32 ChunkBytesWritten;
@@ -288,53 +282,6 @@ struct fsctl_get_integrity_information_rsp {
/* Integrity flags for above */
#define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001

/* Reparse structures - see MS-FSCC 2.1.2 */

/* struct fsctl_reparse_info_req is empty, only response structs (see below) */

struct reparse_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 DataBuffer[]; /* Variable Length */
} __packed;

struct reparse_guid_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 ReparseGuid[16];
__u8 DataBuffer[]; /* Variable Length */
} __packed;

struct reparse_mount_point_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__u8 PathBuffer[]; /* Variable Length */
} __packed;

#define SYMLINK_FLAG_RELATIVE 0x00000001

struct reparse_symlink_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__le32 Flags;
__u8 PathBuffer[]; /* Variable Length */
} __packed;

/* See MS-FSCC 2.1.2.6 and cifspdu.h for struct reparse_posix_data */


/* See MS-DFSC 2.2.2 */
struct fsctl_get_dfs_referral_req {
__le16 MaxReferralLevel;
@@ -350,22 +297,6 @@ struct network_resiliency_req {
} __packed;
/* There is no buffer for the response ie no struct network_resiliency_rsp */


struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
} __packed;

struct validate_negotiate_info_rsp {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 Dialect; /* Dialect in use for the connection */
} __packed;

#define RSS_CAPABLE cpu_to_le32(0x00000001)
#define RDMA_CAPABLE cpu_to_le32(0x00000002)

@@ -401,56 +332,13 @@ struct compress_ioctl {
__le16 CompressionState; /* See cifspdu.h for possible flag values */
} __packed;

struct duplicate_extents_to_file {
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
__u64 VolatileFileHandle;
__le64 SourceFileOffset;
__le64 TargetFileOffset;
__le64 ByteCount; /* Bytes to be copied */
} __packed;

/*
* Maximum number of iovs we need for an ioctl request.
* [0] : struct smb2_ioctl_req
* [1] : in_data
*/
#define SMB2_IOCTL_IOV_SIZE 2

struct smb2_oplock_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 24 */
__u8 OplockLevel;
__u8 Reserved;
__le32 Reserved2;
__u64 PersistentFid;
__u64 VolatileFid;
} __packed;

#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)

struct smb2_lease_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 44 */
__le16 Epoch;
__le32 Flags;
__u8 LeaseKey[16];
__le32 CurrentLeaseState;
__le32 NewLeaseState;
__le32 BreakReason;
__le32 AccessMaskHint;
__le32 ShareMaskHint;
} __packed;

struct smb2_lease_ack {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
__le16 Reserved;
__le32 Flags;
__u8 LeaseKey[16];
__le32 LeaseState;
__le64 LeaseDuration;
} __packed;

/*
* PDU query infolevel structure definitions
* BB consider moving to a different header
4 changes: 2 additions & 2 deletions fs/ksmbd/oplock.c
Original file line number Diff line number Diff line change
@@ -656,8 +656,8 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
rsp->Reserved = 0;
rsp->Reserved2 = 0;
rsp->PersistentFid = cpu_to_le64(fp->persistent_id);
rsp->VolatileFid = cpu_to_le64(fp->volatile_id);
rsp->PersistentFid = fp->persistent_id;
rsp->VolatileFid = fp->volatile_id;

inc_rfc1001_len(work->response_buf, 24);

8 changes: 4 additions & 4 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
@@ -7887,8 +7887,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
char req_oplevel = 0, rsp_oplevel = 0;
unsigned int oplock_change_type;

volatile_id = le64_to_cpu(req->VolatileFid);
persistent_id = le64_to_cpu(req->PersistentFid);
volatile_id = req->VolatileFid;
persistent_id = req->PersistentFid;
req_oplevel = req->OplockLevel;
ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n",
volatile_id, persistent_id, req_oplevel);
@@ -7983,8 +7983,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
rsp->OplockLevel = rsp_oplevel;
rsp->Reserved = 0;
rsp->Reserved2 = 0;
rsp->VolatileFid = cpu_to_le64(volatile_id);
rsp->PersistentFid = cpu_to_le64(persistent_id);
rsp->VolatileFid = volatile_id;
rsp->PersistentFid = persistent_id;
inc_rfc1001_len(work->response_buf, 24);
return;

73 changes: 0 additions & 73 deletions fs/ksmbd/smb2pdu.h
Original file line number Diff line number Diff line change
@@ -169,29 +169,6 @@ struct smb2_buffer_desc_v1 {

#define SMB2_0_IOCTL_IS_FSCTL 0x00000001

struct duplicate_extents_to_file {
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
__u64 VolatileFileHandle;
__le64 SourceFileOffset;
__le64 TargetFileOffset;
__le64 ByteCount; /* Bytes to be copied */
} __packed;

struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[1]; /* dialect (someday maybe list) client asked for */
} __packed;

struct validate_negotiate_info_rsp {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 Dialect; /* Dialect in use for the connection */
} __packed;

struct smb_sockaddr_in {
__be16 Port;
__be32 IPv4address;
@@ -265,18 +242,6 @@ struct file_sparse {
__u8 SetSparse;
} __packed;

struct file_zero_data_information {
__le64 FileOffset;
__le64 BeyondFinalZero;
} __packed;

struct reparse_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 DataBuffer[]; /* Variable Length */
} __packed;

/* FILE Info response size */
#define FILE_DIRECTORY_INFORMATION_SIZE 1
#define FILE_FULL_DIRECTORY_INFORMATION_SIZE 2
@@ -332,49 +297,11 @@ struct fs_type_info {
long magic_number;
} __packed;

struct smb2_oplock_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 24 */
__u8 OplockLevel;
__u8 Reserved;
__le32 Reserved2;
__le64 PersistentFid;
__le64 VolatileFid;
} __packed;

#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)

struct smb2_lease_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 44 */
__le16 Epoch;
__le32 Flags;
__u8 LeaseKey[16];
__le32 CurrentLeaseState;
__le32 NewLeaseState;
__le32 BreakReason;
__le32 AccessMaskHint;
__le32 ShareMaskHint;
} __packed;

struct smb2_lease_ack {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
__le16 Reserved;
__le32 Flags;
__u8 LeaseKey[16];
__le32 LeaseState;
__le64 LeaseDuration;
} __packed;

/*
* PDU query infolevel structure definitions
* BB consider moving to a different header
*/

#define OP_BREAK_STRUCT_SIZE_20 24
#define OP_BREAK_STRUCT_SIZE_21 36

struct smb2_file_access_info {
__le32 AccessFlags;
} __packed;
Loading

0 comments on commit c7803b0

Please sign in to comment.