aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-03-11 12:32:21 +0100
committerMartin Willi <martin@revosec.ch>2013-03-11 12:32:21 +0100
commitd3f5a05e292f63ef285a1f0a458669f59bf179fc (patch)
tree93e33d741ad66fb9d8e50579a105e94aa52f5357 /src
parent8f727d8007510839a17796b53afe090a8955e23d (diff)
downloadstrongswan-d3f5a05e292f63ef285a1f0a458669f59bf179fc.tar.bz2
strongswan-d3f5a05e292f63ef285a1f0a458669f59bf179fc.tar.xz
When adding Netlink attributes, increase header length with potential alignment
If the payload is unaligned, we must make sure the total netlink message length includes the added alignment for the first attribute.
Diffstat (limited to 'src')
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c62
1 files changed, 30 insertions, 32 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index e81e55c24..3231f8212 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -1259,7 +1259,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_ALG_AEAD;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) +
enc_key.len);
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1291,7 +1292,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_ALG_CRYPT;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + enc_key.len);
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1344,8 +1346,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_ALG_AUTH_TRUNC;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_auth) +
int_key.len);
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1364,8 +1366,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_ALG_AUTH;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + int_key.len);
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1394,7 +1396,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
ipcomp_transform_names, ipcomp);
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1414,8 +1416,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_ENCAP;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1446,7 +1447,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1464,8 +1465,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_TFCPAD;
rthdr->rta_len = RTA_LENGTH(sizeof(u_int32_t));
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1487,8 +1487,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr->rta_type = XFRMA_REPLAY_ESN_VAL;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state_esn) +
(this->replay_window + 7) / 8);
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1580,7 +1580,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
return;
@@ -1681,7 +1681,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
return FAILED;
@@ -1784,7 +1784,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
return FAILED;
@@ -1828,7 +1828,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
struct nlmsghdr *hdr, *out = NULL;
struct xfrm_usersa_id *sa_id;
struct xfrm_usersa_info *out_sa = NULL, *sa;
- size_t len;
+ size_t len, newlen;
struct rtattr *rta;
size_t rtasize;
struct xfrm_encap_tmpl* tmpl = NULL;
@@ -1866,7 +1866,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
return FAILED;
@@ -1956,8 +1956,9 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
}
memcpy(pos, rta, rta->rta_len);
- pos += RTA_ALIGN(rta->rta_len);
- hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
+ newlen = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rta->rta_len);
+ pos += newlen - hdr->nlmsg_len;
+ hdr->nlmsg_len = newlen;
}
rta = RTA_NEXT(rta, rtasize);
}
@@ -1967,8 +1968,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
{ /* add tmpl if we are enabling it */
rta->rta_type = XFRMA_ENCAP;
rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
-
- hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rta->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -1988,8 +1988,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
rta->rta_type = XFRMA_REPLAY_ESN_VAL;
rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state_esn) +
this->replay_bmp);
-
- hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rta->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -2003,8 +2002,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
{
rta->rta_type = XFRMA_REPLAY_VAL;
rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state));
-
- hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rta->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
goto failed;
@@ -2134,7 +2132,8 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
}
rthdr->rta_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
- hdr->nlmsg_len += RTA_ALIGN(RTA_LENGTH(sizeof(struct xfrm_user_tmpl)));
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) +
+ RTA_ALIGN(RTA_LENGTH(sizeof(struct xfrm_user_tmpl)));
if (hdr->nlmsg_len > sizeof(request))
{
this->mutex->unlock(this->mutex);
@@ -2171,7 +2170,7 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
this->mutex->unlock(this->mutex);
@@ -2414,8 +2413,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
-
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
return FAILED;
@@ -2586,7 +2584,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
rthdr->rta_type = XFRMA_MARK;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
+ hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
this->mutex->unlock(this->mutex);