aboutsummaryrefslogtreecommitdiff
path: root/lib/libipsec
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2017-04-13 14:44:17 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2017-04-13 14:44:17 +0000
commit4e0e8f3107affbfd2cffa8ae92535e3a0cbdce31 (patch)
tree0a73737ddecb6b8d2467b589d37940091e24f675 /lib/libipsec
parent35e492f3bd4160991994617f4354f9e0b256f9af (diff)
downloadsrc-4e0e8f3107affbfd2cffa8ae92535e3a0cbdce31.tar.gz
src-4e0e8f3107affbfd2cffa8ae92535e3a0cbdce31.zip
Notes
Diffstat (limited to 'lib/libipsec')
-rw-r--r--lib/libipsec/pfkey.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c
index 34a3ac300989..4791ddc2a648 100644
--- a/lib/libipsec/pfkey.c
+++ b/lib/libipsec/pfkey.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <netipsec/ipsec.h>
#include <stdlib.h>
+#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
@@ -69,6 +70,7 @@ static caddr_t pfkey_setsadbmsg(caddr_t, caddr_t, u_int, u_int,
u_int, u_int32_t, pid_t);
static caddr_t pfkey_setsadbsa(caddr_t, caddr_t, u_int32_t, u_int,
u_int, u_int, u_int32_t);
+static caddr_t pfkey_setsadbxreplay(caddr_t, caddr_t, uint32_t);
static caddr_t pfkey_setsadbaddr(caddr_t, caddr_t, u_int,
struct sockaddr *, u_int, u_int);
static caddr_t pfkey_setsadbkey(caddr_t, caddr_t, u_int, caddr_t, u_int);
@@ -1196,6 +1198,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
+ sizeof(struct sadb_lifetime)
+ sizeof(struct sadb_lifetime);
+ if (wsize > UINT8_MAX) {
+ if (wsize > (UINT32_MAX - 32) >> 3) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return (-1);
+ }
+ len += sizeof(struct sadb_x_sa_replay);
+ }
if (e_type != SADB_EALG_NONE)
len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
if (a_type != SADB_AALG_NONE)
@@ -1223,6 +1232,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
free(newmsg);
return -1;
}
+ if (wsize > UINT8_MAX) {
+ p = pfkey_setsadbxreplay(p, ep, wsize);
+ if (!p) {
+ free(newmsg);
+ return (-1);
+ }
+ }
p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
if (!p) {
@@ -1982,7 +1998,7 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
p->sadb_sa_len = PFKEY_UNIT64(len);
p->sadb_sa_exttype = SADB_EXT_SA;
p->sadb_sa_spi = spi;
- p->sadb_sa_replay = wsize;
+ p->sadb_sa_replay = wsize > UINT8_MAX ? UINT8_MAX: wsize;
p->sadb_sa_state = SADB_SASTATE_LARVAL;
p->sadb_sa_auth = auth;
p->sadb_sa_encrypt = enc;
@@ -1992,6 +2008,31 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
}
/*
+ * Set data into sadb_x_sa_replay.
+ * `buf' must has been allocated sufficiently.
+ */
+static caddr_t
+pfkey_setsadbxreplay(caddr_t buf, caddr_t lim, uint32_t wsize)
+{
+ struct sadb_x_sa_replay *p;
+ u_int len;
+
+ p = (struct sadb_x_sa_replay *)buf;
+ len = sizeof(struct sadb_x_sa_replay);
+
+ if (buf + len > lim)
+ return (NULL);
+
+ memset(p, 0, len);
+ p->sadb_x_sa_replay_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
+ /* Convert wsize from bytes to number of packets. */
+ p->sadb_x_sa_replay_replay = wsize << 3;
+
+ return (buf + len);
+}
+
+/*
* set data into sadb_address.
* `buf' must has been allocated sufficiently.
* prefixlen is in bits.