]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Sep 2015 16:59:35 +0000 (09:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Sep 2015 16:59:35 +0000 (09:59 -0700)
Pull cifs updates from Steve French:
 "Small cifs fix and a patch for improved debugging"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Fix use-after-free on mid_q_entry
  Update cifs version number
  Add way to query server fs info for smb3

fs/cifs/cifs_ioctl.h [new file with mode: 0644]
fs/cifs/cifsfs.h
fs/cifs/cifspdu.h
fs/cifs/cifssmb.c
fs/cifs/ioctl.c
fs/cifs/smb2pdu.c
fs/cifs/transport.c

diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h
new file mode 100644 (file)
index 0000000..0065256
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *   fs/cifs/cifs_ioctl.h
+ *
+ *   Structure definitions for io control for cifs/smb3
+ *
+ *   Copyright (c) 2015 Steve French <steve.french@primarydata.com>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ */
+
+struct smb_mnt_fs_info {
+       __u32   version; /* 0001 */
+       __u16   protocol_id;
+       __u16   tcon_flags;
+       __u32   vol_serial_number;
+       __u32   vol_create_time;
+       __u32   share_caps;
+       __u32   share_flags;
+       __u32   sector_flags;
+       __u32   optimal_sector_size;
+       __u32   max_bytes_chunk;
+       __u32   fs_attributes;
+       __u32   max_path_component;
+       __u32   device_type;
+       __u32   device_characteristics;
+       __u32   maximal_access;
+       __u64   cifs_posix_caps;
+} __packed;
+
+#define CIFS_IOCTL_MAGIC       0xCF
+#define CIFS_IOC_COPYCHUNK_FILE        _IOW(CIFS_IOCTL_MAGIC, 3, int)
+#define CIFS_IOC_SET_INTEGRITY  _IO(CIFS_IOCTL_MAGIC, 4)
+#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info)
index a782b22904e40b71387d844a6a7879bab8191a88..27aea110e92365e1e91610579369215cc54644ea 100644 (file)
@@ -136,5 +136,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.06"
+#define CIFS_VERSION   "2.07"
 #endif                         /* _CIFSFS_H */
index 47b030da0781e988c7bcafefd462a5e8b45ff14c..f5b87303ce46d50abab41e6017c33cecb06194bb 100644 (file)
@@ -2245,6 +2245,20 @@ typedef struct {
 #define FILE_DEVICE_VIRTUAL_DISK        0x00000024
 #define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
 
+/* Device Characteristics */
+#define FILE_REMOVABLE_MEDIA                   0x00000001
+#define FILE_READ_ONLY_DEVICE                  0x00000002
+#define FILE_FLOPPY_DISKETTE                   0x00000004
+#define FILE_WRITE_ONCE_MEDIA                  0x00000008
+#define FILE_REMOTE_DEVICE                     0x00000010
+#define FILE_DEVICE_IS_MOUNTED                 0x00000020
+#define FILE_VIRTUAL_VOLUME                    0x00000040
+#define FILE_DEVICE_SECURE_OPEN                        0x00000100
+#define FILE_CHARACTERISTIC_TS_DEVICE          0x00001000
+#define FILE_CHARACTERISTIC_WEBDAV_DEVICE      0x00002000
+#define FILE_PORTABLE_DEVICE                   0x00004000
+#define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000
+
 typedef struct {
        __le32 DeviceType;
        __le32 DeviceCharacteristics;
index 672ef35c9f73c59d1f4b566bec2f16b4c74e4a8f..90b4f9f7de660a261b5f93322af59282294953fd 100644 (file)
@@ -696,7 +696,9 @@ cifs_echo_callback(struct mid_q_entry *mid)
 {
        struct TCP_Server_Info *server = mid->callback_data;
 
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(server, 1, CIFS_ECHO_OP);
 }
 
@@ -1572,7 +1574,9 @@ cifs_readv_callback(struct mid_q_entry *mid)
        }
 
        queue_work(cifsiod_wq, &rdata->work);
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(server, 1, 0);
 }
 
@@ -2032,6 +2036,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
 {
        struct cifs_writedata *wdata = mid->callback_data;
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int written;
        WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
 
@@ -2068,7 +2073,9 @@ cifs_writev_callback(struct mid_q_entry *mid)
        }
 
        queue_work(cifsiod_wq, &wdata->work);
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(tcon->ses->server, 1, 0);
 }
 
