Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_masq: register/unregister notifiers on module init/exit

We have to register the notifiers in the masquerade expression from
the the module _init and _exit path.

This fixes crashes when removing the masquerade rule with no
ipt_MASQUERADE support in place (which was masking the problem).

Fixes: 9ba1f72 ("netfilter: nf_tables: add new nft_masq expression")
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Arturo Borrero and committed by
Pablo Neira Ayuso
8da4cc1b 07dcc686

+22 -46
+11 -23
net/ipv4/netfilter/nft_masq_ipv4.c
··· 32 32 data[NFT_REG_VERDICT].verdict = verdict; 33 33 } 34 34 35 - static int nft_masq_ipv4_init(const struct nft_ctx *ctx, 36 - const struct nft_expr *expr, 37 - const struct nlattr * const tb[]) 38 - { 39 - int err; 40 - 41 - err = nft_masq_init(ctx, expr, tb); 42 - if (err < 0) 43 - return err; 44 - 45 - nf_nat_masquerade_ipv4_register_notifier(); 46 - return 0; 47 - } 48 - 49 - static void nft_masq_ipv4_destroy(const struct nft_ctx *ctx, 50 - const struct nft_expr *expr) 51 - { 52 - nf_nat_masquerade_ipv4_unregister_notifier(); 53 - } 54 - 55 35 static struct nft_expr_type nft_masq_ipv4_type; 56 36 static const struct nft_expr_ops nft_masq_ipv4_ops = { 57 37 .type = &nft_masq_ipv4_type, 58 38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)), 59 39 .eval = nft_masq_ipv4_eval, 60 - .init = nft_masq_ipv4_init, 61 - .destroy = nft_masq_ipv4_destroy, 40 + .init = nft_masq_init, 62 41 .dump = nft_masq_dump, 63 42 }; 64 43 ··· 52 73 53 74 static int __init nft_masq_ipv4_module_init(void) 54 75 { 55 - return nft_register_expr(&nft_masq_ipv4_type); 76 + int ret; 77 + 78 + ret = nft_register_expr(&nft_masq_ipv4_type); 79 + if (ret < 0) 80 + return ret; 81 + 82 + nf_nat_masquerade_ipv4_register_notifier(); 83 + 84 + return ret; 56 85 } 57 86 58 87 static void __exit nft_masq_ipv4_module_exit(void) 59 88 { 60 89 nft_unregister_expr(&nft_masq_ipv4_type); 90 + nf_nat_masquerade_ipv4_unregister_notifier(); 61 91 } 62 92 63 93 module_init(nft_masq_ipv4_module_init);
+11 -23
net/ipv6/netfilter/nft_masq_ipv6.c
··· 32 32 data[NFT_REG_VERDICT].verdict = verdict; 33 33 } 34 34 35 - static int nft_masq_ipv6_init(const struct nft_ctx *ctx, 36 - const struct nft_expr *expr, 37 - const struct nlattr * const tb[]) 38 - { 39 - int err; 40 - 41 - err = nft_masq_init(ctx, expr, tb); 42 - if (err < 0) 43 - return err; 44 - 45 - nf_nat_masquerade_ipv6_register_notifier(); 46 - return 0; 47 - } 48 - 49 - static void nft_masq_ipv6_destroy(const struct nft_ctx *ctx, 50 - const struct nft_expr *expr) 51 - { 52 - nf_nat_masquerade_ipv6_unregister_notifier(); 53 - } 54 - 55 35 static struct nft_expr_type nft_masq_ipv6_type; 56 36 static const struct nft_expr_ops nft_masq_ipv6_ops = { 57 37 .type = &nft_masq_ipv6_type, 58 38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)), 59 39 .eval = nft_masq_ipv6_eval, 60 - .init = nft_masq_ipv6_init, 61 - .destroy = nft_masq_ipv6_destroy, 40 + .init = nft_masq_init, 62 41 .dump = nft_masq_dump, 63 42 }; 64 43 ··· 52 73 53 74 static int __init nft_masq_ipv6_module_init(void) 54 75 { 55 - return nft_register_expr(&nft_masq_ipv6_type); 76 + int ret; 77 + 78 + ret = nft_register_expr(&nft_masq_ipv6_type); 79 + if (ret < 0) 80 + return ret; 81 + 82 + nf_nat_masquerade_ipv6_register_notifier(); 83 + 84 + return ret; 56 85 } 57 86 58 87 static void __exit nft_masq_ipv6_module_exit(void) 59 88 { 60 89 nft_unregister_expr(&nft_masq_ipv6_type); 90 + nf_nat_masquerade_ipv6_unregister_notifier(); 61 91 } 62 92 63 93 module_init(nft_masq_ipv6_module_init);