Hi,
There are more m_pullup()s in IPsec input. Pass down the pointer
to the mbuf. At the end it will reach ip_deliver() which expects
a pointer to an mbuf anyway.
ok?
bluhm
Index: netinet/ip_ah.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ah.c,v
retrieving revision 1.160
diff -u -p -r1.160 ip_ah.c
--- netinet/ip_ah.c 23 Oct 2021 22:19:37 -0000 1.160
+++ netinet/ip_ah.c 23 Oct 2021 23:31:00 -0000
@@ -721,7 +721,7 @@ ah_input(struct mbuf **mp, struct tdb *t
/* Release the crypto descriptors */
crypto_freereq(crp);
- error = ah_input_cb(tdb, tc, m, clen);
+ error = ah_input_cb(tdb, tc, mp, clen);
if (error) {
ipsecstat_inc(ipsec_idrops);
tdb->tdb_idrops++;
@@ -737,9 +737,10 @@ ah_input(struct mbuf **mp, struct tdb *t
}
int
-ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen)
+ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen)
{
const struct auth_hash *ahx = tdb->tdb_authalgxform;
+ struct mbuf *m = *mp;
int roff, rplen, skip, protoff;
u_int64_t rpl;
u_int32_t btsx, esn;
@@ -899,10 +900,10 @@ ah_input_cb(struct tdb *tdb, struct tdb_
free(tc, M_XDATA, 0);
- return ipsec_common_input_cb(m, tdb, skip, protoff);
+ return ipsec_common_input_cb(mp, tdb, skip, protoff);
baddone:
- m_freem(m);
+ m_freemp(mp);
free(tc, M_XDATA, 0);
return -1;
}
Index: netinet/ip_esp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_esp.c,v
retrieving revision 1.179
diff -u -p -r1.179 ip_esp.c
--- netinet/ip_esp.c 23 Oct 2021 22:19:37 -0000 1.179
+++ netinet/ip_esp.c 23 Oct 2021 23:43:36 -0000
@@ -546,7 +546,7 @@ esp_input(struct mbuf **mp, struct tdb *
/* Release the crypto descriptors */
crypto_freereq(crp);
- error = esp_input_cb(tdb, tc, m, clen);
+ error = esp_input_cb(tdb, tc, mp, clen);
if (error) {
ipsecstat_inc(ipsec_idrops);
tdb->tdb_idrops++;
@@ -565,9 +565,10 @@ esp_input(struct mbuf **mp, struct tdb *
* ESP input callback, called directly by the crypto driver.
*/
int
-esp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen)
+esp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int
clen)
{
u_int8_t lastthree[3], aalg[AH_HMAC_MAX_HASHLEN];
+ struct mbuf *m = *mp;
int hlen, roff, skip, protoff;
struct mbuf *m1, *mo;
const struct auth_hash *esph;
@@ -751,10 +752,10 @@ esp_input_cb(struct tdb *tdb, struct tdb
free(tc, M_XDATA, 0);
/* Back to generic IPsec input processing */
- return ipsec_common_input_cb(m, tdb, skip, protoff);
+ return ipsec_common_input_cb(mp, tdb, skip, protoff);
baddone:
- m_freem(m);
+ m_freemp(mp);
free(tc, M_XDATA, 0);
return -1;
}
Index: netinet/ip_ipcomp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipcomp.c,v
retrieving revision 1.82
diff -u -p -r1.82 ip_ipcomp.c
--- netinet/ip_ipcomp.c 23 Oct 2021 22:19:37 -0000 1.82
+++ netinet/ip_ipcomp.c 23 Oct 2021 23:46:24 -0000
@@ -203,7 +203,7 @@ ipcomp_input(struct mbuf **mp, struct td
/* Release the crypto descriptors */
crypto_freereq(crp);
- error = ipcomp_input_cb(tdb, tc, m, clen);
+ error = ipcomp_input_cb(tdb, tc, mp, clen);
if (error) {
ipsecstat_inc(ipsec_idrops);
tdb->tdb_idrops++;
@@ -219,8 +219,10 @@ ipcomp_input(struct mbuf **mp, struct td
}
int
-ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int
clen)
+ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp,
+ int clen)
{
+ struct mbuf *m = *mp;
int skip, protoff, roff, hlen = IPCOMP_HLENGTH;
u_int8_t nproto;
u_int64_t ibytes;
@@ -259,7 +261,8 @@ ipcomp_input_cb(struct tdb *tdb, struct
/* In case it's not done already, adjust the size of the mbuf chain */
m->m_pkthdr.len = clen + hlen + skip;
- if ((m->m_len < skip + hlen) && (m = m_pullup(m, skip + hlen)) == 0) {
+ if (m->m_len < skip + hlen &&
+ (m = *mp = m_pullup(m, skip + hlen)) == NULL) {
ipcompstat_inc(ipcomps_hdrops);
goto baddone;
}
@@ -334,10 +337,10 @@ ipcomp_input_cb(struct tdb *tdb, struct
m_copyback(m, protoff, sizeof(u_int8_t), &nproto, M_NOWAIT);
/* Back to generic IPsec input processing */
- return ipsec_common_input_cb(m, tdb, skip, protoff);
+ return ipsec_common_input_cb(mp, tdb, skip, protoff);
baddone:
- m_freem(m);
+ m_freemp(mp);
free(tc, M_XDATA, 0);
return -1;
}
Index: netinet/ip_ipsp.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.212
diff -u -p -r1.212 ip_ipsp.h
--- netinet/ip_ipsp.h 23 Oct 2021 22:19:37 -0000 1.212
+++ netinet/ip_ipsp.h 23 Oct 2021 23:32:03 -0000
@@ -571,7 +571,7 @@ int ah_attach(void);
int ah_init(struct tdb *, const struct xformsw *, struct ipsecinit *);
int ah_zeroize(struct tdb *);
int ah_input(struct mbuf **, struct tdb *, int, int);
-int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int);
+int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int);
int ah_output(struct mbuf *, struct tdb *, int, int);
int ah_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int,
int);
@@ -590,7 +590,7 @@ int esp_attach(void);
int esp_init(struct tdb *, const struct xformsw *, struct ipsecinit *);
int esp_zeroize(struct tdb *);
int esp_input(struct mbuf **, struct tdb *, int, int);
-int esp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int);
+int esp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int);
int esp_output(struct mbuf *, struct tdb *, int, int);
int esp_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int,
int);
@@ -608,7 +608,7 @@ int ipcomp_attach(void);
int ipcomp_init(struct tdb *, const struct xformsw *, struct ipsecinit *);
int ipcomp_zeroize(struct tdb *);
int ipcomp_input(struct mbuf **, struct tdb *, int, int);
-int ipcomp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int);
+int ipcomp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int);
int ipcomp_output(struct mbuf *, struct tdb *, int, int);
int ipcomp_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int,
int);
@@ -648,7 +648,7 @@ void ipsp_init(void);
void ipsec_init(void);
int ipsec_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int ipsec_common_input(struct mbuf **, int, int, int, int, int);
-int ipsec_common_input_cb(struct mbuf *, struct tdb *, int, int);
+int ipsec_common_input_cb(struct mbuf **, struct tdb *, int, int);
int ipsec_delete_policy(struct ipsec_policy *);
ssize_t ipsec_hdrsz(struct tdb *);
void ipsec_adjust_mtu(struct mbuf *, u_int32_t);
Index: netinet/ipsec_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.187
diff -u -p -r1.187 ipsec_input.c
--- netinet/ipsec_input.c 23 Oct 2021 22:19:37 -0000 1.187
+++ netinet/ipsec_input.c 23 Oct 2021 23:46:35 -0000
@@ -372,8 +372,9 @@ ipsec_common_input(struct mbuf **mp, int
* filtering and other sanity checks on the processed packet.
*/
int
-ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
+ipsec_common_input_cb(struct mbuf **mp, struct tdb *tdbp, int skip, int
protoff)
{
+ struct mbuf *m = *mp;
int af, sproto;
u_int8_t prot;
#if NBPFILTER > 0
@@ -396,7 +397,8 @@ ipsec_common_input_cb(struct mbuf *m, st
/* Fix IPv4 header */
if (af == AF_INET) {
- if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) {
+ if (m->m_len < skip &&
+ (m = *mp = m_pullup(m, skip)) == NULL) {
DPRINTF("processing failed for SA %s/%08x",
ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)),
ntohl(tdbp->tdb_spi));
@@ -441,7 +443,7 @@ ipsec_common_input_cb(struct mbuf *m, st
/* Fix IPv6 header */
if (af == AF_INET6) {
if (m->m_len < sizeof(struct ip6_hdr) &&
- (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
+ (m = *mp = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
DPRINTF("processing failed for SA %s/%08x",
ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)),
@@ -631,11 +633,11 @@ ipsec_common_input_cb(struct mbuf *m, st
}
#endif
/* Call the appropriate IPsec transform callback. */
- ip_deliver(&m, &skip, prot, af);
+ ip_deliver(mp, &skip, prot, af);
return 0;
baddone:
- m_freem(m);
+ m_freemp(mp);
return -1;
#undef IPSEC_ISTAT
}