diff --git a/net/strongswan/Makefile b/net/strongswan/Makefile index 88ed0a50e..5d31c564a 100644 --- a/net/strongswan/Makefile +++ b/net/strongswan/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=strongswan PKG_VERSION:=5.3.5 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=http://download.strongswan.org/ http://download2.strongswan.org/ diff --git a/net/strongswan/patches/110-connmark-Fix-alignment-when-adding-rules.patch b/net/strongswan/patches/110-connmark-Fix-alignment-when-adding-rules.patch new file mode 100644 index 000000000..963bd1bfc --- /dev/null +++ b/net/strongswan/patches/110-connmark-Fix-alignment-when-adding-rules.patch @@ -0,0 +1,411 @@ +From a4d7f5ee6f36decdcd18d70078e1f0a847fe9b24 Mon Sep 17 00:00:00 2001 +From: Tobias Brunner +Date: Mon, 30 Nov 2015 16:04:35 +0100 +Subject: [PATCH 1/2] connmark: Fix alignment when adding rules + +The structs that make up a message sent to the kernel have all to be +aligned with XT_ALIGN. That was not necessarily the case when +initializing the complete message as struct. + + #1212 +--- + src/libcharon/plugins/connmark/connmark_listener.c | 332 +++++++++++---------- + 1 file changed, 172 insertions(+), 160 deletions(-) + +diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c +index 23df690..cd53701 100644 +--- a/src/libcharon/plugins/connmark/connmark_listener.c ++++ b/src/libcharon/plugins/connmark/connmark_listener.c +@@ -1,4 +1,7 @@ + /* ++ * Copyright (C) 2015 Tobias Brunner ++ * Hochschule fuer Technik Rapperswil ++ * + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * +@@ -25,6 +28,14 @@ + #include + #include + ++/** ++ * Add a struct at the current position in the buffer ++ */ ++#define ADD_STRUCT(pos, st, ...) ({\ ++ typeof(pos) _cur = pos; pos += XT_ALIGN(sizeof(st));\ ++ *(st*)_cur = (st){ __VA_ARGS__ };\ ++ (st*)_cur;\ ++}) + + typedef struct private_connmark_listener_t private_connmark_listener_t; + +@@ -108,54 +119,54 @@ static bool manage_pre_esp_in_udp(private_connmark_listener_t *this, + u_int mark, u_int32_t spi, + host_t *dst, host_t *src) + { +- struct { +- struct ipt_entry e; +- struct ipt_entry_match m; +- struct xt_udp udp; +- struct ipt_entry_target t; +- struct xt_mark_tginfo2 tm; +- } ipt = { +- .e = { +- .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + +- sizeof(ipt.udp)), +- .next_offset = sizeof(ipt), +- .ip = { +- .proto = IPPROTO_UDP, +- }, ++ u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + ++ XT_ALIGN(sizeof(struct xt_udp)); ++ u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; ++ u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + ++ XT_ALIGN(sizeof(struct xt_mark_tginfo2)); ++ u_int16_t entry_size = target_offset + target_size; ++ u_char ipt[entry_size], *pos = ipt; ++ struct ipt_entry *e; ++ ++ memset(ipt, 0, sizeof(ipt)); ++ e = ADD_STRUCT(pos, struct ipt_entry, ++ .target_offset = target_offset, ++ .next_offset = entry_size, ++ .ip = { ++ .proto = IPPROTO_UDP, + }, +- .m = { +- .u = { +- .user = { +- .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)), +- .name = "udp", +- }, ++ ); ++ if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) || ++ !host2in(src, &e->ip.src, &e->ip.smsk)) ++ { ++ return FALSE; ++ } ++ ADD_STRUCT(pos, struct ipt_entry_match, ++ .u = { ++ .user = { ++ .match_size = match_size, ++ .name = "udp", + }, + }, +- .udp = { +- .spts = { src->get_port(src), src->get_port(src) }, +- .dpts = { dst->get_port(dst), dst->get_port(dst) }, +- }, +- .t = { +- .u = { +- .user = { +- .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), +- .name = "MARK", +- .revision = 2, +- }, ++ ); ++ ADD_STRUCT(pos, struct xt_udp, ++ .spts = { src->get_port(src), src->get_port(src) }, ++ .dpts = { dst->get_port(dst), dst->get_port(dst) }, ++ ); ++ ADD_STRUCT(pos, struct ipt_entry_target, ++ .u = { ++ .user = { ++ .target_size = target_size, ++ .name = "MARK", ++ .revision = 2, + }, + }, +- .tm = { +- .mark = mark, +- .mask = ~0, +- }, +- }; +- +- if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || +- !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) +- { +- return FALSE; +- } +- return manage_rule(ipth, "PREROUTING", add, &ipt.e); ++ ); ++ ADD_STRUCT(pos, struct xt_mark_tginfo2, ++ .mark = mark, ++ .mask = ~0, ++ ); ++ return manage_rule(ipth, "PREROUTING", add, e); + } + + /** +@@ -166,53 +177,53 @@ static bool manage_pre_esp(private_connmark_listener_t *this, + u_int mark, u_int32_t spi, + host_t *dst, host_t *src) + { +- struct { +- struct ipt_entry e; +- struct ipt_entry_match m; +- struct xt_esp esp; +- struct ipt_entry_target t; +- struct xt_mark_tginfo2 tm; +- } ipt = { +- .e = { +- .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + +- sizeof(ipt.esp)), +- .next_offset = sizeof(ipt), +- .ip = { +- .proto = IPPROTO_ESP, +- }, ++ u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + ++ XT_ALIGN(sizeof(struct xt_esp)); ++ u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; ++ u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + ++ XT_ALIGN(sizeof(struct xt_mark_tginfo2)); ++ u_int16_t entry_size = target_offset + target_size; ++ u_char ipt[entry_size], *pos = ipt; ++ struct ipt_entry *e; ++ ++ memset(ipt, 0, sizeof(ipt)); ++ e = ADD_STRUCT(pos, struct ipt_entry, ++ .target_offset = target_offset, ++ .next_offset = entry_size, ++ .ip = { ++ .proto = IPPROTO_ESP, + }, +- .m = { +- .u = { +- .user = { +- .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)), +- .name = "esp", +- }, ++ ); ++ if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) || ++ !host2in(src, &e->ip.src, &e->ip.smsk)) ++ { ++ return FALSE; ++ } ++ ADD_STRUCT(pos, struct ipt_entry_match, ++ .u = { ++ .user = { ++ .match_size = match_size, ++ .name = "esp", + }, + }, +- .esp = { +- .spis = { htonl(spi), htonl(spi) }, +- }, +- .t = { +- .u = { +- .user = { +- .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), +- .name = "MARK", +- .revision = 2, +- }, ++ ); ++ ADD_STRUCT(pos, struct xt_esp, ++ .spis = { htonl(spi), htonl(spi) }, ++ ); ++ ADD_STRUCT(pos, struct ipt_entry_target, ++ .u = { ++ .user = { ++ .target_size = target_size, ++ .name = "MARK", ++ .revision = 2, + }, + }, +- .tm = { +- .mark = mark, +- .mask = ~0, +- }, +- }; +- +- if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || +- !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) +- { +- return FALSE; +- } +- return manage_rule(ipth, "PREROUTING", add, &ipt.e); ++ ); ++ ADD_STRUCT(pos, struct xt_mark_tginfo2, ++ .mark = mark, ++ .mask = ~0, ++ ); ++ return manage_rule(ipth, "PREROUTING", add, e); + } + + /** +@@ -238,59 +249,59 @@ static bool manage_in(private_connmark_listener_t *this, + u_int mark, u_int32_t spi, + traffic_selector_t *dst, traffic_selector_t *src) + { +- struct { +- struct ipt_entry e; +- struct ipt_entry_match m; +- struct xt_policy_info p; +- struct ipt_entry_target t; +- struct xt_connmark_tginfo1 cm; +- } ipt = { +- .e = { +- .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + +- sizeof(ipt.p)), +- .next_offset = sizeof(ipt), +- }, +- .m = { +- .u = { +- .user = { +- .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.p)), +- .name = "policy", +- }, ++ u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + ++ XT_ALIGN(sizeof(struct xt_policy_info)); ++ u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; ++ u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + ++ XT_ALIGN(sizeof(struct xt_connmark_tginfo1)); ++ u_int16_t entry_size = target_offset + target_size; ++ u_char ipt[entry_size], *pos = ipt; ++ struct ipt_entry *e; ++ ++ memset(ipt, 0, sizeof(ipt)); ++ e = ADD_STRUCT(pos, struct ipt_entry, ++ .target_offset = target_offset, ++ .next_offset = entry_size, ++ ); ++ if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) || ++ !ts2in(src, &e->ip.src, &e->ip.smsk)) ++ { ++ return FALSE; ++ } ++ ADD_STRUCT(pos, struct ipt_entry_match, ++ .u = { ++ .user = { ++ .match_size = match_size, ++ .name = "policy", + }, + }, +- .p = { +- .pol = { +- { +- .spi = spi, +- .match.spi = 1, +- }, ++ ); ++ ADD_STRUCT(pos, struct xt_policy_info, ++ .pol = { ++ { ++ .spi = spi, ++ .match.spi = 1, + }, +- .len = 1, +- .flags = XT_POLICY_MATCH_IN, + }, +- .t = { +- .u = { +- .user = { +- .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), +- .name = "CONNMARK", +- .revision = 1, +- }, ++ .len = 1, ++ .flags = XT_POLICY_MATCH_IN, ++ ); ++ ADD_STRUCT(pos, struct ipt_entry_target, ++ .u = { ++ .user = { ++ .target_size = target_size, ++ .name = "CONNMARK", ++ .revision = 1, + }, + }, +- .cm = { +- .ctmark = mark, +- .ctmask = ~0, +- .nfmask = ~0, +- .mode = XT_CONNMARK_SET, +- }, +- }; +- +- if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || +- !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) +- { +- return FALSE; +- } +- return manage_rule(ipth, "INPUT", add, &ipt.e); ++ ); ++ ADD_STRUCT(pos, struct xt_connmark_tginfo1, ++ .ctmark = mark, ++ .ctmask = ~0, ++ .nfmask = ~0, ++ .mode = XT_CONNMARK_SET, ++ ); ++ return manage_rule(ipth, "INPUT", add, e); + } + + /** +@@ -300,37 +311,38 @@ static bool manage_out(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + traffic_selector_t *dst, traffic_selector_t *src) + { +- struct { +- struct ipt_entry e; +- struct ipt_entry_target t; +- struct xt_connmark_tginfo1 cm; +- } ipt = { +- .e = { +- .target_offset = XT_ALIGN(sizeof(ipt.e)), +- .next_offset = sizeof(ipt), +- }, +- .t = { +- .u = { +- .user = { +- .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), +- .name = "CONNMARK", +- .revision = 1, +- }, +- }, +- }, +- .cm = { +- .ctmask = ~0, +- .nfmask = ~0, +- .mode = XT_CONNMARK_RESTORE, +- }, +- }; +- +- if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || +- !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) ++ u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)); ++ u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + ++ XT_ALIGN(sizeof(struct xt_connmark_tginfo1)); ++ u_int16_t entry_size = target_offset + target_size; ++ u_char ipt[entry_size], *pos = ipt; ++ struct ipt_entry *e; ++ ++ memset(ipt, 0, sizeof(ipt)); ++ e = ADD_STRUCT(pos, struct ipt_entry, ++ .target_offset = target_offset, ++ .next_offset = entry_size, ++ ); ++ if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) || ++ !ts2in(src, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } +- return manage_rule(ipth, "OUTPUT", add, &ipt.e); ++ ADD_STRUCT(pos, struct ipt_entry_target, ++ .u = { ++ .user = { ++ .target_size = target_size, ++ .name = "CONNMARK", ++ .revision = 1, ++ }, ++ }, ++ ); ++ ADD_STRUCT(pos, struct xt_connmark_tginfo1, ++ .ctmask = ~0, ++ .nfmask = ~0, ++ .mode = XT_CONNMARK_RESTORE, ++ ); ++ return manage_rule(ipth, "OUTPUT", add, e); + } + + /** +-- +2.4.10