diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2011-01-06 14:25:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-06 14:25:00 -0500 |
commit | cba85b532e4aabdb97f44c18987d45141fd93faa (patch) | |
tree | 785e2a715a922c36b15e1929473498e3b3aae724 /net | |
parent | f682cefa5ad204d3bfaa54a58046c66d2d035ac1 (diff) |
netfilter: fix export secctx error handling
In 1ae4de0cdf855305765592647025bde55e85e451, the secctx was exported
via the /proc/net/netfilter/nf_conntrack and ctnetlink interfaces
instead of the secmark.
That patch introduced the use of security_secid_to_secctx() which may
return a non-zero value on error.
In one of my setups, I have NF_CONNTRACK_SECMARK enabled but no
security modules. Thus, security_secid_to_secctx() returns a negative
value that results in the breakage of the /proc and `conntrack -L'
outputs. To fix this, we skip the inclusion of secctx if the
aforementioned function fails.
This patch also fixes the dynamic netlink message size calculation
if security_secid_to_secctx() returns an error, since its logic is
also wrong.
This problem exists in Linux kernel >= 2.6.37.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 25 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 2 |
3 files changed, 16 insertions, 13 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 37f8adb68c79..63f60fc5d26a 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -97,7 +97,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) | |||
97 | 97 | ||
98 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); | 98 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); |
99 | if (ret) | 99 | if (ret) |
100 | return ret; | 100 | return 0; |
101 | 101 | ||
102 | ret = seq_printf(s, "secctx=%s ", secctx); | 102 | ret = seq_printf(s, "secctx=%s ", secctx); |
103 | 103 | ||
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b729ace1dcc1..0cdba50c0d69 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -254,7 +254,7 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) | |||
254 | 254 | ||
255 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); | 255 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); |
256 | if (ret) | 256 | if (ret) |
257 | return ret; | 257 | return 0; |
258 | 258 | ||
259 | ret = -1; | 259 | ret = -1; |
260 | nest_secctx = nla_nest_start(skb, CTA_SECCTX | NLA_F_NESTED); | 260 | nest_secctx = nla_nest_start(skb, CTA_SECCTX | NLA_F_NESTED); |
@@ -453,16 +453,22 @@ ctnetlink_counters_size(const struct nf_conn *ct) | |||
453 | ; | 453 | ; |
454 | } | 454 | } |
455 | 455 | ||
456 | #ifdef CONFIG_NF_CONNTRACK_SECMARK | 456 | static inline int |
457 | static int ctnetlink_nlmsg_secctx_size(const struct nf_conn *ct) | 457 | ctnetlink_secctx_size(const struct nf_conn *ct) |
458 | { | 458 | { |
459 | int len; | 459 | #ifdef CONFIG_NF_CONNTRACK_SECMARK |
460 | int len, ret; | ||
460 | 461 | ||
461 | security_secid_to_secctx(ct->secmark, NULL, &len); | 462 | ret = security_secid_to_secctx(ct->secmark, NULL, &len); |
463 | if (ret) | ||
464 | return 0; | ||
462 | 465 | ||
463 | return sizeof(char) * len; | 466 | return nla_total_size(0) /* CTA_SECCTX */ |
464 | } | 467 | + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ |
468 | #else | ||
469 | return 0; | ||
465 | #endif | 470 | #endif |
471 | } | ||
466 | 472 | ||
467 | static inline size_t | 473 | static inline size_t |
468 | ctnetlink_nlmsg_size(const struct nf_conn *ct) | 474 | ctnetlink_nlmsg_size(const struct nf_conn *ct) |
@@ -479,10 +485,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct) | |||
479 | + nla_total_size(0) /* CTA_PROTOINFO */ | 485 | + nla_total_size(0) /* CTA_PROTOINFO */ |
480 | + nla_total_size(0) /* CTA_HELP */ | 486 | + nla_total_size(0) /* CTA_HELP */ |
481 | + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */ | 487 | + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */ |
482 | #ifdef CONFIG_NF_CONNTRACK_SECMARK | 488 | + ctnetlink_secctx_size(ct) |
483 | + nla_total_size(0) /* CTA_SECCTX */ | ||
484 | + nla_total_size(ctnetlink_nlmsg_secctx_size(ct)) /* CTA_SECCTX_NAME */ | ||
485 | #endif | ||
486 | #ifdef CONFIG_NF_NAT_NEEDED | 489 | #ifdef CONFIG_NF_NAT_NEEDED |
487 | + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */ | 490 | + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */ |
488 | + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */ | 491 | + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */ |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 0fb65705b44b..b4d7f0f24b27 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -118,7 +118,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) | |||
118 | 118 | ||
119 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); | 119 | ret = security_secid_to_secctx(ct->secmark, &secctx, &len); |
120 | if (ret) | 120 | if (ret) |
121 | return ret; | 121 | return 0; |
122 | 122 | ||
123 | ret = seq_printf(s, "secctx=%s ", secctx); | 123 | ret = seq_printf(s, "secctx=%s ", secctx); |
124 | 124 | ||