* [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions @ 2017-04-15 23:29 Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 1/6] netfilter: conntrack: move helper struct to nf_conntrack_helper.h Florian Westphal ` (6 more replies) 0 siblings, 7 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel 3 years ago we had to bump the offsets to the extensions (223b02d923ecd7c84cf9780bb3686f455d279279, "netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len") because total size of all extensions had increased to a point where u8 did overflow. We already dieted the extensions back to more reasonable sizes, however, I never wanted to switch back because overflow produces hard to diagnose crash bugs, and we could not add compile-time assert because extensions can be dynamically sized. This series makes the last veriable-sized extension (helper) fixed in size by adding a 32byte scratch area for helpers to use and then adds the compile-time asserts to catch overflow during build time. include/net/netfilter/nf_conntrack.h | 19 ---------------- include/net/netfilter/nf_conntrack_extend.h | 12 ++-------- include/net/netfilter/nf_conntrack_helper.h | 31 ++++++++++++++++++++++---- net/netfilter/nf_conntrack_amanda.c | 2 + net/netfilter/nf_conntrack_core.c | 33 ++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_extend.c | 16 +++++-------- net/netfilter/nf_conntrack_ftp.c | 8 +++--- net/netfilter/nf_conntrack_h323_main.c | 6 +---- net/netfilter/nf_conntrack_helper.c | 6 +---- net/netfilter/nf_conntrack_irc.c | 2 - net/netfilter/nf_conntrack_netbios_ns.c | 2 + net/netfilter/nf_conntrack_pptp.c | 3 +- net/netfilter/nf_conntrack_sane.c | 8 +++--- net/netfilter/nf_conntrack_sip.c | 14 +++++------ net/netfilter/nf_conntrack_tftp.c | 6 +++-- net/netfilter/nfnetlink_cthelper.c | 10 ++++++-- 16 files changed, 106 insertions(+), 72 deletions(-) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH nf-next 1/6] netfilter: conntrack: move helper struct to nf_conntrack_helper.h 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 2/6] netfilter: helper: add build-time asserts for helper data size Florian Westphal ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal its definition is not needed in nf_conntrack.h. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_conntrack.h | 19 ------------------- include/net/netfilter/nf_conntrack_helper.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 4978a82b75fa..8ece3612d0cd 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -50,25 +50,6 @@ union nf_conntrack_expect_proto { #define NF_CT_ASSERT(x) #endif -struct nf_conntrack_helper; - -/* Must be kept in sync with the classes defined by helpers */ -#define NF_CT_MAX_EXPECT_CLASSES 4 - -/* nf_conn feature for connections that have a helper */ -struct nf_conn_help { - /* Helper. if any */ - struct nf_conntrack_helper __rcu *helper; - - struct hlist_head expectations; - - /* Current number of expected connections */ - u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; - - /* private helper information. */ - char data[]; -}; - #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 1eaac1f4cd6a..15d746558665 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -52,6 +52,23 @@ struct nf_conntrack_helper { unsigned int queue_num; /* For user-space helpers. */ }; +/* Must be kept in sync with the classes defined by helpers */ +#define NF_CT_MAX_EXPECT_CLASSES 4 + +/* nf_conn feature for connections that have a helper */ +struct nf_conn_help { + /* Helper. if any */ + struct nf_conntrack_helper __rcu *helper; + + struct hlist_head expectations; + + /* Current number of expected connections */ + u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; + + /* private helper information. */ + char data[]; +}; + struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum); -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH nf-next 2/6] netfilter: helper: add build-time asserts for helper data size 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 1/6] netfilter: conntrack: move helper struct to nf_conntrack_helper.h Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 3/6] netfilter: nfnetlink_cthelper: reject too large userspace allocation requests Florian Westphal ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal add a 32 byte scratch area in the helper struct instead of relying on variable sized helpers plus compile-time asserts to let us know if 32 bytes aren't enough anymore. Not having variable sized helpers will later allow to add BUILD_BUG_ON for the total size of conntrack extensions -- the helper extension is the only one that doesn't have a fixed size. The (useless!) NF_CT_HELPER_BUILD_BUG_ON(0); are added so that in case someone adds a new helper and copy-pastes from one that doesn't store private data at least some indication that this macro should be used somehow is there... Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_conntrack_helper.h | 5 ++++- net/netfilter/nf_conntrack_amanda.c | 2 ++ net/netfilter/nf_conntrack_ftp.c | 2 ++ net/netfilter/nf_conntrack_h323_main.c | 2 ++ net/netfilter/nf_conntrack_netbios_ns.c | 2 ++ net/netfilter/nf_conntrack_pptp.c | 2 ++ net/netfilter/nf_conntrack_sane.c | 2 ++ net/netfilter/nf_conntrack_sip.c | 2 ++ net/netfilter/nf_conntrack_tftp.c | 2 ++ 9 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 15d746558665..29539ed1008f 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -66,9 +66,12 @@ struct nf_conn_help { u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; /* private helper information. */ - char data[]; + char data[32] __aligned(8); }; +#define NF_CT_HELPER_BUILD_BUG_ON(structsize) \ + BUILD_BUG_ON((structsize) > FIELD_SIZEOF(struct nf_conn_help, data)) + struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum); diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index 57a26cc90c9f..03d2ccffa9fa 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c @@ -207,6 +207,8 @@ static int __init nf_conntrack_amanda_init(void) { int ret, i; + NF_CT_HELPER_BUILD_BUG_ON(0); + for (i = 0; i < ARRAY_SIZE(search); i++) { search[i].ts = textsearch_prepare(ts_algo, search[i].string, search[i].len, diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 4aecef4a89fb..58e1256cd05d 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -577,6 +577,8 @@ static int __init nf_conntrack_ftp_init(void) { int i, ret = 0; + NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master)); + ftp_buffer = kmalloc(65536, GFP_KERNEL); if (!ftp_buffer) return -ENOMEM; diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index f65d93639d12..e98204349efe 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -1836,6 +1836,8 @@ static int __init nf_conntrack_h323_init(void) { int ret; + NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_h323_master)); + h323_buffer = kmalloc(65536, GFP_KERNEL); if (!h323_buffer) return -ENOMEM; diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c index 4c8f30a3d6d2..496ce173f0c1 100644 --- a/net/netfilter/nf_conntrack_netbios_ns.c +++ b/net/netfilter/nf_conntrack_netbios_ns.c @@ -58,6 +58,8 @@ static struct nf_conntrack_helper helper __read_mostly = { static int __init nf_conntrack_netbios_ns_init(void) { + NF_CT_HELPER_BUILD_BUG_ON(0); + exp_policy.timeout = timeout; return nf_conntrack_helper_register(&helper); } diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index f60a4755d71e..34fac4c52c4c 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -607,6 +607,8 @@ static struct nf_conntrack_helper pptp __read_mostly = { static int __init nf_conntrack_pptp_init(void) { + NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_pptp_master)); + return nf_conntrack_helper_register(&pptp); } diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index 9dcb9ee9b97d..1121db08d048 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c @@ -184,6 +184,8 @@ static int __init nf_conntrack_sane_init(void) { int i, ret = 0; + NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master)); + sane_buffer = kmalloc(65536, GFP_KERNEL); if (!sane_buffer) return -ENOMEM; diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 91a9c97b7e9a..79bbcc4d52ee 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -1622,6 +1622,8 @@ static int __init nf_conntrack_sip_init(void) { int i, ret; + NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sip_master)); + if (ports_c == 0) ports[ports_c++] = SIP_PORT; diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index b1227dc6f75e..27e2f6f904dc 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c @@ -113,6 +113,8 @@ static int __init nf_conntrack_tftp_init(void) { int i, ret; + NF_CT_HELPER_BUILD_BUG_ON(0); + if (ports_c == 0) ports[ports_c++] = TFTP_PORT; -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH nf-next 3/6] netfilter: nfnetlink_cthelper: reject too large userspace allocation requests 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 1/6] netfilter: conntrack: move helper struct to nf_conntrack_helper.h Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 2/6] netfilter: helper: add build-time asserts for helper data size Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 4/6] netfilter: helpers: remove data_len usage for inkernel helpers Florian Westphal ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal Userspace should not abuse the kernel to store large amounts of data, reject requests larger than the private area can accommodate. Signed-off-by: Florian Westphal <fw@strlen.de> --- net/netfilter/nfnetlink_cthelper.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 9a50bf93dd16..eef7120e1f74 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -104,7 +104,7 @@ nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) if (help->helper->data_len == 0) return -EINVAL; - memcpy(help->data, nla_data(attr), help->helper->data_len); + nla_memcpy(help->data, nla_data(attr), sizeof(help->data)); return 0; } @@ -216,6 +216,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[], { struct nf_conntrack_helper *helper; struct nfnl_cthelper *nfcth; + unsigned int size; int ret; if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN]) @@ -231,7 +232,12 @@ nfnl_cthelper_create(const struct nlattr * const tb[], goto err1; strncpy(helper->name, nla_data(tb[NFCTH_NAME]), NF_CT_HELPER_NAME_LEN); - helper->data_len = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); + size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); + if (size > FIELD_SIZEOF(struct nf_conn_help, data)) { + ret = -ENOMEM; + goto err2; + } + helper->flags |= NF_CT_HELPER_F_USERSPACE; memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple)); -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH nf-next 4/6] netfilter: helpers: remove data_len usage for inkernel helpers 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal ` (2 preceding siblings ...) 2017-04-15 23:29 ` [PATCH nf-next 3/6] netfilter: nfnetlink_cthelper: reject too large userspace allocation requests Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 5/6] netfilter: remove last traces of variable-sized extensions Florian Westphal ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal No need to track this for inkernel helpers anymore as NF_CT_HELPER_BUILD_BUG_ON checks do this now. All inkernel helpers know what kind of structure they stored in helper->data. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_conntrack_helper.h | 11 ++++++----- net/netfilter/nf_conntrack_ftp.c | 6 ++---- net/netfilter/nf_conntrack_h323_main.c | 4 ---- net/netfilter/nf_conntrack_helper.c | 6 ++---- net/netfilter/nf_conntrack_irc.c | 2 +- net/netfilter/nf_conntrack_pptp.c | 1 - net/netfilter/nf_conntrack_sane.c | 6 ++---- net/netfilter/nf_conntrack_sip.c | 12 ++++-------- net/netfilter/nf_conntrack_tftp.c | 4 ++-- 9 files changed, 19 insertions(+), 33 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 29539ed1008f..e04fa7691e5d 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -29,9 +29,6 @@ struct nf_conntrack_helper { struct module *me; /* pointer to self */ const struct nf_conntrack_expect_policy *expect_policy; - /* length of internal data, ie. sizeof(struct nf_ct_*_master) */ - size_t data_len; - /* Tuple of things we will help (compared against server response) */ struct nf_conntrack_tuple tuple; @@ -49,7 +46,11 @@ struct nf_conntrack_helper { unsigned int expect_class_max; unsigned int flags; - unsigned int queue_num; /* For user-space helpers. */ + + /* For user-space helpers: */ + unsigned int queue_num; + /* length of userspace private data stored in nf_conn_help->data */ + u16 data_len; }; /* Must be kept in sync with the classes defined by helpers */ @@ -82,7 +83,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, u16 l3num, u16 protonum, const char *name, u16 default_port, u16 spec_port, u32 id, const struct nf_conntrack_expect_policy *exp_pol, - u32 expect_class_max, u32 data_len, + u32 expect_class_max, int (*help)(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo), diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 58e1256cd05d..f0e9a7511e1a 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -591,12 +591,10 @@ static int __init nf_conntrack_ftp_init(void) for (i = 0; i < ports_c; i++) { nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP, "ftp", FTP_PORT, ports[i], ports[i], &ftp_exp_policy, - 0, sizeof(struct nf_ct_ftp_master), help, - nf_ct_ftp_from_nlattr, THIS_MODULE); + 0, help, nf_ct_ftp_from_nlattr, THIS_MODULE); nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP, "ftp", FTP_PORT, ports[i], ports[i], &ftp_exp_policy, - 0, sizeof(struct nf_ct_ftp_master), help, - nf_ct_ftp_from_nlattr, THIS_MODULE); + 0, help, nf_ct_ftp_from_nlattr, THIS_MODULE); } ret = nf_conntrack_helpers_register(ftp, ports_c * 2); diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index e98204349efe..3bcdc718484e 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -637,7 +637,6 @@ static const struct nf_conntrack_expect_policy h245_exp_policy = { static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { .name = "H.245", .me = THIS_MODULE, - .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_UNSPEC, .tuple.dst.protonum = IPPROTO_UDP, .help = h245_help, @@ -1215,7 +1214,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { { .name = "Q.931", .me = THIS_MODULE, - .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET, .tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), .tuple.dst.protonum = IPPROTO_TCP, @@ -1800,7 +1798,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { { .name = "RAS", .me = THIS_MODULE, - .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET, .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), .tuple.dst.protonum = IPPROTO_UDP, @@ -1810,7 +1807,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { { .name = "RAS", .me = THIS_MODULE, - .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET6, .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), .tuple.dst.protonum = IPPROTO_UDP, diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 33ebb78649f8..8239b4406f56 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -178,8 +178,7 @@ nf_ct_helper_ext_add(struct nf_conn *ct, { struct nf_conn_help *help; - help = nf_ct_ext_add_length(ct, NF_CT_EXT_HELPER, - helper->data_len, gfp); + help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp); if (help) INIT_HLIST_HEAD(&help->expectations); else @@ -484,7 +483,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, u16 l3num, u16 protonum, const char *name, u16 default_port, u16 spec_port, u32 id, const struct nf_conntrack_expect_policy *exp_pol, - u32 expect_class_max, u32 data_len, + u32 expect_class_max, int (*help)(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo), @@ -497,7 +496,6 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, helper->tuple.src.u.all = htons(spec_port); helper->expect_policy = exp_pol; helper->expect_class_max = expect_class_max; - helper->data_len = data_len; helper->help = help; helper->from_nlattr = from_nlattr; helper->me = module; diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 1a5af4d4af2d..5523acce9d69 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -263,7 +263,7 @@ static int __init nf_conntrack_irc_init(void) for (i = 0; i < ports_c; i++) { nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, "irc", IRC_PORT, ports[i], i, &irc_exp_policy, - 0, 0, help, NULL, THIS_MODULE); + 0, help, NULL, THIS_MODULE); } ret = nf_conntrack_helpers_register(&irc[0], ports_c); diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 34fac4c52c4c..126031909fc7 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -596,7 +596,6 @@ static const struct nf_conntrack_expect_policy pptp_exp_policy = { static struct nf_conntrack_helper pptp __read_mostly = { .name = "pptp", .me = THIS_MODULE, - .data_len = sizeof(struct nf_ct_pptp_master), .tuple.src.l3num = AF_INET, .tuple.src.u.tcp.port = cpu_to_be16(PPTP_CONTROL_PORT), .tuple.dst.protonum = IPPROTO_TCP, diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index 1121db08d048..ae457f39d5ce 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c @@ -198,13 +198,11 @@ static int __init nf_conntrack_sane_init(void) for (i = 0; i < ports_c; i++) { nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP, "sane", SANE_PORT, ports[i], ports[i], - &sane_exp_policy, 0, - sizeof(struct nf_ct_sane_master), help, NULL, + &sane_exp_policy, 0, help, NULL, THIS_MODULE); nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP, "sane", SANE_PORT, ports[i], ports[i], - &sane_exp_policy, 0, - sizeof(struct nf_ct_sane_master), help, NULL, + &sane_exp_policy, 0, help, NULL, THIS_MODULE); } diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 79bbcc4d52ee..d38af4274335 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -1630,23 +1630,19 @@ static int __init nf_conntrack_sip_init(void) for (i = 0; i < ports_c; i++) { nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP, "sip", SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, - sizeof(struct nf_ct_sip_master), sip_help_udp, + SIP_EXPECT_MAX, sip_help_udp, NULL, THIS_MODULE); nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP, "sip", SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, - sizeof(struct nf_ct_sip_master), sip_help_tcp, + SIP_EXPECT_MAX, sip_help_tcp, NULL, THIS_MODULE); nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP, "sip", SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, - sizeof(struct nf_ct_sip_master), sip_help_udp, + SIP_EXPECT_MAX, sip_help_udp, NULL, THIS_MODULE); nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP, "sip", SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, - sizeof(struct nf_ct_sip_master), sip_help_tcp, + SIP_EXPECT_MAX, sip_help_tcp, NULL, THIS_MODULE); } diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index 27e2f6f904dc..0ec6779fd5d9 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c @@ -121,10 +121,10 @@ static int __init nf_conntrack_tftp_init(void) for (i = 0; i < ports_c; i++) { nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP, "tftp", TFTP_PORT, ports[i], i, &tftp_exp_policy, - 0, 0, tftp_help, NULL, THIS_MODULE); + 0, tftp_help, NULL, THIS_MODULE); nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP, "tftp", TFTP_PORT, ports[i], i, &tftp_exp_policy, - 0, 0, tftp_help, NULL, THIS_MODULE); + 0, tftp_help, NULL, THIS_MODULE); } ret = nf_conntrack_helpers_register(tftp, ports_c * 2); -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH nf-next 5/6] netfilter: remove last traces of variable-sized extensions 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal ` (3 preceding siblings ...) 2017-04-15 23:29 ` [PATCH nf-next 4/6] netfilter: helpers: remove data_len usage for inkernel helpers Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 6/6] netfilter: conntrack: use u8 for extension sizes again Florian Westphal 2017-04-19 15:56 ` [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Pablo Neira Ayuso 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal get rid of the (now unused) nf_ct_ext_add_length define and also rename the function to plain nf_ct_ext_add(). Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_conntrack_extend.h | 8 +------- net/netfilter/nf_conntrack_extend.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 1c3035dda31f..4ec645c8b647 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -86,13 +86,7 @@ static inline void nf_ct_ext_free(struct nf_conn *ct) } /* Add this type, returns pointer to data or NULL. */ -void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, - size_t var_alloc_len, gfp_t gfp); - -#define nf_ct_ext_add(ct, id, gfp) \ - ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), 0, (gfp))) -#define nf_ct_ext_add_length(ct, id, len, gfp) \ - ((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), (len), (gfp))) +void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp); #define NF_CT_EXT_F_PREALLOC 0x0001 diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 008299b7f78f..b5879a9c748d 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -44,8 +44,7 @@ void __nf_ct_ext_destroy(struct nf_conn *ct) EXPORT_SYMBOL(__nf_ct_ext_destroy); static void * -nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, - size_t var_alloc_len, gfp_t gfp) +nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) { unsigned int off, len; struct nf_ct_ext_type *t; @@ -59,8 +58,8 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, } off = ALIGN(sizeof(struct nf_ct_ext), t->align); - len = off + t->len + var_alloc_len; - alloc_size = t->alloc_size + var_alloc_len; + len = off + t->len; + alloc_size = t->alloc_size; rcu_read_unlock(); *ext = kzalloc(alloc_size, gfp); @@ -73,8 +72,7 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, return (void *)(*ext) + off; } -void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, - size_t var_alloc_len, gfp_t gfp) +void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) { struct nf_ct_ext *old, *new; int newlen, newoff; @@ -85,7 +83,7 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, old = ct->ext; if (!old) - return nf_ct_ext_create(&ct->ext, id, var_alloc_len, gfp); + return nf_ct_ext_create(&ct->ext, id, gfp); if (__nf_ct_ext_exist(old, id)) return NULL; @@ -98,7 +96,7 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, } newoff = ALIGN(old->len, t->align); - newlen = newoff + t->len + var_alloc_len; + newlen = newoff + t->len; rcu_read_unlock(); new = __krealloc(old, newlen, gfp); @@ -115,7 +113,7 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id, memset((void *)new + newoff, 0, newlen - newoff); return (void *)new + newoff; } -EXPORT_SYMBOL(__nf_ct_ext_add_length); +EXPORT_SYMBOL(nf_ct_ext_add); static void update_alloc_size(struct nf_ct_ext_type *type) { -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH nf-next 6/6] netfilter: conntrack: use u8 for extension sizes again 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal ` (4 preceding siblings ...) 2017-04-15 23:29 ` [PATCH nf-next 5/6] netfilter: remove last traces of variable-sized extensions Florian Westphal @ 2017-04-15 23:29 ` Florian Westphal 2017-04-19 15:56 ` [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Pablo Neira Ayuso 6 siblings, 0 replies; 8+ messages in thread From: Florian Westphal @ 2017-04-15 23:29 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal commit 223b02d923ecd7c84cf9780bb3686f455d279279 ("netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len") had to increase size of the extension offsets because total size of the extensions had increased to a point where u8 did overflow. 3 years later we've managed to diet extensions a bit and we no longer need u16. Furthermore we can now add a compile-time assertion for this problem. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_conntrack_extend.h | 4 ++-- net/netfilter/nf_conntrack_core.c | 33 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 4ec645c8b647..5fc908dc9f32 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -43,8 +43,8 @@ enum nf_ct_ext_id { /* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext { struct rcu_head rcu; - u16 offset[NF_CT_EXT_NUM]; - u16 len; + u8 offset[NF_CT_EXT_NUM]; + u8 len; char data[0]; }; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 03150f60714d..62368b05cef5 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1804,12 +1804,45 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, &nf_conntrack_htable_size, 0600); +static unsigned int total_extension_size(void) +{ + /* remember to add new extensions below */ + BUILD_BUG_ON(NF_CT_EXT_NUM > 9); + + return sizeof(struct nf_ct_ext) + + sizeof(struct nf_conn_help) +#if IS_ENABLED(CONFIG_NF_NAT) + + sizeof(struct nf_conn_nat) +#endif + + sizeof(struct nf_conn_seqadj) + + sizeof(struct nf_conn_acct) +#ifdef CONFIG_NF_CONNTRACK_EVENTS + + sizeof(struct nf_conntrack_ecache) +#endif +#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP + + sizeof(struct nf_conn_tstamp) +#endif +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + + sizeof(struct nf_conn_timeout) +#endif +#ifdef CONFIG_NF_CONNTRACK_LABELS + + sizeof(struct nf_conn_labels) +#endif +#if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) + + sizeof(struct nf_conn_synproxy) +#endif + ; +}; + int nf_conntrack_init_start(void) { int max_factor = 8; int ret = -ENOMEM; int i; + /* struct nf_ct_ext uses u8 to store offsets/size */ + BUILD_BUG_ON(total_extension_size() > 255u); + seqcount_init(&nf_conntrack_generation); for (i = 0; i < CONNTRACK_LOCKS; i++) -- 2.10.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal ` (5 preceding siblings ...) 2017-04-15 23:29 ` [PATCH nf-next 6/6] netfilter: conntrack: use u8 for extension sizes again Florian Westphal @ 2017-04-19 15:56 ` Pablo Neira Ayuso 6 siblings, 0 replies; 8+ messages in thread From: Pablo Neira Ayuso @ 2017-04-19 15:56 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On Sun, Apr 16, 2017 at 01:29:13AM +0200, Florian Westphal wrote: > 3 years ago we had to bump the offsets to the extensions > (223b02d923ecd7c84cf9780bb3686f455d279279, > "netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len") > because total size of all extensions had increased to a point where u8 > did overflow. > > We already dieted the extensions back to more reasonable sizes, however, > I never wanted to switch back because overflow produces hard to diagnose > crash bugs, and we could not add compile-time assert because extensions > can be dynamically sized. > > This series makes the last veriable-sized extension (helper) > fixed in size by adding a 32byte scratch area for helpers to use > and then adds the compile-time asserts to catch overflow during build > time. Series applied. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-04-19 15:56 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-04-15 23:29 [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 1/6] netfilter: conntrack: move helper struct to nf_conntrack_helper.h Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 2/6] netfilter: helper: add build-time asserts for helper data size Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 3/6] netfilter: nfnetlink_cthelper: reject too large userspace allocation requests Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 4/6] netfilter: helpers: remove data_len usage for inkernel helpers Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 5/6] netfilter: remove last traces of variable-sized extensions Florian Westphal 2017-04-15 23:29 ` [PATCH nf-next 6/6] netfilter: conntrack: use u8 for extension sizes again Florian Westphal 2017-04-19 15:56 ` [PATCH nf-next 0/6] netfilter: remove support for variably-sized extensions Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).