summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Cernekee <cernekee@chromium.org>2017-01-26 14:49:44 -0800
committerPablo Neira Ayuso <pablo@netfilter.org>2017-02-06 12:49:05 +0100
commitf95d7a46bc5722767c30ee223c8b67dd0f2e8793 (patch)
treec22899b99bfdf4d9bbe7eabc33ba013f7dea79a9
parenta963d710f367f68cd13d562a07db55ccb8daade9 (diff)
downloadop-kernel-dev-f95d7a46bc5722767c30ee223c8b67dd0f2e8793.zip
op-kernel-dev-f95d7a46bc5722767c30ee223c8b67dd0f2e8793.tar.gz
netfilter: ctnetlink: Fix regression in CTA_HELP processing
Prior to Linux 4.4, it was usually harmless to send a CTA_HELP attribute containing the name of the current helper. That is no longer the case: as of Linux 4.4, if ctnetlink_change_helper() returns an error from the ct->master check, processing of the request will fail, skipping the NFQA_EXP attribute (if present). This patch changes the behavior to improve compatibility with user programs that expect the kernel interface to work the way it did prior to Linux 4.4. If a user program specifies CTA_HELP but the argument matches the current conntrack helper name, ignore it instead of generating an error. Signed-off-by: Kevin Cernekee <cernekee@chromium.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nf_conntrack_netlink.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index bf04b7e9..6806b5e 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1478,14 +1478,23 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
struct nlattr *helpinfo = NULL;
int err;
- /* don't change helper of sibling connections */
- if (ct->master)
- return -EBUSY;
-
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
if (err < 0)
return err;
+ /* don't change helper of sibling connections */
+ if (ct->master) {
+ /* If we try to change the helper to the same thing twice,
+ * treat the second attempt as a no-op instead of returning
+ * an error.
+ */
+ if (help && help->helper &&
+ !strcmp(help->helper->name, helpname))
+ return 0;
+ else
+ return -EBUSY;
+ }
+
if (!strcmp(helpname, "")) {
if (help && help->helper) {
/* we had a helper before ... */
OpenPOWER on IntegriCloud