Received: by 2002:a05:6a10:d5a5:0:0:0:0 with SMTP id gn37csp3789061pxb; Mon, 4 Oct 2021 09:37:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxpBv3zdjJz2myJaBaNi4TvtBmYXSCPgb3qkr7PeSVbax1w5xkE9tZNa7NjY6xl+TITTvcy X-Received: by 2002:a17:907:785a:: with SMTP id lb26mr18093019ejc.77.1633365433575; Mon, 04 Oct 2021 09:37:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633365433; cv=none; d=google.com; s=arc-20160816; b=RCbFh3SXSLkZtnpYUmOZ6aZRox5ZIyZbQnHLZ3WnYGovS+O7dkGCIZnRRFu5zAS9gB PWyNQ+xGt5GT7c7W/KiQRo52zmQmnzeryrUqL4MXf1GET/RequPXu/AEwq5LfgJrJfYZ Wmi148vJPgfDF87WGGNJKf7NDOuEJRl9mJFV1rQEs9pu4QstyY5plfH5oiqyA3+PKq8A sYbXo53ytVpCRSeQQI//Ffq30D6cteNfVp0Ri9RCLPQOxL8eZ8Go2F0qAR7MQlzR+yKn hszrSubAXBa9BLfGsxQWXjWZ0ZjPyOJZvol7Pb1vmwKidLAkmngndT4FSICXH4Hkx7m6 QfDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Csjpi3+dUzZdNB5K4SsZtB0aHqzb6IcZx5K50CMhSB0=; b=cVXs4keCeoD8KpMLh4hOxWetkGBRAgJ96g6hsce0RNjq6RKhH9K4e0rM1PaB0JwysQ U5XQsNyvhijUUBPFFXO9L4Mh70mKXBnTMylrAEduXxIQ8bNVPCgjpe84kzte1IaFVDsj mEUOjUnnJdWSLSN0JG3WxI3htt4kBfMaOFYrOtvjdtXv0bDD/pBPt5mc8go0k6HlfVrm A93usyny5VDSIy3oI2vc/2H6EmdMv2wW6pudO+WlInP3cnq+/lRBAydcoLLSWTc8St8I KYy68SYmdRkjYPZxoiAx599fC7vCaoB0JWr0CjdAwVBisFwJuCJ22B30x9Utht9Kt8VX ndFA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=2dmHcVDY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z2si312579eju.533.2021.10.04.09.36.47; Mon, 04 Oct 2021 09:37:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=2dmHcVDY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237266AbhJDNgQ (ORCPT + 99 others); Mon, 4 Oct 2021 09:36:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:48814 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236269AbhJDNdv (ORCPT ); Mon, 4 Oct 2021 09:33:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id C136961AAC; Mon, 4 Oct 2021 13:15:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1633353333; bh=mOgugXgcLv2VxWNy/hGeUqDkIQm2ezwHnXM9Shl0ZrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2dmHcVDYfonHoPKtAnoNtluPiUgRqKyr8MuPRt6D5Y8rKAlJ+qvlxNiROh/rjnaee NhOA8azJsNHO3P5RA6VOXWteIaQB1c7ZjU8SOE/U4X0LoSmNm3PIjzTs5brGkRLiLU bIRnQe43ho7L51uMRbXyZ/3dYlXU627iZv94jweo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Florian Westphal , Pablo Neira Ayuso , Sasha Levin , Eric Dumazet Subject: [PATCH 5.14 087/172] netfilter: log: work around missing softdep backend module Date: Mon, 4 Oct 2021 14:52:17 +0200 Message-Id: <20211004125047.798905253@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211004125044.945314266@linuxfoundation.org> References: <20211004125044.945314266@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Florian Westphal [ Upstream commit b53deef054e58fe4f37c66211b8ece9f8fc1aa13 ] iptables/nftables has two types of log modules: 1. backend, e.g. nf_log_syslog, which implement the functionality 2. frontend, e.g. xt_LOG or nft_log, which call the functionality provided by backend based on nf_tables or xtables rule set. Problem is that the request_module() call to load the backed in nf_logger_find_get() might happen with nftables transaction mutex held in case the call path is via nf_tables/nft_compat. This can cause deadlocks (see 'Fixes' tags for details). The chosen solution as to let modprobe deal with this by adding 'pre: ' soft dep tag to xt_LOG (to load the syslog backend) and xt_NFLOG (to load nflog backend). Eric reports that this breaks on systems with older modprobe that doesn't support softdeps. Another, similar issue occurs when someone either insmods xt_(NF)LOG directly or unloads the backend module (possible if no log frontend is in use): because the frontend module is already loaded, modprobe is not invoked again so the softdep isn't evaluated. Add a workaround: If nf_logger_find_get() returns -ENOENT and call is not via nft_compat, load the backend explicitly and try again. Else, let nft_compat ask for deferred request_module via nf_tables infra. Softdeps are kept in-place, so with newer modprobe the dependencies are resolved from userspace. Fixes: cefa31a9d461 ("netfilter: nft_log: perform module load from nf_tables") Fixes: a38b5b56d6f4 ("netfilter: nf_log: add module softdeps") Reported-and-tested-by: Eric Dumazet Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_compat.c | 17 ++++++++++++++++- net/netfilter/xt_LOG.c | 10 +++++++++- net/netfilter/xt_NFLOG.c | 10 +++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 272bcdb1392d..f69cc73c5813 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Used for matches where *info is larger than X byte */ #define NFT_MATCH_LARGE_THRESH 192 @@ -257,8 +258,22 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, nft_compat_wait_for_destructors(); ret = xt_check_target(&par, size, proto, inv); - if (ret < 0) + if (ret < 0) { + if (ret == -ENOENT) { + const char *modname = NULL; + + if (strcmp(target->name, "LOG") == 0) + modname = "nf_log_syslog"; + else if (strcmp(target->name, "NFLOG") == 0) + modname = "nfnetlink_log"; + + if (modname && + nft_request_module(ctx->net, "%s", modname) == -EAGAIN) + return -EAGAIN; + } + return ret; + } /* The standard target cannot be used */ if (!target->target) diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index 2ff75f7637b0..f39244f9c0ed 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c @@ -44,6 +44,7 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par) static int log_tg_check(const struct xt_tgchk_param *par) { const struct xt_log_info *loginfo = par->targinfo; + int ret; if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6) return -EINVAL; @@ -58,7 +59,14 @@ static int log_tg_check(const struct xt_tgchk_param *par) return -EINVAL; } - return nf_logger_find_get(par->family, NF_LOG_TYPE_LOG); + ret = nf_logger_find_get(par->family, NF_LOG_TYPE_LOG); + if (ret != 0 && !par->nft_compat) { + request_module("%s", "nf_log_syslog"); + + ret = nf_logger_find_get(par->family, NF_LOG_TYPE_LOG); + } + + return ret; } static void log_tg_destroy(const struct xt_tgdtor_param *par) diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c index fb5793208059..e660c3710a10 100644 --- a/net/netfilter/xt_NFLOG.c +++ b/net/netfilter/xt_NFLOG.c @@ -42,13 +42,21 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par) static int nflog_tg_check(const struct xt_tgchk_param *par) { const struct xt_nflog_info *info = par->targinfo; + int ret; if (info->flags & ~XT_NFLOG_MASK) return -EINVAL; if (info->prefix[sizeof(info->prefix) - 1] != '\0') return -EINVAL; - return nf_logger_find_get(par->family, NF_LOG_TYPE_ULOG); + ret = nf_logger_find_get(par->family, NF_LOG_TYPE_ULOG); + if (ret != 0 && !par->nft_compat) { + request_module("%s", "nfnetlink_log"); + + ret = nf_logger_find_get(par->family, NF_LOG_TYPE_ULOG); + } + + return ret; } static void nflog_tg_destroy(const struct xt_tgdtor_param *par) -- 2.33.0