From patchwork Sat Apr 18 13:59:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: lauri X-Patchwork-Id: 6237061 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id ED350BF4A6 for ; Sat, 18 Apr 2015 13:59:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 059FF203ED for ; Sat, 18 Apr 2015 13:59:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EBF86203EC for ; Sat, 18 Apr 2015 13:59:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753193AbbDRN7i (ORCPT ); Sat, 18 Apr 2015 09:59:38 -0400 Received: from mail-wg0-f54.google.com ([74.125.82.54]:35409 "EHLO mail-wg0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753183AbbDRN7h (ORCPT ); Sat, 18 Apr 2015 09:59:37 -0400 Received: by wgyo15 with SMTP id o15so138243666wgy.2 for ; Sat, 18 Apr 2015 06:59:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=XdrJUdTmK/Fsq0CbvoWL6LT5CX6Tt3Dp9BPZR0z0sCs=; b=akNayuzh98sf2Ba7vsL51hIM5z5OXe9qPiVH1bd2EVzbMkrN9IFqv5F7Jq5gkPllJQ BhzvAkWPH4o/B6lVPF/UnSEDuj5DsFTpGopz5GOa+Egy37Cpz43TyDCNaPy+koUYfP4w Oi3UkbJo5HXPkQLWTEnKb89x0F9Nqg9xAkVhXISu6LWAL5UkIWsBVb3g/1umqDZ17Oip kWkgZbeWc3tawrPOluCw31oTCG2y5jhbQiSq2adUe3eS4lOllot3GMsvom5M3lkeRXCB cB/NwuhGS2pTw+UdDeAaYzYMh5+CrLKy4PNvEP+mLmut7kZs0KR9FBDxRLZ/l7RKJpk7 LDtg== X-Received: by 10.194.86.135 with SMTP id p7mr14954121wjz.89.1429365575825; Sat, 18 Apr 2015 06:59:35 -0700 (PDT) Received: from localhost.localdomain ([88.128.80.54]) by mx.google.com with ESMTPSA id g14sm15580716wjs.47.2015.04.18.06.59.34 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Apr 2015 06:59:34 -0700 (PDT) From: =?UTF-8?q?Lauri=20V=C3=B5sandi?= To: linux-btrfs@vger.kernel.org Cc: =?UTF-8?q?Lauri=20V=C3=B5sandi?= Subject: [PATCH] btrfs-progs: optionally enforce chroot for btrfs receive Date: Sat, 18 Apr 2015 16:59:05 +0300 Message-Id: <1429365545-2419-1-git-send-email-lauri.vosandi@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <217a387d55b5828a82fadad98dd88a959e7a13ed.1429008167.git.lauri.vosandi@gmail.com> References: <217a387d55b5828a82fadad98dd88a959e7a13ed.1429008167.git.lauri.vosandi@gmail.com> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, 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 This patch forces btrfs receive to issue chroot before parsing the btrfs stream using command-line flag -C to confine the process and minimize damage that could be done via malicious btrfs stream. Signed-off-by: Lauri Võsandi --- cmds-receive.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/cmds-receive.c b/cmds-receive.c index 44ef27e..73bd88b 100644 --- a/cmds-receive.c +++ b/cmds-receive.c @@ -61,6 +61,7 @@ struct btrfs_receive char *root_path; char *dest_dir_path; /* relative to root_path */ char *full_subvol_path; + int dest_dir_chroot; struct subvol_info *cur_subvol; @@ -867,14 +868,27 @@ static int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd, goto out; } - /* - * find_mount_root returns a root_path that is a subpath of - * dest_dir_full_path. Now get the other part of root_path, - * which is the destination dir relative to root_path. - */ - r->dest_dir_path = dest_dir_full_path + strlen(r->root_path); - while (r->dest_dir_path[0] == '/') - r->dest_dir_path++; + if (r->dest_dir_chroot) { + if (chroot(dest_dir_full_path)) { + ret = -errno; + fprintf(stderr, + "ERROR: failed to chroot to %s, %s\n", + dest_dir_full_path, + strerror(-ret)); + goto out; + } + if(chdir("/")) { + ret = -errno; + fprintf(stderr, + "ERROR: failed to chdir to /, %s\n", + strerror(-ret)); + } + if (g_verbose >= 1) { + fprintf(stderr, "chrooted to %s\n", + dest_dir_full_path); + } + r->root_path = r->dest_dir_path = strdup("/"); + } ret = subvol_uuid_search_init(r->mnt_fd, &r->sus); if (ret < 0) @@ -940,6 +954,7 @@ int cmd_receive(int argc, char **argv) r.write_fd = -1; r.dest_dir_fd = -1; r.explicit_parent = NULL; + r.dest_dir_chroot = 0; while (1) { int c; @@ -948,7 +963,7 @@ int cmd_receive(int argc, char **argv) { NULL, 0, NULL, 0 } }; - c = getopt_long(argc, argv, "evf:p:", long_opts, NULL); + c = getopt_long(argc, argv, "Cevf:p:", long_opts, NULL); if (c < 0) break; @@ -962,6 +977,9 @@ int cmd_receive(int argc, char **argv) case 'e': r.honor_end_cmd = 1; break; + case 'C': + r.dest_dir_chroot = 1; + break; case 'E': max_errors = arg_strtou64(optarg); break; @@ -1014,6 +1032,7 @@ const char * const cmd_receive_usage[] = { " in the data stream. Without this option,", " the receiver terminates only if an error", " is recognized or on EOF.", + "-C Confine the process to using chroot", "--max-errors Terminate as soon as N errors happened while", " processing commands from the send stream.", " Default value is 1. A value of 0 means no limit.",