cifs: fix bad fids sent over wire
authorPaulo Alcantara <pc@cjr.nz>
Mon, 21 Mar 2022 16:08:25 +0000 (13:08 -0300)
committerSteve French <stfrench@microsoft.com>
Thu, 21 Jul 2022 15:40:01 +0000 (10:40 -0500)
The client used to partially convert the fids to le64, while storing
or sending them by using host endianness.  This broke the client on
big-endian machines.  Instead of converting them to le64, store them
as opaque integers and then avoid byteswapping when sending them over
wire.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: Tom Talpey <tom@talpey.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/smbfs_common/smb2pdu.h

index b25623e3fe3d5596e10202c5d8abcc2fd96f76f2..3b7c636be3774aead5e496bd5207ae95e05c72d4 100644 (file)
@@ -832,8 +832,8 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
        rc = __smb2_handle_cancelled_cmd(tcon,
                                         le16_to_cpu(hdr->Command),
                                         le64_to_cpu(hdr->MessageId),
-                                        le64_to_cpu(rsp->PersistentFileId),
-                                        le64_to_cpu(rsp->VolatileFileId));
+                                        rsp->PersistentFileId,
+                                        rsp->VolatileFileId);
        if (rc)
                cifs_put_tcon(tcon);
 
index 41504234603b75a06a2913fdbb934c50ab16596a..6173efc57dcfde1fd9a35c3890138d6f6ee4f7ff 100644 (file)
@@ -897,8 +897,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        atomic_inc(&tcon->num_remote_opens);
 
        o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
-       oparms.fid->persistent_fid = le64_to_cpu(o_rsp->PersistentFileId);
-       oparms.fid->volatile_fid = le64_to_cpu(o_rsp->VolatileFileId);
+       oparms.fid->persistent_fid = o_rsp->PersistentFileId;
+       oparms.fid->volatile_fid = o_rsp->VolatileFileId;
 #ifdef CONFIG_CIFS_DEBUG2
        oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
 #endif /* CIFS_DEBUG2 */
@@ -2401,8 +2401,8 @@ again:
                cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc);
                goto qdf_free;
        }
-       fid->persistent_fid = le64_to_cpu(op_rsp->PersistentFileId);
-       fid->volatile_fid = le64_to_cpu(op_rsp->VolatileFileId);
+       fid->persistent_fid = op_rsp->PersistentFileId;
+       fid->volatile_fid = op_rsp->VolatileFileId;
 
        /* Anything else than ENODATA means a genuine error */
        if (rc && rc != -ENODATA) {
index 7e7909b1ae1180f836054d51a0da6bc918943231..7e15b0092243d84ac5100f0b5b497ea92cb9b9d3 100644 (file)
@@ -2734,13 +2734,10 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
                goto err_free_req;
        }
 
-       trace_smb3_posix_mkdir_done(xid, le64_to_cpu(rsp->PersistentFileId),
-                                   tcon->tid,
-                                   ses->Suid, CREATE_NOT_FILE,
-                                   FILE_WRITE_ATTRIBUTES);
+       trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
+                                   CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES);
 
-       SMB2_close(xid, tcon, le64_to_cpu(rsp->PersistentFileId),
-                  le64_to_cpu(rsp->VolatileFileId));
+       SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
 
        /* Eventually save off posix specific response info and timestaps */
 
@@ -3009,14 +3006,12 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
        } else if (rsp == NULL) /* unlikely to happen, but safer to check */
                goto creat_exit;
        else
-               trace_smb3_open_done(xid, le64_to_cpu(rsp->PersistentFileId),
-                                    tcon->tid,
-                                    ses->Suid, oparms->create_options,
-                                    oparms->desired_access);
+               trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
+                                    oparms->create_options, oparms->desired_access);
 
        atomic_inc(&tcon->num_remote_opens);
-       oparms->fid->persistent_fid = le64_to_cpu(rsp->PersistentFileId);
-       oparms->fid->volatile_fid = le64_to_cpu(rsp->VolatileFileId);
+       oparms->fid->persistent_fid = rsp->PersistentFileId;
+       oparms->fid->volatile_fid = rsp->VolatileFileId;
        oparms->fid->access = oparms->desired_access;
 #ifdef CONFIG_CIFS_DEBUG2
        oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
