aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-12 21:49:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-12 21:49:53 -0400
commitccda3c4b77777f66aeb3c531352bb40d59501c59 (patch)
tree1f06e12e644bd24d35df6924b85cfceed3947bfb
parent427fbe89261d8f11cd20b5a4ba94e977061f69d6 (diff)
parent6e70c267e68d77679534dcf4aaf84e66f2cf1425 (diff)
Merge tag '4.17-rc4-SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Some small SMB3 fixes for 4.17-rc5, some for stable" * tag '4.17-rc4-SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: directory sync should not return an error cifs: smb2ops: Fix listxattr() when there are no EAs cifs: smbd: Enable signing with smbdirect cifs: Allocate validate negotiation request through kmalloc
-rw-r--r--fs/cifs/cifsfs.c13
-rw-r--r--fs/cifs/connect.c8
-rw-r--r--fs/cifs/smb2ops.c6
-rw-r--r--fs/cifs/smb2pdu.c73
4 files changed, 57 insertions, 43 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index f715609b13f3..5a5a0158cc8f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1047,6 +1047,18 @@ out:
1047 return rc; 1047 return rc;
1048} 1048}
1049 1049
1050/*
1051 * Directory operations under CIFS/SMB2/SMB3 are synchronous, so fsync()
1052 * is a dummy operation.
1053 */
1054static int cifs_dir_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1055{
1056 cifs_dbg(FYI, "Sync directory - name: %pD datasync: 0x%x\n",
1057 file, datasync);
1058
1059 return 0;
1060}
1061
1050static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, 1062static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
1051 struct file *dst_file, loff_t destoff, 1063 struct file *dst_file, loff_t destoff,
1052 size_t len, unsigned int flags) 1064 size_t len, unsigned int flags)
@@ -1181,6 +1193,7 @@ const struct file_operations cifs_dir_ops = {
1181 .copy_file_range = cifs_copy_file_range, 1193 .copy_file_range = cifs_copy_file_range,
1182 .clone_file_range = cifs_clone_file_range, 1194 .clone_file_range = cifs_clone_file_range,
1183 .llseek = generic_file_llseek, 1195 .llseek = generic_file_llseek,
1196 .fsync = cifs_dir_fsync,
1184}; 1197};
1185 1198
1186static void 1199static void
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index a5aa158d535a..7a10a5d0731f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1977,14 +1977,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1977 goto cifs_parse_mount_err; 1977 goto cifs_parse_mount_err;
1978 } 1978 }
1979 1979
1980#ifdef CONFIG_CIFS_SMB_DIRECT
1981 if (vol->rdma && vol->sign) {
1982 cifs_dbg(VFS, "Currently SMB direct doesn't support signing."
1983 " This is being fixed\n");
1984 goto cifs_parse_mount_err;
1985 }
1986#endif
1987
1988#ifndef CONFIG_KEYS 1980#ifndef CONFIG_KEYS
1989 /* Muliuser mounts require CONFIG_KEYS support */ 1981 /* Muliuser mounts require CONFIG_KEYS support */
1990 if (vol->multiuser) { 1982 if (vol->multiuser) {
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index b76b85881dcc..9c6d95ffca97 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -589,9 +589,15 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
589 589
590 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 590 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
591 591
592 /*
593 * If ea_name is NULL (listxattr) and there are no EAs, return 0 as it's
594 * not an error. Otherwise, the specified ea_name was not found.
595 */
592 if (!rc) 596 if (!rc)
593 rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data, 597 rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data,
594 SMB2_MAX_EA_BUF, ea_name); 598 SMB2_MAX_EA_BUF, ea_name);
599 else if (!ea_name && rc == -ENODATA)
600 rc = 0;
595 601
596 kfree(smb2_data); 602 kfree(smb2_data);
597 return rc; 603 return rc;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 60db51bae0e3..0f48741a0130 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -730,19 +730,14 @@ neg_exit:
730 730
731int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) 731int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
732{ 732{
733 int rc = 0; 733 int rc;
734 struct validate_negotiate_info_req vneg_inbuf; 734 struct validate_negotiate_info_req *pneg_inbuf;
735 struct validate_negotiate_info_rsp *pneg_rsp = NULL; 735 struct validate_negotiate_info_rsp *pneg_rsp = NULL;
736 u32 rsplen; 736 u32 rsplen;
737 u32 inbuflen; /* max of 4 dialects */ 737 u32 inbuflen; /* max of 4 dialects */
738 738
739 cifs_dbg(FYI, "validate negotiate\n"); 739 cifs_dbg(FYI, "validate negotiate\n");
740 740
741#ifdef CONFIG_CIFS_SMB_DIRECT
742 if (tcon->ses->server->rdma)
743 return 0;
744#endif
745
746 /* In SMB3.11 preauth integrity supersedes validate negotiate */ 741 /* In SMB3.11 preauth integrity supersedes validate negotiate */
747 if (tcon->ses->server->dialect == SMB311_PROT_ID) 742 if (tcon->ses->server->dialect == SMB311_PROT_ID)
748 return 0; 743 return 0;
@@ -765,63 +760,69 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
765 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) 760 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
766 cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); 761 cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
767 762
768 vneg_inbuf.Capabilities = 763 pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS);
764 if (!pneg_inbuf)
765 return -ENOMEM;
766
767 pneg_inbuf->Capabilities =
769 cpu_to_le32(tcon->ses->server->vals->req_capabilities); 768 cpu_to_le32(tcon->ses->server->vals->req_capabilities);
770 memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid, 769 memcpy(pneg_inbuf->Guid, tcon->ses->server->client_guid,
771 SMB2_CLIENT_GUID_SIZE); 770 SMB2_CLIENT_GUID_SIZE);
772 771
773 if (tcon->ses->sign) 772 if (tcon->ses->sign)
774 vneg_inbuf.SecurityMode = 773 pneg_inbuf->SecurityMode =
775 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED); 774 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
776 else if (global_secflags & CIFSSEC_MAY_SIGN) 775 else if (global_secflags & CIFSSEC_MAY_SIGN)
777 vneg_inbuf.SecurityMode = 776 pneg_inbuf->SecurityMode =
778 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED); 777 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
779 else 778 else
780 vneg_inbuf.SecurityMode = 0; 779 pneg_inbuf->SecurityMode = 0;
781 780
782 781
783 if (strcmp(tcon->ses->server->vals->version_string, 782 if (strcmp(tcon->ses->server->vals->version_string,
784 SMB3ANY_VERSION_STRING) == 0) { 783 SMB3ANY_VERSION_STRING) == 0) {
785 vneg_inbuf.Dialects[0] = cpu_to_le16(SMB30_PROT_ID); 784 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
786 vneg_inbuf.Dialects[1] = cpu_to_le16(SMB302_PROT_ID); 785 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
787 vneg_inbuf.DialectCount = cpu_to_le16(2); 786 pneg_inbuf->DialectCount = cpu_to_le16(2);
788 /* structure is big enough for 3 dialects, sending only 2 */ 787 /* structure is big enough for 3 dialects, sending only 2 */
789 inbuflen = sizeof(struct validate_negotiate_info_req) - 2; 788 inbuflen = sizeof(*pneg_inbuf) -
789 sizeof(pneg_inbuf->Dialects[0]);
790 } else if (strcmp(tcon->ses->server->vals->version_string, 790 } else if (strcmp(tcon->ses->server->vals->version_string,
791 SMBDEFAULT_VERSION_STRING) == 0) { 791 SMBDEFAULT_VERSION_STRING) == 0) {
792 vneg_inbuf.Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 792 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
793 vneg_inbuf.Dialects[1] = cpu_to_le16(SMB30_PROT_ID); 793 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
794 vneg_inbuf.Dialects[2] = cpu_to_le16(SMB302_PROT_ID); 794 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
795 vneg_inbuf.DialectCount = cpu_to_le16(3); 795 pneg_inbuf->DialectCount = cpu_to_le16(3);
796 /* structure is big enough for 3 dialects */ 796 /* structure is big enough for 3 dialects */
797 inbuflen = sizeof(struct validate_negotiate_info_req); 797 inbuflen = sizeof(*pneg_inbuf);
798 } else { 798 } else {
799 /* otherwise specific dialect was requested */ 799 /* otherwise specific dialect was requested */
800 vneg_inbuf.Dialects[0] = 800 pneg_inbuf->Dialects[0] =
801 cpu_to_le16(tcon->ses->server->vals->protocol_id); 801 cpu_to_le16(tcon->ses->server->vals->protocol_id);
802 vneg_inbuf.DialectCount = cpu_to_le16(1); 802 pneg_inbuf->DialectCount = cpu_to_le16(1);
803 /* structure is big enough for 3 dialects, sending only 1 */ 803 /* structure is big enough for 3 dialects, sending only 1 */
804 inbuflen = sizeof(struct validate_negotiate_info_req) - 4; 804 inbuflen = sizeof(*pneg_inbuf) -
805 sizeof(pneg_inbuf->Dialects[0]) * 2;
805 } 806 }
806 807
807 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 808 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
808 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, 809 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
809 (char *)&vneg_inbuf, sizeof(struct validate_negotiate_info_req), 810 (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen);
810 (char **)&pneg_rsp, &rsplen);
811 811
812 if (rc != 0) { 812 if (rc != 0) {
813 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); 813 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
814 return -EIO; 814 rc = -EIO;
815 goto out_free_inbuf;
815 } 816 }
816 817
817 if (rsplen != sizeof(struct validate_negotiate_info_rsp)) { 818 rc = -EIO;
819 if (rsplen != sizeof(*pneg_rsp)) {
818 cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n", 820 cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n",
819 rsplen); 821 rsplen);
820 822
821 /* relax check since Mac returns max bufsize allowed on ioctl */ 823 /* relax check since Mac returns max bufsize allowed on ioctl */
822 if ((rsplen > CIFSMaxBufSize) 824 if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
823 || (rsplen < sizeof(struct validate_negotiate_info_rsp))) 825 goto out_free_rsp;
824 goto err_rsp_free;
825 } 826 }
826 827
827 /* check validate negotiate info response matches what we got earlier */ 828 /* check validate negotiate info response matches what we got earlier */
@@ -838,15 +839,17 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
838 goto vneg_out; 839 goto vneg_out;
839 840
840 /* validate negotiate successful */ 841 /* validate negotiate successful */
842 rc = 0;
841 cifs_dbg(FYI, "validate negotiate info successful\n"); 843 cifs_dbg(FYI, "validate negotiate info successful\n");
842 kfree(pneg_rsp); 844 goto out_free_rsp;
843 return 0;
844 845
845vneg_out: 846vneg_out:
846 cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n"); 847 cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
847err_rsp_free: 848out_free_rsp:
848 kfree(pneg_rsp); 849 kfree(pneg_rsp);
849 return -EIO; 850out_free_inbuf:
851 kfree(pneg_inbuf);
852 return rc;
850} 853}
851 854
852enum securityEnum 855enum securityEnum