index 49b8b6e41a188b3a832c3e32c482ed7a99091aa1..c63f5227b68181ed772d1a999686a852a23d41e9 100644 (file)
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifsfs.h"
+#include "cifs_ioctl.h"
 #include <linux/btrfs.h>
 
-#define CIFS_IOCTL_MAGIC       0xCF
-#define CIFS_IOC_COPYCHUNK_FILE        _IOW(CIFS_IOCTL_MAGIC, 3, int)
-#define CIFS_IOC_SET_INTEGRITY  _IO(CIFS_IOCTL_MAGIC, 4)
-
 static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
                        unsigned long srcfd, u64 off, u64 len, u64 destoff,
                        bool dup_extents)
@@ -135,6 +132,43 @@ out_drop_write:
        return rc;
 }
 
+static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
+                               void __user *arg)
+{
+       int rc = 0;
+       struct smb_mnt_fs_info *fsinf;
+
+       fsinf = kzalloc(sizeof(struct smb_mnt_fs_info), GFP_KERNEL);
+       if (fsinf == NULL)
+               return -ENOMEM;
+
+       fsinf->version = 1;
+       fsinf->protocol_id = tcon->ses->server->vals->protocol_id;
+       fsinf->device_characteristics =
+                       le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics);
+       fsinf->device_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
+       fsinf->fs_attributes = le32_to_cpu(tcon->fsAttrInfo.Attributes);
+       fsinf->max_path_component =
+               le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength);
+#ifdef CONFIG_CIFS_SMB2
+       fsinf->vol_serial_number = tcon->vol_serial_number;
+       fsinf->vol_create_time = le64_to_cpu(tcon->vol_create_time);
+       fsinf->share_flags = tcon->share_flags;
+       fsinf->share_caps = le32_to_cpu(tcon->capabilities);
+       fsinf->sector_flags = tcon->ss_flags;
+       fsinf->optimal_sector_size = tcon->perf_sector_size;
+       fsinf->max_bytes_chunk = tcon->max_bytes_chunk;
+       fsinf->maximal_access = tcon->maximal_access;
+#endif /* SMB2 */
+       fsinf->cifs_posix_caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
+
+       if (copy_to_user(arg, fsinf, sizeof(struct smb_mnt_fs_info)))
+               rc = -EFAULT;
+
+       kfree(fsinf);
+       return rc;
+}
+
 long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 {
        struct inode *inode = file_inode(filep);
@@ -148,8 +182,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 
        xid = get_xid();
 
-       cifs_dbg(FYI, "ioctl file %p  cmd %u  arg %lu\n", filep, command, arg);
-
        cifs_sb = CIFS_SB(inode->i_sb);
 
        switch (command) {
@@ -228,6 +260,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                        else
                                rc = -EOPNOTSUPP;
                        break;
+               case CIFS_IOC_GET_MNT_INFO:
+                       tcon = tlink_tcon(pSMBFile->tlink);
+                       rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
+                       break;
                default:
                        cifs_dbg(FYI, "unsupported ioctl\n");
                        break;
index b8b4f08ee094e2f8a2b811f076ca0eb4cc3e68b9..070fb2ad85ced4483d28d88c1fa4832e92eef3ba 100644 (file)
@@ -1626,7 +1626,9 @@ smb2_echo_callback(struct mid_q_entry *mid)
        if (mid->mid_state == MID_RESPONSE_RECEIVED)
                credits_received = le16_to_cpu(smb2->hdr.CreditRequest);
 
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(server, credits_received, CIFS_ECHO_OP);
 }
 
@@ -1810,7 +1812,9 @@ smb2_readv_callback(struct mid_q_entry *mid)
                cifs_stats_fail_inc(tcon, SMB2_READ_HE);
 
        queue_work(cifsiod_wq, &rdata->work);
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(server, credits_received, 0);
 }
 
@@ -1938,6 +1942,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
 {
        struct cifs_writedata *wdata = mid->callback_data;
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int written;
        struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
        unsigned int credits_received = 1;
@@ -1977,7 +1982,9 @@ smb2_writev_callback(struct mid_q_entry *mid)
                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
 
        queue_work(cifsiod_wq, &wdata->work);
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        add_credits(tcon->ses->server, credits_received, 0);
 }
 
index 126f46b887cc85b6ba6a0f313b918e2d8b026708..2a24c524fb9a90cedd4187460ecb90c0e5dfcf0c 100644 (file)
@@ -644,7 +644,9 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
        }
        spin_unlock(&GlobalMid_Lock);
 
+       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
+       mutex_unlock(&server->srv_mutex);
        return rc;
 }