@@ -3313,8 +3308,8 @@ SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
        if (rc)
                return rc;
 
-       req->PersistentFileId = cpu_to_le64(persistent_fid);
-       req->VolatileFileId = cpu_to_le64(volatile_fid);
+       req->PersistentFileId = persistent_fid;
+       req->VolatileFileId = volatile_fid;
        if (query_attrs)
                req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
        else
@@ -3677,8 +3672,8 @@ SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
        if (rc)
                return rc;
 
-       req->PersistentFileId = cpu_to_le64(persistent_fid);
-       req->VolatileFileId = cpu_to_le64(volatile_fid);
+       req->PersistentFileId = persistent_fid;
+       req->VolatileFileId = volatile_fid;
        /* See note 354 of MS-SMB2, 64K max */
        req->OutputBufferLength =
                cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
@@ -3951,8 +3946,8 @@ SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
        if (rc)
                return rc;
 
-       req->PersistentFileId = cpu_to_le64(persistent_fid);
-       req->VolatileFileId = cpu_to_le64(volatile_fid);
+       req->PersistentFileId = persistent_fid;
+       req->VolatileFileId = volatile_fid;
 
        iov[0].iov_base = (char *)req;
        iov[0].iov_len = total_len;
@@ -4033,8 +4028,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
        shdr = &req->hdr;
        shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
 
-       req->PersistentFileId = cpu_to_le64(io_parms->persistent_fid);
-       req->VolatileFileId = cpu_to_le64(io_parms->volatile_fid);
+       req->PersistentFileId = io_parms->persistent_fid;
+       req->VolatileFileId = io_parms->volatile_fid;
        req->ReadChannelInfoOffset = 0; /* reserved */
        req->ReadChannelInfoLength = 0; /* reserved */
        req->Channel = 0; /* reserved */
@@ -4094,8 +4089,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
                         */
                        shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
                        shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF);
-                       req->PersistentFileId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
-                       req->VolatileFileId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
+                       req->PersistentFileId = (u64)-1;
+                       req->VolatileFileId = (u64)-1;
                }
        }
        if (remaining_bytes > io_parms->length)
@@ -4307,21 +4302,19 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
                        cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
                        cifs_dbg(VFS, "Send error in read = %d\n", rc);
                        trace_smb3_read_err(xid,
-                                           le64_to_cpu(req->PersistentFileId),
+                                           req->PersistentFileId,
                                            io_parms->tcon->tid, ses->Suid,
                                            io_parms->offset, io_parms->length,
                                            rc);
                } else
-                       trace_smb3_read_done(xid,
-                                            le64_to_cpu(req->PersistentFileId),
-                                            io_parms->tcon->tid, ses->Suid,
-                                            io_parms->offset, 0);
+                       trace_smb3_read_done(xid, req->PersistentFileId, io_parms->tcon->tid,
+                                            ses->Suid, io_parms->offset, 0);
                free_rsp_buf(resp_buftype, rsp_iov.iov_base);
                cifs_small_buf_release(req);
                return rc == -ENODATA ? 0 : rc;
        } else
                trace_smb3_read_done(xid,
-                                    le64_to_cpu(req->PersistentFileId),
+                                   req->PersistentFileId,
                                    io_parms->tcon->tid, ses->Suid,
                                    io_parms->offset, io_parms->length);
 
@@ -4463,8 +4456,8 @@ smb2_async_writev(struct cifs_writedata *wdata,
        shdr = (struct smb2_hdr *)req;
        shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid);
 
-       req->PersistentFileId = cpu_to_le64(wdata->cfile->fid.persistent_fid);
-       req->VolatileFileId = cpu_to_le64(wdata->cfile->fid.volatile_fid);
+       req->PersistentFileId = wdata->cfile->fid.persistent_fid;
+       req->VolatileFileId = wdata->cfile->fid.volatile_fid;
        req->WriteChannelInfoOffset = 0;
        req->WriteChannelInfoLength = 0;
        req->Channel = 0;
