diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-03-19 12:32:59 -0400 |
---|---|---|
committer | Jan Engelhardt <jengelh@medozas.de> | 2010-03-25 11:56:09 -0400 |
commit | 4a5a5c73b7cfee46a0b1411903cfa0dea532deec (patch) | |
tree | 3f7ef0def4adf3a01e15ab3a2a7231967b87bfee /net/netfilter | |
parent | d6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddc (diff) |
netfilter: xtables: slightly better error reporting
When extended status codes are available, such as ENOMEM on failed
allocations, or subsequent functions (e.g. nf_ct_get_l3proto), passing
them up to userspace seems like a good idea compared to just always
EINVAL.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/xt_CONNSECMARK.c | 8 | ||||
-rw-r--r-- | net/netfilter/xt_CT.c | 11 | ||||
-rw-r--r-- | net/netfilter/xt_DSCP.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_HL.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_LED.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_NFQUEUE.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_RATEEST.c | 9 | ||||
-rw-r--r-- | net/netfilter/xt_SECMARK.c | 16 | ||||
-rw-r--r-- | net/netfilter/xt_cluster.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_connbytes.c | 6 | ||||
-rw-r--r-- | net/netfilter/xt_connlimit.c | 8 | ||||
-rw-r--r-- | net/netfilter/xt_connmark.c | 14 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 7 | ||||
-rw-r--r-- | net/netfilter/xt_dscp.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_hashlimit.c | 32 | ||||
-rw-r--r-- | net/netfilter/xt_helper.c | 6 | ||||
-rw-r--r-- | net/netfilter/xt_limit.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_quota.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_rateest.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_recent.c | 5 | ||||
-rw-r--r-- | net/netfilter/xt_state.c | 7 | ||||
-rw-r--r-- | net/netfilter/xt_statistic.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_string.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_time.c | 2 |
24 files changed, 101 insertions, 56 deletions
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 2287a82a0703..105a62e985d3 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c | |||
@@ -87,6 +87,7 @@ connsecmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
87 | static int connsecmark_tg_check(const struct xt_tgchk_param *par) | 87 | static int connsecmark_tg_check(const struct xt_tgchk_param *par) |
88 | { | 88 | { |
89 | const struct xt_connsecmark_target_info *info = par->targinfo; | 89 | const struct xt_connsecmark_target_info *info = par->targinfo; |
90 | int ret; | ||
90 | 91 | ||
91 | if (strcmp(par->table, "mangle") != 0 && | 92 | if (strcmp(par->table, "mangle") != 0 && |
92 | strcmp(par->table, "security") != 0) { | 93 | strcmp(par->table, "security") != 0) { |
@@ -102,13 +103,14 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par) | |||
102 | 103 | ||
103 | default: | 104 | default: |
104 | pr_info("invalid mode: %hu\n", info->mode); | 105 | pr_info("invalid mode: %hu\n", info->mode); |
105 | return false; | 106 | return -EINVAL; |
106 | } | 107 | } |
107 | 108 | ||
108 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 109 | ret = nf_ct_l3proto_try_module_get(par->family); |
110 | if (ret < 0) { | ||
109 | pr_info("cannot load conntrack support for proto=%u\n", | 111 | pr_info("cannot load conntrack support for proto=%u\n", |
110 | par->family); | 112 | par->family); |
111 | return -EINVAL; | 113 | return ret; |
112 | } | 114 | } |
113 | return 0; | 115 | return 0; |
114 | } | 116 | } |
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index ee566e2e4534..65dd348ae361 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
@@ -59,6 +59,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par) | |||
59 | struct nf_conntrack_tuple t; | 59 | struct nf_conntrack_tuple t; |
60 | struct nf_conn_help *help; | 60 | struct nf_conn_help *help; |
61 | struct nf_conn *ct; | 61 | struct nf_conn *ct; |
62 | int ret = 0; | ||
62 | u8 proto; | 63 | u8 proto; |
63 | 64 | ||
64 | if (info->flags & ~XT_CT_NOTRACK) | 65 | if (info->flags & ~XT_CT_NOTRACK) |
@@ -75,28 +76,34 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par) | |||
75 | goto err1; | 76 | goto err1; |
76 | #endif | 77 | #endif |
77 | 78 | ||
78 | if (nf_ct_l3proto_try_module_get(par->family) < 0) | 79 | ret = nf_ct_l3proto_try_module_get(par->family); |
80 | if (ret < 0) | ||
79 | goto err1; | 81 | goto err1; |
80 | 82 | ||
81 | memset(&t, 0, sizeof(t)); | 83 | memset(&t, 0, sizeof(t)); |
82 | ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL); | 84 | ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL); |
85 | ret = PTR_ERR(ct); | ||
83 | if (IS_ERR(ct)) | 86 | if (IS_ERR(ct)) |
84 | goto err2; | 87 | goto err2; |
85 | 88 | ||
89 | ret = 0; | ||
86 | if ((info->ct_events || info->exp_events) && | 90 | if ((info->ct_events || info->exp_events) && |
87 | !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, | 91 | !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, |
88 | GFP_KERNEL)) | 92 | GFP_KERNEL)) |
89 | goto err3; | 93 | goto err3; |
90 | 94 | ||
91 | if (info->helper[0]) { | 95 | if (info->helper[0]) { |
96 | ret = -ENOENT; | ||
92 | proto = xt_ct_find_proto(par); | 97 | proto = xt_ct_find_proto(par); |
93 | if (!proto) | 98 | if (!proto) |
94 | goto err3; | 99 | goto err3; |
95 | 100 | ||
101 | ret = -ENOMEM; | ||
96 | help = nf_ct_helper_ext_add(ct, GFP_KERNEL); | 102 | help = nf_ct_helper_ext_add(ct, GFP_KERNEL); |
97 | if (help == NULL) | 103 | if (help == NULL) |
98 | goto err3; | 104 | goto err3; |
99 | 105 | ||
106 | ret = -ENOENT; | ||
100 | help->helper = nf_conntrack_helper_try_module_get(info->helper, | 107 | help->helper = nf_conntrack_helper_try_module_get(info->helper, |
101 | par->family, | 108 | par->family, |
102 | proto); | 109 | proto); |
@@ -115,7 +122,7 @@ err3: | |||
115 | err2: | 122 | err2: |
116 | nf_ct_l3proto_module_put(par->family); | 123 | nf_ct_l3proto_module_put(par->family); |
117 | err1: | 124 | err1: |
118 | return -EINVAL; | 125 | return ret; |
119 | } | 126 | } |
120 | 127 | ||
121 | static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par) | 128 | static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par) |
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c index aa263b80f8c0..969634f293e5 100644 --- a/net/netfilter/xt_DSCP.c +++ b/net/netfilter/xt_DSCP.c | |||
@@ -66,7 +66,7 @@ static int dscp_tg_check(const struct xt_tgchk_param *par) | |||
66 | 66 | ||
67 | if (info->dscp > XT_DSCP_MAX) { | 67 | if (info->dscp > XT_DSCP_MAX) { |
68 | pr_info("dscp %x out of range\n", info->dscp); | 68 | pr_info("dscp %x out of range\n", info->dscp); |
69 | return -EINVAL; | 69 | return -EDOM; |
70 | } | 70 | } |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
diff --git a/net/netfilter/xt_HL.c b/net/netfilter/xt_HL.c index 7a47383ec723..77b99f732711 100644 --- a/net/netfilter/xt_HL.c +++ b/net/netfilter/xt_HL.c | |||
@@ -107,7 +107,7 @@ static int ttl_tg_check(const struct xt_tgchk_param *par) | |||
107 | 107 | ||
108 | if (info->mode > IPT_TTL_MAXMODE) { | 108 | if (info->mode > IPT_TTL_MAXMODE) { |
109 | pr_info("TTL: invalid or unknown mode %u\n", info->mode); | 109 | pr_info("TTL: invalid or unknown mode %u\n", info->mode); |
110 | return false; | 110 | return -EINVAL; |
111 | } | 111 | } |
112 | if (info->mode != IPT_TTL_SET && info->ttl == 0) | 112 | if (info->mode != IPT_TTL_SET && info->ttl == 0) |
113 | return -EINVAL; | 113 | return -EINVAL; |
diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c index 22b5b7057397..efcf56db23e8 100644 --- a/net/netfilter/xt_LED.c +++ b/net/netfilter/xt_LED.c | |||
@@ -93,7 +93,7 @@ static int led_tg_check(const struct xt_tgchk_param *par) | |||
93 | 93 | ||
94 | ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL); | 94 | ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL); |
95 | if (!ledinternal) | 95 | if (!ledinternal) |
96 | return -EINVAL; | 96 | return -ENOMEM; |
97 | 97 | ||
98 | ledinternal->netfilter_led_trigger.name = ledinfo->id; | 98 | ledinternal->netfilter_led_trigger.name = ledinfo->id; |
99 | 99 | ||
@@ -115,7 +115,7 @@ static int led_tg_check(const struct xt_tgchk_param *par) | |||
115 | 115 | ||
116 | exit_alloc: | 116 | exit_alloc: |
117 | kfree(ledinternal); | 117 | kfree(ledinternal); |
118 | return -EINVAL; | 118 | return err; |
119 | } | 119 | } |
120 | 120 | ||
121 | static void led_tg_destroy(const struct xt_tgdtor_param *par) | 121 | static void led_tg_destroy(const struct xt_tgdtor_param *par) |
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c index add1789ae4a8..f9217cb56fe3 100644 --- a/net/netfilter/xt_NFQUEUE.c +++ b/net/netfilter/xt_NFQUEUE.c | |||
@@ -98,7 +98,7 @@ static int nfqueue_tg_v1_check(const struct xt_tgchk_param *par) | |||
98 | if (maxid > 0xffff) { | 98 | if (maxid > 0xffff) { |
99 | pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n", | 99 | pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n", |
100 | info->queues_total, maxid); | 100 | info->queues_total, maxid); |
101 | return -EINVAL; | 101 | return -ERANGE; |
102 | } | 102 | } |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 7af5fba39cdd..40751c618e70 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c | |||
@@ -93,6 +93,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
93 | struct nlattr opt; | 93 | struct nlattr opt; |
94 | struct gnet_estimator est; | 94 | struct gnet_estimator est; |
95 | } cfg; | 95 | } cfg; |
96 | int ret; | ||
96 | 97 | ||
97 | if (unlikely(!rnd_inited)) { | 98 | if (unlikely(!rnd_inited)) { |
98 | get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); | 99 | get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); |
@@ -115,6 +116,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
117 | 118 | ||
119 | ret = -ENOMEM; | ||
118 | est = kzalloc(sizeof(*est), GFP_KERNEL); | 120 | est = kzalloc(sizeof(*est), GFP_KERNEL); |
119 | if (!est) | 121 | if (!est) |
120 | goto err1; | 122 | goto err1; |
@@ -130,8 +132,9 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
130 | cfg.est.interval = info->interval; | 132 | cfg.est.interval = info->interval; |
131 | cfg.est.ewma_log = info->ewma_log; | 133 | cfg.est.ewma_log = info->ewma_log; |
132 | 134 | ||
133 | if (gen_new_estimator(&est->bstats, &est->rstats, &est->lock, | 135 | ret = gen_new_estimator(&est->bstats, &est->rstats, |
134 | &cfg.opt) < 0) | 136 | &est->lock, &cfg.opt); |
137 | if (ret < 0) | ||
135 | goto err2; | 138 | goto err2; |
136 | 139 | ||
137 | info->est = est; | 140 | info->est = est; |
@@ -141,7 +144,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
141 | err2: | 144 | err2: |
142 | kfree(est); | 145 | kfree(est); |
143 | err1: | 146 | err1: |
144 | return -EINVAL; | 147 | return ret; |
145 | } | 148 | } |
146 | 149 | ||
147 | static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par) | 150 | static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par) |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 39098fc9887d..a91d4a7d5a2c 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -50,7 +50,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
50 | return XT_CONTINUE; | 50 | return XT_CONTINUE; |
51 | } | 51 | } |
52 | 52 | ||
53 | static bool checkentry_selinux(struct xt_secmark_target_info *info) | 53 | static int checkentry_selinux(struct xt_secmark_target_info *info) |
54 | { | 54 | { |
55 | int err; | 55 | int err; |
56 | struct xt_secmark_target_selinux_info *sel = &info->u.sel; | 56 | struct xt_secmark_target_selinux_info *sel = &info->u.sel; |
@@ -62,27 +62,28 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info) | |||
62 | if (err == -EINVAL) | 62 | if (err == -EINVAL) |
63 | pr_info("invalid SELinux context \'%s\'\n", | 63 | pr_info("invalid SELinux context \'%s\'\n", |
64 | sel->selctx); | 64 | sel->selctx); |
65 | return false; | 65 | return err; |
66 | } | 66 | } |
67 | 67 | ||
68 | if (!sel->selsid) { | 68 | if (!sel->selsid) { |
69 | pr_info("unable to map SELinux context \'%s\'\n", sel->selctx); | 69 | pr_info("unable to map SELinux context \'%s\'\n", sel->selctx); |
70 | return false; | 70 | return -ENOENT; |
71 | } | 71 | } |
72 | 72 | ||
73 | err = selinux_secmark_relabel_packet_permission(sel->selsid); | 73 | err = selinux_secmark_relabel_packet_permission(sel->selsid); |
74 | if (err) { | 74 | if (err) { |
75 | pr_info("unable to obtain relabeling permission\n"); | 75 | pr_info("unable to obtain relabeling permission\n"); |
76 | return false; | 76 | return err; |
77 | } | 77 | } |
78 | 78 | ||
79 | selinux_secmark_refcount_inc(); | 79 | selinux_secmark_refcount_inc(); |
80 | return true; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int secmark_tg_check(const struct xt_tgchk_param *par) | 83 | static int secmark_tg_check(const struct xt_tgchk_param *par) |
84 | { | 84 | { |
85 | struct xt_secmark_target_info *info = par->targinfo; | 85 | struct xt_secmark_target_info *info = par->targinfo; |
86 | int err; | ||
86 | 87 | ||
87 | if (strcmp(par->table, "mangle") != 0 && | 88 | if (strcmp(par->table, "mangle") != 0 && |
88 | strcmp(par->table, "security") != 0) { | 89 | strcmp(par->table, "security") != 0) { |
@@ -99,8 +100,9 @@ static int secmark_tg_check(const struct xt_tgchk_param *par) | |||
99 | 100 | ||
100 | switch (info->mode) { | 101 | switch (info->mode) { |
101 | case SECMARK_MODE_SEL: | 102 | case SECMARK_MODE_SEL: |
102 | if (!checkentry_selinux(info)) | 103 | err = checkentry_selinux(info); |
103 | return -EINVAL; | 104 | if (err <= 0) |
105 | return err; | ||
104 | break; | 106 | break; |
105 | 107 | ||
106 | default: | 108 | default: |
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c index 30cb7762fc41..6c941e1c6b9e 100644 --- a/net/netfilter/xt_cluster.c +++ b/net/netfilter/xt_cluster.c | |||
@@ -145,7 +145,7 @@ static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par) | |||
145 | if (info->node_mask >= (1ULL << info->total_nodes)) { | 145 | if (info->node_mask >= (1ULL << info->total_nodes)) { |
146 | pr_info("this node mask cannot be " | 146 | pr_info("this node mask cannot be " |
147 | "higher than the total number of nodes\n"); | 147 | "higher than the total number of nodes\n"); |
148 | return -EINVAL; | 148 | return -EDOM; |
149 | } | 149 | } |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index bf8e286361c3..2ff332ecc342 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c | |||
@@ -96,6 +96,7 @@ connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
96 | static int connbytes_mt_check(const struct xt_mtchk_param *par) | 96 | static int connbytes_mt_check(const struct xt_mtchk_param *par) |
97 | { | 97 | { |
98 | const struct xt_connbytes_info *sinfo = par->matchinfo; | 98 | const struct xt_connbytes_info *sinfo = par->matchinfo; |
99 | int ret; | ||
99 | 100 | ||
100 | if (sinfo->what != XT_CONNBYTES_PKTS && | 101 | if (sinfo->what != XT_CONNBYTES_PKTS && |
101 | sinfo->what != XT_CONNBYTES_BYTES && | 102 | sinfo->what != XT_CONNBYTES_BYTES && |
@@ -107,10 +108,11 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par) | |||
107 | sinfo->direction != XT_CONNBYTES_DIR_BOTH) | 108 | sinfo->direction != XT_CONNBYTES_DIR_BOTH) |
108 | return -EINVAL; | 109 | return -EINVAL; |
109 | 110 | ||
110 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 111 | ret = nf_ct_l3proto_try_module_get(par->family); |
112 | if (ret < 0) { | ||
111 | pr_info("cannot load conntrack support for proto=%u\n", | 113 | pr_info("cannot load conntrack support for proto=%u\n", |
112 | par->family); | 114 | par->family); |
113 | return -EINVAL; | 115 | return ret; |
114 | } | 116 | } |
115 | 117 | ||
116 | return 0; | 118 | return 0; |
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 68e89f08140b..370088ec5764 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
@@ -220,22 +220,24 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) | |||
220 | { | 220 | { |
221 | struct xt_connlimit_info *info = par->matchinfo; | 221 | struct xt_connlimit_info *info = par->matchinfo; |
222 | unsigned int i; | 222 | unsigned int i; |
223 | int ret; | ||
223 | 224 | ||
224 | if (unlikely(!connlimit_rnd_inited)) { | 225 | if (unlikely(!connlimit_rnd_inited)) { |
225 | get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); | 226 | get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); |
226 | connlimit_rnd_inited = true; | 227 | connlimit_rnd_inited = true; |
227 | } | 228 | } |
228 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 229 | ret = nf_ct_l3proto_try_module_get(par->family); |
230 | if (ret < 0) { | ||
229 | pr_info("cannot load conntrack support for " | 231 | pr_info("cannot load conntrack support for " |
230 | "address family %u\n", par->family); | 232 | "address family %u\n", par->family); |
231 | return -EINVAL; | 233 | return ret; |
232 | } | 234 | } |
233 | 235 | ||
234 | /* init private data */ | 236 | /* init private data */ |
235 | info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); | 237 | info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); |
236 | if (info->data == NULL) { | 238 | if (info->data == NULL) { |
237 | nf_ct_l3proto_module_put(par->family); | 239 | nf_ct_l3proto_module_put(par->family); |
238 | return -EINVAL; | 240 | return -ENOMEM; |
239 | } | 241 | } |
240 | 242 | ||
241 | spin_lock_init(&info->data->lock); | 243 | spin_lock_init(&info->data->lock); |
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index e137af5559e0..71e38a1fd656 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c | |||
@@ -76,10 +76,13 @@ connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
76 | 76 | ||
77 | static int connmark_tg_check(const struct xt_tgchk_param *par) | 77 | static int connmark_tg_check(const struct xt_tgchk_param *par) |
78 | { | 78 | { |
79 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 79 | int ret; |
80 | |||
81 | ret = nf_ct_l3proto_try_module_get(par->family); | ||
82 | if (ret < 0) { | ||
80 | pr_info("cannot load conntrack support for proto=%u\n", | 83 | pr_info("cannot load conntrack support for proto=%u\n", |
81 | par->family); | 84 | par->family); |
82 | return -EINVAL; | 85 | return ret; |
83 | } | 86 | } |
84 | return 0; | 87 | return 0; |
85 | } | 88 | } |
@@ -105,10 +108,13 @@ connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
105 | 108 | ||
106 | static int connmark_mt_check(const struct xt_mtchk_param *par) | 109 | static int connmark_mt_check(const struct xt_mtchk_param *par) |
107 | { | 110 | { |
108 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 111 | int ret; |
112 | |||
113 | ret = nf_ct_l3proto_try_module_get(par->family); | ||
114 | if (ret < 0) { | ||
109 | pr_info("cannot load conntrack support for proto=%u\n", | 115 | pr_info("cannot load conntrack support for proto=%u\n", |
110 | par->family); | 116 | par->family); |
111 | return -EINVAL; | 117 | return ret; |
112 | } | 118 | } |
113 | return 0; | 119 | return 0; |
114 | } | 120 | } |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 26e34aa7f8d1..e0bcf8d2cf33 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -208,10 +208,13 @@ conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par) | |||
208 | 208 | ||
209 | static int conntrack_mt_check(const struct xt_mtchk_param *par) | 209 | static int conntrack_mt_check(const struct xt_mtchk_param *par) |
210 | { | 210 | { |
211 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 211 | int ret; |
212 | |||
213 | ret = nf_ct_l3proto_try_module_get(par->family); | ||
214 | if (ret < 0) { | ||
212 | pr_info("cannot load conntrack support for proto=%u\n", | 215 | pr_info("cannot load conntrack support for proto=%u\n", |
213 | par->family); | 216 | par->family); |
214 | return -EINVAL; | 217 | return ret; |
215 | } | 218 | } |
216 | return 0; | 219 | return 0; |
217 | } | 220 | } |
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c index f355fb9e06fa..9db51fddbdb8 100644 --- a/net/netfilter/xt_dscp.c +++ b/net/netfilter/xt_dscp.c | |||
@@ -48,7 +48,7 @@ static int dscp_mt_check(const struct xt_mtchk_param *par) | |||
48 | 48 | ||
49 | if (info->dscp > XT_DSCP_MAX) { | 49 | if (info->dscp > XT_DSCP_MAX) { |
50 | pr_info("dscp %x out of range\n", info->dscp); | 50 | pr_info("dscp %x out of range\n", info->dscp); |
51 | return -EINVAL; | 51 | return -EDOM; |
52 | } | 52 | } |
53 | 53 | ||
54 | return 0; | 54 | return 0; |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 0c0152902b3b..c89fde7d1234 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -214,7 +214,7 @@ static int htable_create_v0(struct net *net, struct xt_hashlimit_info *minfo, u_ | |||
214 | hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + | 214 | hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + |
215 | sizeof(struct list_head) * size); | 215 | sizeof(struct list_head) * size); |
216 | if (!hinfo) | 216 | if (!hinfo) |
217 | return -1; | 217 | return -ENOMEM; |
218 | minfo->hinfo = hinfo; | 218 | minfo->hinfo = hinfo; |
219 | 219 | ||
220 | /* copy match config into hashtable config */ | 220 | /* copy match config into hashtable config */ |
@@ -250,7 +250,7 @@ static int htable_create_v0(struct net *net, struct xt_hashlimit_info *minfo, u_ | |||
250 | &dl_file_ops, hinfo); | 250 | &dl_file_ops, hinfo); |
251 | if (!hinfo->pde) { | 251 | if (!hinfo->pde) { |
252 | vfree(hinfo); | 252 | vfree(hinfo); |
253 | return -1; | 253 | return -ENOMEM; |
254 | } | 254 | } |
255 | hinfo->net = net; | 255 | hinfo->net = net; |
256 | 256 | ||
@@ -285,7 +285,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, | |||
285 | hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + | 285 | hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + |
286 | sizeof(struct list_head) * size); | 286 | sizeof(struct list_head) * size); |
287 | if (hinfo == NULL) | 287 | if (hinfo == NULL) |
288 | return -1; | 288 | return -ENOMEM; |
289 | minfo->hinfo = hinfo; | 289 | minfo->hinfo = hinfo; |
290 | 290 | ||
291 | /* copy match config into hashtable config */ | 291 | /* copy match config into hashtable config */ |
@@ -311,7 +311,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo, | |||
311 | &dl_file_ops, hinfo); | 311 | &dl_file_ops, hinfo); |
312 | if (hinfo->pde == NULL) { | 312 | if (hinfo->pde == NULL) { |
313 | vfree(hinfo); | 313 | vfree(hinfo); |
314 | return -1; | 314 | return -ENOMEM; |
315 | } | 315 | } |
316 | hinfo->net = net; | 316 | hinfo->net = net; |
317 | 317 | ||
@@ -675,13 +675,14 @@ static int hashlimit_mt_check_v0(const struct xt_mtchk_param *par) | |||
675 | { | 675 | { |
676 | struct net *net = par->net; | 676 | struct net *net = par->net; |
677 | struct xt_hashlimit_info *r = par->matchinfo; | 677 | struct xt_hashlimit_info *r = par->matchinfo; |
678 | int ret; | ||
678 | 679 | ||
679 | /* Check for overflow. */ | 680 | /* Check for overflow. */ |
680 | if (r->cfg.burst == 0 || | 681 | if (r->cfg.burst == 0 || |
681 | user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) { | 682 | user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) { |
682 | pr_info("overflow, try lower: %u/%u\n", | 683 | pr_info("overflow, try lower: %u/%u\n", |
683 | r->cfg.avg, r->cfg.burst); | 684 | r->cfg.avg, r->cfg.burst); |
684 | return -EINVAL; | 685 | return -ERANGE; |
685 | } | 686 | } |
686 | if (r->cfg.mode == 0 || | 687 | if (r->cfg.mode == 0 || |
687 | r->cfg.mode > (XT_HASHLIMIT_HASH_DPT | | 688 | r->cfg.mode > (XT_HASHLIMIT_HASH_DPT | |
@@ -698,9 +699,12 @@ static int hashlimit_mt_check_v0(const struct xt_mtchk_param *par) | |||
698 | 699 | ||
699 | mutex_lock(&hashlimit_mutex); | 700 | mutex_lock(&hashlimit_mutex); |
700 | r->hinfo = htable_find_get(net, r->name, par->family); | 701 | r->hinfo = htable_find_get(net, r->name, par->family); |
701 | if (!r->hinfo && htable_create_v0(net, r, par->family) != 0) { | 702 | if (r->hinfo == NULL) { |
702 | mutex_unlock(&hashlimit_mutex); | 703 | ret = htable_create_v0(net, r, par->family); |
703 | return -EINVAL; | 704 | if (ret < 0) { |
705 | mutex_unlock(&hashlimit_mutex); | ||
706 | return ret; | ||
707 | } | ||
704 | } | 708 | } |
705 | mutex_unlock(&hashlimit_mutex); | 709 | mutex_unlock(&hashlimit_mutex); |
706 | return 0; | 710 | return 0; |
@@ -710,6 +714,7 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) | |||
710 | { | 714 | { |
711 | struct net *net = par->net; | 715 | struct net *net = par->net; |
712 | struct xt_hashlimit_mtinfo1 *info = par->matchinfo; | 716 | struct xt_hashlimit_mtinfo1 *info = par->matchinfo; |
717 | int ret; | ||
713 | 718 | ||
714 | /* Check for overflow. */ | 719 | /* Check for overflow. */ |
715 | if (info->cfg.burst == 0 || | 720 | if (info->cfg.burst == 0 || |
@@ -717,7 +722,7 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) | |||
717 | user2credits(info->cfg.avg)) { | 722 | user2credits(info->cfg.avg)) { |
718 | pr_info("overflow, try lower: %u/%u\n", | 723 | pr_info("overflow, try lower: %u/%u\n", |
719 | info->cfg.avg, info->cfg.burst); | 724 | info->cfg.avg, info->cfg.burst); |
720 | return -EINVAL; | 725 | return -ERANGE; |
721 | } | 726 | } |
722 | if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) | 727 | if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) |
723 | return -EINVAL; | 728 | return -EINVAL; |
@@ -733,9 +738,12 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) | |||
733 | 738 | ||
734 | mutex_lock(&hashlimit_mutex); | 739 | mutex_lock(&hashlimit_mutex); |
735 | info->hinfo = htable_find_get(net, info->name, par->family); | 740 | info->hinfo = htable_find_get(net, info->name, par->family); |
736 | if (!info->hinfo && htable_create(net, info, par->family) != 0) { | 741 | if (info->hinfo == NULL) { |
737 | mutex_unlock(&hashlimit_mutex); | 742 | ret = htable_create(net, info, par->family); |
738 | return -EINVAL; | 743 | if (ret < 0) { |
744 | mutex_unlock(&hashlimit_mutex); | ||
745 | return ret; | ||
746 | } | ||
739 | } | 747 | } |
740 | mutex_unlock(&hashlimit_mutex); | 748 | mutex_unlock(&hashlimit_mutex); |
741 | return 0; | 749 | return 0; |
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index eb308b32bfe0..b8b3e13dc71e 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c | |||
@@ -57,11 +57,13 @@ helper_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
57 | static int helper_mt_check(const struct xt_mtchk_param *par) | 57 | static int helper_mt_check(const struct xt_mtchk_param *par) |
58 | { | 58 | { |
59 | struct xt_helper_info *info = par->matchinfo; | 59 | struct xt_helper_info *info = par->matchinfo; |
60 | int ret; | ||
60 | 61 | ||
61 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 62 | ret = nf_ct_l3proto_try_module_get(par->family); |
63 | if (ret < 0) { | ||
62 | pr_info("cannot load conntrack support for proto=%u\n", | 64 | pr_info("cannot load conntrack support for proto=%u\n", |
63 | par->family); | 65 | par->family); |
64 | return -EINVAL; | 66 | return ret; |
65 | } | 67 | } |
66 | info->name[29] = '\0'; | 68 | info->name[29] = '\0'; |
67 | return 0; | 69 | return 0; |
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 5ff0580ce878..e2a284ebb415 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c | |||
@@ -107,12 +107,12 @@ static int limit_mt_check(const struct xt_mtchk_param *par) | |||
107 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { | 107 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { |
108 | pr_info("Overflow, try lower: %u/%u\n", | 108 | pr_info("Overflow, try lower: %u/%u\n", |
109 | r->avg, r->burst); | 109 | r->avg, r->burst); |
110 | return -EINVAL; | 110 | return -ERANGE; |
111 | } | 111 | } |
112 | 112 | ||
113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
114 | if (priv == NULL) | 114 | if (priv == NULL) |
115 | return -EINVAL; | 115 | return -ENOMEM; |
116 | 116 | ||
117 | /* For SMP, we only want to use one set of state. */ | 117 | /* For SMP, we only want to use one set of state. */ |
118 | r->master = priv; | 118 | r->master = priv; |
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c index 766e71c6dc55..3e5cbd85a65b 100644 --- a/net/netfilter/xt_quota.c +++ b/net/netfilter/xt_quota.c | |||
@@ -52,7 +52,7 @@ static int quota_mt_check(const struct xt_mtchk_param *par) | |||
52 | 52 | ||
53 | q->master = kmalloc(sizeof(*q->master), GFP_KERNEL); | 53 | q->master = kmalloc(sizeof(*q->master), GFP_KERNEL); |
54 | if (q->master == NULL) | 54 | if (q->master == NULL) |
55 | return -EINVAL; | 55 | return -ENOMEM; |
56 | 56 | ||
57 | q->master->quota = q->quota; | 57 | q->master->quota = q->quota; |
58 | return 0; | 58 | return 0; |
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c index 0b5c6122737d..23805f8a444b 100644 --- a/net/netfilter/xt_rateest.c +++ b/net/netfilter/xt_rateest.c | |||
@@ -78,6 +78,7 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) | |||
78 | { | 78 | { |
79 | struct xt_rateest_match_info *info = par->matchinfo; | 79 | struct xt_rateest_match_info *info = par->matchinfo; |
80 | struct xt_rateest *est1, *est2; | 80 | struct xt_rateest *est1, *est2; |
81 | int ret = false; | ||
81 | 82 | ||
82 | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | | 83 | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | |
83 | XT_RATEEST_MATCH_REL)) != 1) | 84 | XT_RATEEST_MATCH_REL)) != 1) |
@@ -95,6 +96,7 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) | |||
95 | goto err1; | 96 | goto err1; |
96 | } | 97 | } |
97 | 98 | ||
99 | ret = -ENOENT; | ||
98 | est1 = xt_rateest_lookup(info->name1); | 100 | est1 = xt_rateest_lookup(info->name1); |
99 | if (!est1) | 101 | if (!est1) |
100 | goto err1; | 102 | goto err1; |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 0994ff54a731..0d9f80b1dd9f 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -355,8 +355,10 @@ static int recent_mt_check(const struct xt_mtchk_param *par) | |||
355 | 355 | ||
356 | t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, | 356 | t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, |
357 | GFP_KERNEL); | 357 | GFP_KERNEL); |
358 | if (t == NULL) | 358 | if (t == NULL) { |
359 | ret = -ENOMEM; | ||
359 | goto out; | 360 | goto out; |
361 | } | ||
360 | t->refcnt = 1; | 362 | t->refcnt = 1; |
361 | strcpy(t->name, info->name); | 363 | strcpy(t->name, info->name); |
362 | INIT_LIST_HEAD(&t->lru_list); | 364 | INIT_LIST_HEAD(&t->lru_list); |
@@ -367,6 +369,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par) | |||
367 | &recent_mt_fops, t); | 369 | &recent_mt_fops, t); |
368 | if (pde == NULL) { | 370 | if (pde == NULL) { |
369 | kfree(t); | 371 | kfree(t); |
372 | ret = -ENOMEM; | ||
370 | goto out; | 373 | goto out; |
371 | } | 374 | } |
372 | pde->uid = ip_list_uid; | 375 | pde->uid = ip_list_uid; |
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index 8e8c9df51784..2b75230d15ca 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c | |||
@@ -39,10 +39,13 @@ state_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
39 | 39 | ||
40 | static int state_mt_check(const struct xt_mtchk_param *par) | 40 | static int state_mt_check(const struct xt_mtchk_param *par) |
41 | { | 41 | { |
42 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 42 | int ret; |
43 | |||
44 | ret = nf_ct_l3proto_try_module_get(par->family); | ||
45 | if (ret < 0) { | ||
43 | pr_info("cannot load conntrack support for proto=%u\n", | 46 | pr_info("cannot load conntrack support for proto=%u\n", |
44 | par->family); | 47 | par->family); |
45 | return -EINVAL; | 48 | return ret; |
46 | } | 49 | } |
47 | return 0; | 50 | return 0; |
48 | } | 51 | } |
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index 29d76f8f1880..8ed2b2905091 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c | |||
@@ -62,7 +62,7 @@ static int statistic_mt_check(const struct xt_mtchk_param *par) | |||
62 | 62 | ||
63 | info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); | 63 | info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); |
64 | if (info->master == NULL) | 64 | if (info->master == NULL) |
65 | return -EINVAL; | 65 | return -ENOMEM; |
66 | info->master->count = info->u.nth.count; | 66 | info->master->count = info->u.nth.count; |
67 | 67 | ||
68 | return 0; | 68 | return 0; |
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index e1f22a7a4152..b0f8292db6f8 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c | |||
@@ -63,7 +63,7 @@ static int string_mt_check(const struct xt_mtchk_param *par) | |||
63 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, | 63 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, |
64 | GFP_KERNEL, flags); | 64 | GFP_KERNEL, flags); |
65 | if (IS_ERR(ts_conf)) | 65 | if (IS_ERR(ts_conf)) |
66 | return -EINVAL; | 66 | return PTR_ERR(ts_conf); |
67 | 67 | ||
68 | conf->config = ts_conf; | 68 | conf->config = ts_conf; |
69 | return 0; | 69 | return 0; |
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index 8dde5e51ff19..d8556fdda440 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c | |||
@@ -225,7 +225,7 @@ static int time_mt_check(const struct xt_mtchk_param *par) | |||
225 | info->daytime_stop > XT_TIME_MAX_DAYTIME) { | 225 | info->daytime_stop > XT_TIME_MAX_DAYTIME) { |
226 | pr_info("invalid argument - start or " | 226 | pr_info("invalid argument - start or " |
227 | "stop time greater than 23:59:59\n"); | 227 | "stop time greater than 23:59:59\n"); |
228 | return -EINVAL; | 228 | return -EDOM; |
229 | } | 229 | } |
230 | 230 | ||
231 | return 0; | 231 | return 0; |