From patchwork Fri Sep 27 05:58:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 2952831 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 78FA29F289 for ; Fri, 27 Sep 2013 05:58:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8C57020318 for ; Fri, 27 Sep 2013 05:58:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8E3C2202EC for ; Fri, 27 Sep 2013 05:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750981Ab3I0F6H (ORCPT ); Fri, 27 Sep 2013 01:58:07 -0400 Received: from mail-pa0-f43.google.com ([209.85.220.43]:56968 "EHLO mail-pa0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750975Ab3I0F6G (ORCPT ); Fri, 27 Sep 2013 01:58:06 -0400 Received: by mail-pa0-f43.google.com with SMTP id hz1so2326103pad.2 for ; Thu, 26 Sep 2013 22:58:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=NU6t+9M1aYr4G2jX7J9/3akp9wZ8ja8HyGr3afYF1s0=; b=qSPfqal22y7JJconqXuAQD5c7CTvE2mr2+kNB6AHAa7NiualKDpSaMf3hWxPspNq0a t/xgxBXnVZ4lpL359LpdNWkxRA9QeKe4X+hPy9R+L/GG8Cik8FU0D0oHnz0oIBHNv+9t kiQ1FjMSqNdgfUdnDm+lhbVrXTMK7H+d6QybHDtS/1KJbdQ4p3GgjG1pvW+IQeOHLwj4 gLePvYRoPoSix7fkVBuY/7x0acbtqssYRCzH5/hdiTbVaTJpjg3vrmm762INtVRzExNz oHvS39r+JxLGlZIanw5FnKPzZ9echLCXMs0WgOGqmhfcLurjf/wdzn8e0MhUk0rPO7LZ 7GIw== MIME-Version: 1.0 X-Received: by 10.68.218.69 with SMTP id pe5mr5361456pbc.71.1380261485125; Thu, 26 Sep 2013 22:58:05 -0700 (PDT) Received: by 10.68.249.5 with HTTP; Thu, 26 Sep 2013 22:58:05 -0700 (PDT) Date: Fri, 27 Sep 2013 00:58:05 -0500 Message-ID: Subject: Distinguishing between different types of reparse point symlinks From: Steve French To: "linux-cifs@vger.kernel.org" Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I have to make some minor fixes to the patch below to account for little endian specific fields in symlink reparse point structure, but it does fix the problem ("ls -l" to windows 8 or later share which has multiple types of reparse points in the same directory, not all of which are NTFS symlinks). From: Steve French Date: Thu, 26 Sep 2013 19:49:14 -0500 Subject: [PATCH] [CIFS] do not treat non-symlink reparse points as valid symlinks Windows 8 and later can create NFS symlinks (within reparse points) which we were assuming were normal NTFS symlinks and thus reporting corrupt paths for. Add check for reparse points to make sure that they really are normal symlinks before we try to parse the pathname. This fixes commit d244bf2dfbebfded05f494ffd53659fa7b1e32c1 which implemented follow link for non-Unix CIFS mounts CC: Stable Reviewed-by: Andrew Bartlett Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 2 +- fs/cifs/cifssmb.c | 9 +++++++-- fs/cifs/smbfsctl.h | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index a630475..5f295f3 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1491,7 +1491,7 @@ struct file_notify_information { __u8 FileName[0]; } __attribute__((packed)); -struct reparse_data { +struct reparse_symlink_data { __u32 ReparseTag; __u16 ReparseDataLength; __u16 Reserved; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4baf359..0bf7635 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3088,7 +3088,7 @@ CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, bool is_unicode; unsigned int sub_len; char *sub_start; - struct reparse_data *reparse_buf; + struct reparse_symlink_data *reparse_buf; __u32 data_offset, data_count; char *end_of_smb; @@ -3137,12 +3137,17 @@ CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, goto qreparse_out; } end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount; - reparse_buf = (struct reparse_data *) + reparse_buf = (struct reparse_symlink_data *) ((char *)&pSMBr->hdr.Protocol + data_offset); if ((char *)reparse_buf >= end_of_smb) { rc = -EIO; goto qreparse_out; } + if (reparse_buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) { + rc = -EOPNOTSUPP; + goto qreparse_out; + } + if ((reparse_buf->PathBuffer + reparse_buf->PrintNameOffset + reparse_buf->PrintNameLength) > end_of_smb) { cifs_dbg(FYI, "reparse buf beyond SMB\n"); diff --git a/fs/cifs/smbfsctl.h b/fs/cifs/smbfsctl.h index d952ee4..3a10e1c 100644 --- a/fs/cifs/smbfsctl.h +++ b/fs/cifs/smbfsctl.h @@ -97,9 +97,23 @@ #define FSCTL_QUERY_NETWORK_INTERFACE_INFO 0x001401FC /* BB add struct */ #define FSCTL_SRV_READ_HASH 0x001441BB /* BB add struct */ +/* See FSCC 2.1.2.5 */ #define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 #define IO_REPARSE_TAG_HSM 0xC0000004 #define IO_REPARSE_TAG_SIS 0x80000007 +#define IO_REPARSE_TAG_HSM2 0x80000006 +#define IO_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 +/* Used by the DFS filter. See MS-DFSC */ +#define IO_REPARSE_TAG_DFS 0x8000000A +/* Used by the DFS filter See MS-DFSC */ +#define IO_REPARSE_TAG_DFSR 0x80000012 +#define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B +/* See section MS-FSCC 2.1.2.4 */ +#define IO_REPARSE_TAG_SYMLINK 0xA000000C +#define IO_REPARSE_TAG_DEDUP 0x80000013 +#define IO_REPARSE_APPXSTREAM 0xC0000014 +/* NFS symlinks, Win 8/SMB3 and later */ +#define IO_REPARSE_TAG_NFS 0xA0000014 /* fsctl flags */ /* If Flags is set to this value, the request is an FSCTL not ioctl request */