Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 384989b5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

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
parents d77e92e2 5fb4e288
Loading
Loading
Loading
Loading

fs/cifs/cifs_ioctl.h

0 → 100644
+42 −0
Original line number Diff line number Diff line
/*
 *   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)
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+14 −0
Original line number Diff line number Diff line
@@ -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;
+7 −0
Original line number Diff line number Diff line
@@ -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);
}

+42 −6
Original line number Diff line number Diff line
@@ -31,12 +31,9 @@
#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 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
	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;
Loading