From patchwork Tue Sep 26 20:40:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 9972725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5C2106037F for ; Tue, 26 Sep 2017 20:40:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5318028FAD for ; Tue, 26 Sep 2017 20:40:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4821D28FB5; Tue, 26 Sep 2017 20:40:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 311F728FB8 for ; Tue, 26 Sep 2017 20:40:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S968777AbdIZUkN (ORCPT ); Tue, 26 Sep 2017 16:40:13 -0400 Received: from mail-qk0-f193.google.com ([209.85.220.193]:36009 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964856AbdIZUkM (ORCPT ); Tue, 26 Sep 2017 16:40:12 -0400 Received: by mail-qk0-f193.google.com with SMTP id i14so7580011qke.3 for ; Tue, 26 Sep 2017 13:40:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id; bh=in2SnQ0lIv8OV27z5+gPzzhi/s3O1D1cCfEVEtNkFpE=; b=w2f2K6eDBhH9u/hxaxQQwOlWbehdQ0tNU+Q48pIVnR3vIq/W8o9PNhdqShLX7TNzuo At7KhdGc2kjHVMTJscFPMR2K+U4VpRrP1NH5+dkNWvMAwr81oXt3ospmmTCCYzc8gVou QU1BnqMHTQNGdbdxeoV+FlsDresOXMkgk7WJ/NBSHx9eXh+EcExFcsk6EzQONFzYFuxs ruLKHtCggkj8hjofSm/Cv/lwBu9FHA71paPA+kFan1xRnWFU/HkXeASa3CDj0LhsC47g 22v7mg3UrPnqsygUSA9F2yynw6CPk235cOHi0kTyLPFPzMxt88dxtp9wPnlSOe9OFrr2 IP8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=in2SnQ0lIv8OV27z5+gPzzhi/s3O1D1cCfEVEtNkFpE=; b=KJ4UH4vukogD1kJeR0IAcl+xGjwWjOr9EaHF55rTPueYQEKt4u6mPilG3PMEMlfi7O QnD/CdNFCpKa05akxtu1DwrN+Cyv3CbADeEZDlZ1ZW3+tU3fHkFqJozhOnp+QKXVXCFE b3pkJeHiu3TCRpajIuSajv7E8ndzJJAumwyvAcg1/mtyb5S29AEZUIhtm/toBdrJc0wy OQ0JpNIdPPqoRgjSS3VGGou3wpeWJlxZjLn3zYyGwyQf888JPsWAXn3fud+aRsRipbK5 7u7LZO+f/ivuBIZDbB7T7p4blFCsueiJmLR5g1K2xWGi9BKUUG2wjvZnl0x6Mdk7zR8r H5yQ== X-Gm-Message-State: AHPjjUh9XHj83GfepJ31ZEIOgT1fDa67+klliBEhY+4D6oCfh0Kwj3w5 x8jVBE8RP3AceL95iIyML6YlGSV/ X-Google-Smtp-Source: AOwi7QBzNIh1GlkauvcC2vVoQPCNmsm38reXyBrBIcX3MRJj7crR8vtTuRCsbCu59VUorieoK1KFyQ== X-Received: by 10.55.181.129 with SMTP id e123mr17472561qkf.128.1506458411200; Tue, 26 Sep 2017 13:40:11 -0700 (PDT) Received: from localhost ([2606:a000:4381:1201:225:22ff:feb3:e51a]) by smtp.gmail.com with ESMTPSA id g1sm3320508qta.95.2017.09.26.13.40.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Sep 2017 13:40:10 -0700 (PDT) From: Josef Bacik X-Google-Original-From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH] btrfs: fix send ioctl on 32bit with 64bit kernel Date: Tue, 26 Sep 2017 16:40:09 -0400 Message-Id: <1506458409-2428-1-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 2.7.4 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We pass in a pointer in our send arg struct, this means the struct size doesn't match with 32bit user space and 64bit kernel space. Fix this by adding a compat mode and doing the appropriate conversion. Signed-off-by: Josef Bacik --- fs/btrfs/ioctl.c | 6 +++++- fs/btrfs/send.c | 34 ++++++++++++++++++++++++++++------ fs/btrfs/send.h | 2 +- include/uapi/linux/btrfs.h | 13 +++++++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 050d2d9c5533..9169d67e49b9 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -5594,7 +5594,11 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_set_received_subvol_32(file, argp); #endif case BTRFS_IOC_SEND: - return btrfs_ioctl_send(file, argp); + return btrfs_ioctl_send(file, argp, false); +#ifdef CONFIG_64BIT + case BTRFS_IOC_SEND_32: + return btrfs_ioctl_send(file, argp, true); +#endif case BTRFS_IOC_GET_DEV_STATS: return btrfs_ioctl_get_dev_stats(fs_info, argp); case BTRFS_IOC_QUOTA_CTL: diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 32b043ef8ac9..2041cac1875a 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "send.h" #include "backref.h" @@ -6365,7 +6366,7 @@ static void btrfs_root_dec_send_in_progress(struct btrfs_root* root) spin_unlock(&root->root_item_lock); } -long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) +long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_, bool compat) { int ret = 0; struct btrfs_root *send_root = BTRFS_I(file_inode(mnt_file))->root; @@ -6407,11 +6408,32 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) goto out; } - arg = memdup_user(arg_, sizeof(*arg)); - if (IS_ERR(arg)) { - ret = PTR_ERR(arg); - arg = NULL; - goto out; + if (compat) { + struct btrfs_ioctl_send_args_32 args32; + ret = copy_from_user(&args32, arg_, sizeof(args32)); + if (ret) { + btrfs_err(fs_info, "args32 copy failed\n"); + goto out; + } + arg = kzalloc(sizeof(*arg), GFP_KERNEL); + if (!arg) { + ret = -ENOMEM; + goto out; + } + arg->send_fd = args32.send_fd; + arg->clone_sources_count = args32.clone_sources_count; + arg->clone_sources = compat_ptr(args32.clone_sources); + arg->parent_root = args32.parent_root; + arg->flags = args32.flags; + memcpy(arg->reserved, args32.reserved, + sizeof(args32.reserved)); + } else { + arg = memdup_user(arg_, sizeof(*arg)); + if (IS_ERR(arg)) { + ret = PTR_ERR(arg); + arg = NULL; + goto out; + } } /* diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h index 02e00166c4da..d45d2471c4b6 100644 --- a/fs/btrfs/send.h +++ b/fs/btrfs/send.h @@ -130,5 +130,5 @@ enum { #define BTRFS_SEND_A_MAX (__BTRFS_SEND_A_MAX - 1) #ifdef __KERNEL__ -long btrfs_ioctl_send(struct file *mnt_file, void __user *arg); +long btrfs_ioctl_send(struct file *mnt_file, void __user *arg, bool compat); #endif diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 378230c163d5..50b201222cfc 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -719,6 +719,19 @@ struct btrfs_ioctl_send_args { __u64 reserved[4]; /* in */ }; +#ifdef CONFIG_64BIT +struct btrfs_ioctl_send_args_32 { + __s64 send_fd; /* in */ + __u64 clone_sources_count; /* in */ + __u32 clone_sources; /* in */ + __u64 parent_root; /* in */ + __u64 flags; /* in */ + __u64 reserved[4]; /* in */ +} __attribute__ ((__packed__)); +#define BTRFS_IOC_SEND_32 _IOW(BTRFS_IOCTL_MAGIC, 38, \ + struct btrfs_ioctl_send_args_32) +#endif + /* Error codes as returned by the kernel */ enum btrfs_err_code { BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET = 1,