aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiping Zhang <liping.zhang@spreadtrum.com>2016-07-23 04:00:31 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2016-07-23 06:22:07 -0400
commit2bf4fade54de995f84d319ae02003609dca450f3 (patch)
tree024cb3652c7f57ae1dc8ef1df2333a2d4a2c581d
parent96d1327ac2e3dc3ac4204fe3656dad0043fc0efd (diff)
netfilter: nft_compat: put back match/target module if init fail
If the user specify the invalid NFTA_MATCH_INFO/NFTA_TARGET_INFO attr or memory alloc fail, we should call module_put to the related match or target. Otherwise, we cannot remove the module even nobody use it. Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nft_compat.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 6228c422c766..2e07cec50ffd 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -634,6 +634,7 @@ nft_match_select_ops(const struct nft_ctx *ctx,
634 struct xt_match *match; 634 struct xt_match *match;
635 char *mt_name; 635 char *mt_name;
636 u32 rev, family; 636 u32 rev, family;
637 int err;
637 638
638 if (tb[NFTA_MATCH_NAME] == NULL || 639 if (tb[NFTA_MATCH_NAME] == NULL ||
639 tb[NFTA_MATCH_REV] == NULL || 640 tb[NFTA_MATCH_REV] == NULL ||
@@ -660,13 +661,17 @@ nft_match_select_ops(const struct nft_ctx *ctx,
660 if (IS_ERR(match)) 661 if (IS_ERR(match))
661 return ERR_PTR(-ENOENT); 662 return ERR_PTR(-ENOENT);
662 663
663 if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) 664 if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) {
664 return ERR_PTR(-EINVAL); 665 err = -EINVAL;
666 goto err;
667 }
665 668
666 /* This is the first time we use this match, allocate operations */ 669 /* This is the first time we use this match, allocate operations */
667 nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 670 nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL);
668 if (nft_match == NULL) 671 if (nft_match == NULL) {
669 return ERR_PTR(-ENOMEM); 672 err = -ENOMEM;
673 goto err;
674 }
670 675
671 nft_match->ops.type = &nft_match_type; 676 nft_match->ops.type = &nft_match_type;
672 nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize)); 677 nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
@@ -680,6 +685,9 @@ nft_match_select_ops(const struct nft_ctx *ctx,
680 list_add(&nft_match->head, &nft_match_list); 685 list_add(&nft_match->head, &nft_match_list);
681 686
682 return &nft_match->ops; 687 return &nft_match->ops;
688err:
689 module_put(match->me);
690 return ERR_PTR(err);
683} 691}
684 692
685static void nft_match_release(void) 693static void nft_match_release(void)
@@ -717,6 +725,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
717 struct xt_target *target; 725 struct xt_target *target;
718 char *tg_name; 726 char *tg_name;
719 u32 rev, family; 727 u32 rev, family;
728 int err;
720 729
721 if (tb[NFTA_TARGET_NAME] == NULL || 730 if (tb[NFTA_TARGET_NAME] == NULL ||
722 tb[NFTA_TARGET_REV] == NULL || 731 tb[NFTA_TARGET_REV] == NULL ||
@@ -743,13 +752,17 @@ nft_target_select_ops(const struct nft_ctx *ctx,
743 if (IS_ERR(target)) 752 if (IS_ERR(target))
744 return ERR_PTR(-ENOENT); 753 return ERR_PTR(-ENOENT);
745 754
746 if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) 755 if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) {
747 return ERR_PTR(-EINVAL); 756 err = -EINVAL;
757 goto err;
758 }
748 759
749 /* This is the first time we use this target, allocate operations */ 760 /* This is the first time we use this target, allocate operations */
750 nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL); 761 nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL);
751 if (nft_target == NULL) 762 if (nft_target == NULL) {
752 return ERR_PTR(-ENOMEM); 763 err = -ENOMEM;
764 goto err;
765 }
753 766
754 nft_target->ops.type = &nft_target_type; 767 nft_target->ops.type = &nft_target_type;
755 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); 768 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
@@ -767,6 +780,9 @@ nft_target_select_ops(const struct nft_ctx *ctx,
767 list_add(&nft_target->head, &nft_target_list); 780 list_add(&nft_target->head, &nft_target_list);
768 781
769 return &nft_target->ops; 782 return &nft_target->ops;
783err:
784 module_put(target->me);
785 return ERR_PTR(err);
770} 786}
771 787
772static void nft_target_release(void) 788static void nft_target_release(void)