@@ -4562,7 +4555,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
 
        if (rc) {
                trace_smb3_write_err(0 /* no xid */,
-                                    le64_to_cpu(req->PersistentFileId),
+                                    req->PersistentFileId,
                                     tcon->tid, tcon->ses->Suid, wdata->offset,
                                     wdata->bytes, rc);
                kref_put(&wdata->refcount, release);
@@ -4615,8 +4608,8 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
 
        req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
 
-       req->PersistentFileId = cpu_to_le64(io_parms->persistent_fid);
-       req->VolatileFileId = cpu_to_le64(io_parms->volatile_fid);
+       req->PersistentFileId = io_parms->persistent_fid;
+       req->VolatileFileId = io_parms->volatile_fid;
        req->WriteChannelInfoOffset = 0;
        req->WriteChannelInfoLength = 0;
        req->Channel = 0;
@@ -4645,7 +4638,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
 
        if (rc) {
                trace_smb3_write_err(xid,
-                                    le64_to_cpu(req->PersistentFileId),
+                                    req->PersistentFileId,
                                     io_parms->tcon->tid,
                                     io_parms->tcon->ses->Suid,
                                     io_parms->offset, io_parms->length, rc);
@@ -4654,7 +4647,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
        } else {
                *nbytes = le32_to_cpu(rsp->DataLength);
                trace_smb3_write_done(xid,
-                                     le64_to_cpu(req->PersistentFileId),
+                                     req->PersistentFileId,
                                      io_parms->tcon->tid,
                                      io_parms->tcon->ses->Suid,
                                      io_parms->offset, *nbytes);
index 38b8fc51486049d4de706f9fcdec3ef1d0bdaf6d..6653b4be4556810dde7eaef9ff7e3afb23c7890f 100644 (file)
@@ -608,8 +608,8 @@ struct smb2_close_req {
        __le16 StructureSize;   /* Must be 24 */
        __le16 Flags;
        __le32 Reserved;
-       __le64  PersistentFileId; /* opaque endianness */
-       __le64  VolatileFileId; /* opaque endianness */
+       __u64  PersistentFileId; /* opaque endianness */
+       __u64  VolatileFileId; /* opaque endianness */
 } __packed;
 
 /*
@@ -653,8 +653,8 @@ struct smb2_read_req {
        __u8   Flags; /* MBZ unless SMB3.02 or later */
        __le32 Length;
        __le64 Offset;
-       __le64  PersistentFileId;
-       __le64  VolatileFileId;
+       __u64  PersistentFileId;
+       __u64  VolatileFileId;
        __le32 MinimumCount;
        __le32 Channel; /* MBZ except for SMB3 or later */
        __le32 RemainingBytes;
@@ -692,8 +692,8 @@ struct smb2_write_req {
        __le16 DataOffset; /* offset from start of SMB2 header to write data */
        __le32 Length;
        __le64 Offset;
-       __le64  PersistentFileId; /* opaque endianness */
-       __le64  VolatileFileId; /* opaque endianness */
+       __u64  PersistentFileId; /* opaque endianness */
+       __u64  VolatileFileId; /* opaque endianness */
        __le32 Channel; /* MBZ unless SMB3.02 or later */
        __le32 RemainingBytes;
        __le16 WriteChannelInfoOffset;
@@ -722,8 +722,8 @@ struct smb2_flush_req {
        __le16 StructureSize;   /* Must be 24 */
        __le16 Reserved1;
        __le32 Reserved2;
-       __le64  PersistentFileId;
-       __le64  VolatileFileId;
+       __u64  PersistentFileId;
+       __u64  VolatileFileId;
 } __packed;
 
 struct smb2_flush_rsp {
@@ -769,8 +769,8 @@ struct smb2_change_notify_req {
        __le16  StructureSize;
        __le16  Flags;
        __le32  OutputBufferLength;
-       __le64  PersistentFileId; /* opaque endianness */
-       __le64  VolatileFileId; /* opaque endianness */
+       __u64   PersistentFileId; /* opaque endianness */
+       __u64   VolatileFileId; /* opaque endianness */
        __le32  CompletionFilter;
        __u32   Reserved;
 } __packed;
@@ -978,8 +978,8 @@ struct smb2_create_rsp {
        __le64 EndofFile;
        __le32 FileAttributes;
        __le32 Reserved2;
-       __le64  PersistentFileId;
-       __le64  VolatileFileId;
+       __u64  PersistentFileId;
+       __u64  VolatileFileId;
        __le32 CreateContextsOffset;
        __le32 CreateContextsLength;
        __u8   Buffer[1];