aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2010-03-19 12:32:59 -0400
committerJan Engelhardt <jengelh@medozas.de>2010-03-25 11:56:09 -0400
commit4a5a5c73b7cfee46a0b1411903cfa0dea532deec (patch)
tree3f7ef0def4adf3a01e15ab3a2a7231967b87bfee /net/netfilter
parentd6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddc (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.c8
-rw-r--r--net/netfilter/xt_CT.c11
-rw-r--r--net/netfilter/xt_DSCP.c2
-rw-r--r--net/netfilter/xt_HL.c2
-rw-r--r--net/netfilter/xt_LED.c4
-rw-r--r--net/netfilter/xt_NFQUEUE.c2
-rw-r--r--net/netfilter/xt_RATEEST.c9
-rw-r--r--net/netfilter/xt_SECMARK.c16
-rw-r--r--net/netfilter/xt_cluster.c2
-rw-r--r--net/netfilter/xt_connbytes.c6
-rw-r--r--net/netfilter/xt_connlimit.c8
-rw-r--r--net/netfilter/xt_connmark.c14
-rw-r--r--net/netfilter/xt_conntrack.c7
-rw-r--r--net/netfilter/xt_dscp.c2
-rw-r--r--net/netfilter/xt_hashlimit.c32
-rw-r--r--net/netfilter/xt_helper.c6
-rw-r--r--net/netfilter/xt_limit.c4
-rw-r--r--net/netfilter/xt_quota.c2
-rw-r--r--net/netfilter/xt_rateest.c2
-rw-r--r--net/netfilter/xt_recent.c5
-rw-r--r--net/netfilter/xt_state.c7
-rw-r--r--net/netfilter/xt_statistic.c2
-rw-r--r--net/netfilter/xt_string.c2
-rw-r--r--net/netfilter/xt_time.c2
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)
87static int connsecmark_tg_check(const struct xt_tgchk_param *par) 87static 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:
115err2: 122err2:
116 nf_ct_l3proto_module_put(par->family); 123 nf_ct_l3proto_module_put(par->family);
117err1: 124err1:
118 return -EINVAL; 125 return ret;
119} 126}
120 127
121static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par) 128static 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
116exit_alloc: 116exit_alloc:
117 kfree(ledinternal); 117 kfree(ledinternal);
118 return -EINVAL; 118 return err;
119} 119}
120 120
121static void led_tg_destroy(const struct xt_tgdtor_param *par) 121static 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)
141err2: 144err2:
142 kfree(est); 145 kfree(est);
143err1: 146err1:
144 return -EINVAL; 147 return ret;
145} 148}
146 149
147static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par) 150static 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
53static bool checkentry_selinux(struct xt_secmark_target_info *info) 53static 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
83static int secmark_tg_check(const struct xt_tgchk_param *par) 83static 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)
96static int connbytes_mt_check(const struct xt_mtchk_param *par) 96static 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
77static int connmark_tg_check(const struct xt_tgchk_param *par) 77static 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
106static int connmark_mt_check(const struct xt_mtchk_param *par) 109static 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
209static int conntrack_mt_check(const struct xt_mtchk_param *par) 209static 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)
57static int helper_mt_check(const struct xt_mtchk_param *par) 57static 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
40static int state_mt_check(const struct xt_mtchk_param *par) 40static 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;