From patchwork Thu Aug 26 21:19:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 12460751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49F68C432BE for ; Thu, 26 Aug 2021 21:36:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DA43B60698 for ; Thu, 26 Aug 2021 21:36:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org DA43B60698 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:53822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mJN2X-0005ZR-3f for qemu-devel@archiver.kernel.org; Thu, 26 Aug 2021 17:36:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41260) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJMnG-00067s-Ke for qemu-devel@nongnu.org; Thu, 26 Aug 2021 17:20:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:49350) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJMnD-00038F-88 for qemu-devel@nongnu.org; Thu, 26 Aug 2021 17:20:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1630012809; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ej4BQlDyf/RX0fz2OHmOyIXmS6uOAnkuOzgjyfuQIbU=; b=EkBhSaVtHPofqMXuxARYfD+rUs+Nw1EZK4/7vWgXV0703wVaC6nZAM0Sm2nPRQaZAY1z4R UhVgGY4cB+kfoZlXObj2aWaY3u7RIOZxYkPJJYwNEChfG1q8YPwmNY4r3Bd6JaQIJnEOWw XmKOs5OVFgchA9PBJauDqbRSCOhJRKM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-562-PKkFc9YDO7GxFvEi7sxTOg-1; Thu, 26 Aug 2021 17:20:08 -0400 X-MC-Unique: PKkFc9YDO7GxFvEi7sxTOg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3A6D98031F9 for ; Thu, 26 Aug 2021 21:19:47 +0000 (UTC) Received: from horse.redhat.com (unknown [10.22.17.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id F2AB86A8FB; Thu, 26 Aug 2021 21:19:46 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 802D42281A8; Thu, 26 Aug 2021 17:19:46 -0400 (EDT) From: Vivek Goyal To: qemu-devel@nongnu.org, virtio-fs@redhat.com Subject: [PATCH 1/2] virtiofsd: Add an array to keep track of blocked xattrs Date: Thu, 26 Aug 2021 17:19:36 -0400 Message-Id: <20210826211937.317558-2-vgoyal@redhat.com> In-Reply-To: <20210826211937.317558-1-vgoyal@redhat.com> References: <20210826211937.317558-1-vgoyal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=vgoyal@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=vgoyal@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.742, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com, vgoyal@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Right now we have capability to block "system.posix_acl_access" and "system.posix_acl_default" xattrs. But we have sort of hardcoded these two values and its not generic. Now we want to support blocking of arbitrary xattr as passed in by user. So let us keep an array of blocked xattrs and consult that array when deciding whether an attribute is blocked or not. This should not result any functional change. Signed-off-by: Vivek Goyal --- tools/virtiofsd/passthrough_ll.c | 77 ++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 38b2af8599..9e93bcdbb3 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -176,6 +176,8 @@ struct lo_data { /* If set, virtiofsd is responsible for setting umask during creation */ bool change_umask; int user_posix_acl, posix_acl; + char **blocked_xattrs; + size_t num_blocked_xattrs; }; static const struct fuse_opt lo_opts[] = { @@ -2811,19 +2813,57 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name, assert(fchdir_res == 0); \ } while (0) +/* Returns 0 on success, 1 on failure */ +static int add_blocked_xattr(struct lo_data *lo, const char *name) +{ + size_t nr_elems = lo->num_blocked_xattrs + 1; + + lo->blocked_xattrs = reallocarray(lo->blocked_xattrs, nr_elems, + sizeof(char *)); + if (!lo->blocked_xattrs) { + fuse_log(FUSE_LOG_ERR, "failed to grow blocked xattrs array: %m\n"); + return 1; + } + + lo->blocked_xattrs[nr_elems - 1] = strdup(name); + if (!lo->blocked_xattrs[nr_elems - 1]) { + fuse_log(FUSE_LOG_ERR, "strdup(%s) failed: %m\n", name); + return 1; + } + lo->num_blocked_xattrs++; + return 0; +} + +static void free_blocked_xattrs(struct lo_data *lo) +{ + size_t i; + + if (!lo->num_blocked_xattrs) { + return; + } + + for (i = 0; i < lo->num_blocked_xattrs; i++) { + free(lo->blocked_xattrs[i]); + } + + free(lo->blocked_xattrs); + lo->num_blocked_xattrs = 0; + lo->blocked_xattrs = NULL; +} + static bool block_xattr(struct lo_data *lo, const char *name) { - /* - * If user explicitly enabled posix_acl or did not provide any option, - * do not block acl. Otherwise block system.posix_acl_access and - * system.posix_acl_default xattrs. - */ - if (lo->user_posix_acl) { + size_t i; + + if (!lo->num_blocked_xattrs) { return false; } - if (!strcmp(name, "system.posix_acl_access") || - !strcmp(name, "system.posix_acl_default")) + + for (i = 0; i < lo->num_blocked_xattrs; i++) { + if (!strcmp(name, lo->blocked_xattrs[i])) { return true; + } + } return false; } @@ -2840,12 +2880,7 @@ static int remove_blocked_xattrs(struct lo_data *lo, char *xattr_list, { size_t out_index, in_index; - /* - * As of now we only filter out acl xattrs. If acls are enabled or - * they have not been explicitly disabled, there is nothing to - * filter. - */ - if (lo->user_posix_acl) { + if (!lo->num_blocked_xattrs) { return in_size; } @@ -3880,6 +3915,7 @@ static void fuse_lo_data_cleanup(struct lo_data *lo) free(lo->xattrmap); free_xattrmap(lo); free(lo->xattr_security_capability); + free_blocked_xattrs(lo); free(lo->source); } @@ -3920,6 +3956,8 @@ int main(int argc, char *argv[]) lo.root.fd = -1; lo.root.fuse_ino = FUSE_ROOT_ID; lo.cache = CACHE_AUTO; + lo.num_blocked_xattrs = 0; + lo.blocked_xattrs = NULL; /* * Set up the ino map like this: @@ -4036,6 +4074,17 @@ int main(int argc, char *argv[]) exit(1); } + if (!lo.user_posix_acl) { + /* User disabled posix acl explicitly. Block acl xattrs */ + if (add_blocked_xattr(&lo, "system.posix_acl_access")) { + exit(1); + } + + if (add_blocked_xattr(&lo, "system.posix_acl_default")) { + exit(1); + } + } + lo.use_statx = true; se = fuse_session_new(&args, &lo_oper, sizeof(lo_oper), &lo); From patchwork Thu Aug 26 21:19:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 12460757 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4E39CC432BE for ; Thu, 26 Aug 2021 21:37:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EBA3E60EB3 for ; Thu, 26 Aug 2021 21:37:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EBA3E60EB3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:60230 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mJN4J-0001UH-4r for qemu-devel@archiver.kernel.org; Thu, 26 Aug 2021 17:37:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41306) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJMnO-0006Jb-L8 for qemu-devel@nongnu.org; Thu, 26 Aug 2021 17:20:23 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:27196) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJMnM-0003FP-2X for qemu-devel@nongnu.org; Thu, 26 Aug 2021 17:20:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1630012819; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1VJhbwoZfoEX/qUOvpVOqjzUcNw33zvAuxlLHDtSvP8=; b=VrqSCYosrk2De3nLYKh7k44EwxD9TT8Av2K6et2+EO4BM2OonIcA8Xi3TPc49wuI59FxbC sHL+OjAPI60IYptQ4e4TQTFJD2rpanOVd4MtvwIsyCMNYXRQsnrqycmMzhwEtpi/nIjxqR yjEnfmTV0FadfC9Ds9WKQQGS0P9nkRE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-295-DtVn6aLcP6mqBH4bihSiSw-1; Thu, 26 Aug 2021 17:20:17 -0400 X-MC-Unique: DtVn6aLcP6mqBH4bihSiSw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 39CA8CF98D for ; Thu, 26 Aug 2021 21:19:47 +0000 (UTC) Received: from horse.redhat.com (unknown [10.22.17.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id F2A016A8F8; Thu, 26 Aug 2021 21:19:46 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 876FB2281A9; Thu, 26 Aug 2021 17:19:46 -0400 (EDT) From: Vivek Goyal To: qemu-devel@nongnu.org, virtio-fs@redhat.com Subject: [PATCH 2/2] virtiofsd: Add option "block_xattr=" to block certain xattrs Date: Thu, 26 Aug 2021 17:19:37 -0400 Message-Id: <20210826211937.317558-3-vgoyal@redhat.com> In-Reply-To: <20210826211937.317558-1-vgoyal@redhat.com> References: <20210826211937.317558-1-vgoyal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=vgoyal@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=vgoyal@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.742, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com, vgoyal@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We need capability to block security.selinux xattr and return EOPNOTSUPP. That way guest SELinux thinks filesystem does not support selinux xattr and falls back to some default label (virtiofs_t) for the virtiofs filesystem instance. So add a generic option "-o block_xattr=", which can allow user to specify a list of xattrs to block. Xattrs should be ":" separated. For example, "-o block_xattr=security.selinux:user.foo". Valid xattrs to block should belong to one of of the "security", "system", "trusted" or "user" xattr namespace. Ex. -o block_xattr="security.selinux:user.foo" One can also specify prefix which should be matched against xattr name and if prefix matches, that xattr will be blocked. Requirement of xattr belonging to one of the 4 namepsaces still remain in place. For example -o block_xattr="user.virtiofs*" should block any xattr name starting with prefix "user.virtiofs". Signed-off-by: Vivek Goyal --- docs/tools/virtiofsd.rst | 17 ++++++ tools/virtiofsd/helper.c | 3 + tools/virtiofsd/passthrough_ll.c | 101 ++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst index b208f2a6f0..406c1ab721 100644 --- a/docs/tools/virtiofsd.rst +++ b/docs/tools/virtiofsd.rst @@ -101,6 +101,23 @@ Options Enable/disable extended attributes (xattr) on files and directories. The default is ``no_xattr``. + * block_xattr= - + Block xattrs specified in the colon separated list. When an xattr + is blocked getxattr/setxattr/removexattr return error code + EOPNOTSUPP, and listxattr removes the xattr from list if there is one. + + xattr name should belong to one of the four namespsaces, namely + security, system, trusted and user. + + e.g. -o block_xattr=security.selinux:user.foo + + One could also specify just a xattr name prefix followed by "*" to + signify any xattr name matching prefix will be blocked. + + e.g -o block_xattr=user.foo* + + This will block any xattr name starting with "user.foo" + * posix_acl|no_posix_acl - Enable/disable posix acl support. Posix ACLs are disabled by default. diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c index a8295d975a..da674ff70a 100644 --- a/tools/virtiofsd/helper.c +++ b/tools/virtiofsd/helper.c @@ -175,6 +175,9 @@ void fuse_cmdline_help(void) " -o xattrmap= Enable xattr mapping (enables xattr)\n" " is a string consists of a series of rules\n" " e.g. -o xattrmap=:map::user.virtiofs.:\n" + " -o block_xattr= Block xattrs specified in list\n" + " is colon separated list of xattrs to block\n" + " e.g. -o block_xattr=security.selinux:user.*\n" " -o modcaps=CAPLIST Modify the list of capabilities\n" " e.g. -o modcaps=+sys_admin:-chown\n" " --rlimit-nofile= set maximum number of file descriptors\n" diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 9e93bcdbb3..2008e6be55 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -142,6 +142,12 @@ typedef struct xattr_map_entry { unsigned int flags; } XattrMapEntry; +struct xattr_block_entry { + /* true if name is prefix otherwise false */ + bool prefix; + char *name; +}; + struct lo_data { pthread_mutex_t mutex; int sandbox; @@ -176,8 +182,9 @@ struct lo_data { /* If set, virtiofsd is responsible for setting umask during creation */ bool change_umask; int user_posix_acl, posix_acl; - char **blocked_xattrs; + struct xattr_block_entry *blocked_xattrs; size_t num_blocked_xattrs; + char *block_xattr_str; }; static const struct fuse_opt lo_opts[] = { @@ -212,6 +219,7 @@ static const struct fuse_opt lo_opts[] = { { "no_killpriv_v2", offsetof(struct lo_data, user_killpriv_v2), 0 }, { "posix_acl", offsetof(struct lo_data, user_posix_acl), 1 }, { "no_posix_acl", offsetof(struct lo_data, user_posix_acl), 0 }, + { "block_xattr=%s", offsetof(struct lo_data, block_xattr_str), 0 }, FUSE_OPT_END }; static bool use_syslog = false; @@ -2817,23 +2825,88 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name, static int add_blocked_xattr(struct lo_data *lo, const char *name) { size_t nr_elems = lo->num_blocked_xattrs + 1; + struct xattr_block_entry *xbe; + char *ptr; lo->blocked_xattrs = reallocarray(lo->blocked_xattrs, nr_elems, - sizeof(char *)); + sizeof(struct xattr_block_entry)); if (!lo->blocked_xattrs) { fuse_log(FUSE_LOG_ERR, "failed to grow blocked xattrs array: %m\n"); return 1; } - lo->blocked_xattrs[nr_elems - 1] = strdup(name); - if (!lo->blocked_xattrs[nr_elems - 1]) { + xbe = &lo->blocked_xattrs[nr_elems - 1]; + xbe->prefix = false; + + ptr = strchr(name, '*'); + if (ptr) { + xbe->prefix = true; + *ptr = '\0'; + } + + xbe->name = strdup(name); + if (!xbe->name) { fuse_log(FUSE_LOG_ERR, "strdup(%s) failed: %m\n", name); return 1; } + lo->num_blocked_xattrs++; return 0; } +/* Returns true on success, false on error */ +static bool valid_block_xattr(char *name) +{ + char *ptr; + + if (!g_str_has_prefix(name, "user.") && + !g_str_has_prefix(name, "system.") && + !g_str_has_prefix(name, "security.") && + !g_str_has_prefix(name, "trusted.")) { + return false; + } + + ptr = strchr(name, '*'); + if (!ptr) { + return true; + } + + /* if there is a '*' in name, it should be last char */ + if (*++ptr != '\0') { + return false; + } + return true; +} + +/* Returns 0 on success, 1 on error */ +static int parse_block_xattr(struct lo_data *lo, char *block_xattr_str) +{ + char *token, *parse_str; + + /* strtok() modifies the string passed. So work on the copy */ + parse_str = strdup(block_xattr_str); + if (!parse_str) { + fuse_log(FUSE_LOG_ERR, "Failed strdup(%s):%m\n", block_xattr_str); + return 1; + } + + while ((token = strtok(parse_str, ":"))) { + parse_str = NULL; + if (!valid_block_xattr(token)) { + fuse_log(FUSE_LOG_ERR, "Invalid xattr to block: %s\n", token); + return 1; + } + if (add_blocked_xattr(lo, token)) { + fuse_log(FUSE_LOG_ERR, "Failed to add blocked xattr %s\n", + token); + free(parse_str); + return 1; + } + } + free(parse_str); + return 0; +} + static void free_blocked_xattrs(struct lo_data *lo) { size_t i; @@ -2843,7 +2916,7 @@ static void free_blocked_xattrs(struct lo_data *lo) } for (i = 0; i < lo->num_blocked_xattrs; i++) { - free(lo->blocked_xattrs[i]); + free(lo->blocked_xattrs[i].name); } free(lo->blocked_xattrs); @@ -2854,14 +2927,22 @@ static void free_blocked_xattrs(struct lo_data *lo) static bool block_xattr(struct lo_data *lo, const char *name) { size_t i; + struct xattr_block_entry *xbe; if (!lo->num_blocked_xattrs) { return false; } for (i = 0; i < lo->num_blocked_xattrs; i++) { - if (!strcmp(name, lo->blocked_xattrs[i])) { - return true; + xbe = &lo->blocked_xattrs[i]; + if (xbe->prefix) { + if (g_str_has_prefix(name, xbe->name)) { + return true; + } + } else { + if (!strcmp(name, xbe->name)) { + return true; + } } } @@ -4068,6 +4149,12 @@ int main(int argc, char *argv[]) exit(1); } + if (lo.block_xattr_str) { + if (parse_block_xattr(&lo, lo.block_xattr_str)) { + exit(1); + } + } + if (lo.user_posix_acl == 1 && !lo.xattr) { fuse_log(FUSE_LOG_ERR, "Can't enable posix ACLs. xattrs are disabled." "\n");