pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33980 )
Change subject: layer23: modem: Validate IP version of UL data packets from tun match PDP context setup ......................................................................
layer23: modem: Validate IP version of UL data packets from tun match PDP context setup
Change-Id: I3fe56fcbdbb6be3366829a14a433b735f7f9d43c --- M src/host/layer23/include/osmocom/bb/common/apn.h M src/host/layer23/src/modem/app_modem.c M src/host/layer23/src/modem/sm.c 3 files changed, 40 insertions(+), 0 deletions(-)
Approvals: fixeria: Looks good to me, approved Jenkins Builder: Verified
diff --git a/src/host/layer23/include/osmocom/bb/common/apn.h b/src/host/layer23/include/osmocom/bb/common/apn.h index aad00b8..0adb8de 100644 --- a/src/host/layer23/include/osmocom/bb/common/apn.h +++ b/src/host/layer23/include/osmocom/bb/common/apn.h @@ -38,6 +38,9 @@ uint8_t qos_len; uint8_t pco[OSMO_GPRS_SM_PCO_MAXLEN]; uint8_t pco_len; + enum osmo_gprs_sm_pdp_addr_ietf_type pdp_addr_ietf_type; + struct osmo_sockaddr pdp_addr_v4; + struct osmo_sockaddr pdp_addr_v6; };
struct osmobb_apn { diff --git a/src/host/layer23/src/modem/app_modem.c b/src/host/layer23/src/modem/app_modem.c index 08a1260..2787ec7 100644 --- a/src/host/layer23/src/modem/app_modem.c +++ b/src/host/layer23/src/modem/app_modem.c @@ -121,6 +121,28 @@ LOGPAPN(LOGL_DEBUG, apn, "system wants to transmit IPv%c pkt to %s (%zu bytes)\n", iph->version == 4 ? '4' : '6', osmo_sockaddr_ntop(&dst.u.sa, addrstr), pkt_len);
+ switch (apn->pdp.pdp_addr_ietf_type) { + case OSMO_GPRS_SM_PDP_ADDR_IETF_IPV4: + if (iph->version != 4) { + LOGPAPN(LOGL_NOTICE, apn, + "system wants to transmit IPv%u pkt to %s (%zu bytes) on IPv4-only PDP Ctx, discarding!\n", + iph->version, osmo_sockaddr_ntop(&dst.u.sa, addrstr), pkt_len); + goto free_ret; + } + break; + case OSMO_GPRS_SM_PDP_ADDR_IETF_IPV6: + if (iph->version != 6) { + LOGPAPN(LOGL_NOTICE, apn, + "system wants to transmit IPv%u pkt to %s (%zu bytes) on IPv6-only PDP Ctx, discarding!\n", + iph->version, osmo_sockaddr_ntop(&dst.u.sa, addrstr), pkt_len); + goto free_ret; + } + break; + default: /* OSMO_GPRS_SM_PDP_ADDR_IETF_IPV4V6 */ + /* Allow any */ + break; + } + rc = modem_sndcp_sn_unitdata_req(apn, msgb_data(msg), pkt_len);
free_ret: diff --git a/src/host/layer23/src/modem/sm.c b/src/host/layer23/src/modem/sm.c index 9b3a35b..1977cd6 100644 --- a/src/host/layer23/src/modem/sm.c +++ b/src/host/layer23/src/modem/sm.c @@ -79,11 +79,14 @@ ms->subscr.gprs.ptmsi = sm_prim->smreg.pdp_act_cnf.acc.gmm.allocated_ptmsi; ms->gmmlayer.tlli = sm_prim->smreg.pdp_act_cnf.acc.gmm.allocated_tlli;
+ apn->pdp.pdp_addr_ietf_type = sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_ietf_type; + netdev = osmo_tundev_get_netdev(apn->tun); switch (sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_ietf_type) { case OSMO_GPRS_SM_PDP_ADDR_IETF_IPV4: LOGPAPN(LOGL_INFO, apn, "Rx %s: IPv4=%s\n", pdu_name, osmo_sockaddr_ntop(&sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4.u.sa, buf_addr)); + memcpy(&apn->pdp.pdp_addr_v4, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4, sizeof(struct osmo_sockaddr)); rc = osmo_netdev_add_addr(netdev, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4, 30); if (rc < 0) { LOGPAPN(LOGL_ERROR, apn, "Rx %s: Failed setting IPv4=%s\n", pdu_name, @@ -94,6 +97,7 @@ case OSMO_GPRS_SM_PDP_ADDR_IETF_IPV6: LOGPAPN(LOGL_INFO, apn, "Rx %s: IPv6=%s [FIXME: IPv6 not yet supported!]\n", pdu_name, osmo_sockaddr_ntop(&sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v6.u.sa, buf_addr)); + memcpy(&apn->pdp.pdp_addr_v6, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v6, sizeof(struct osmo_sockaddr)); rc = osmo_netdev_add_addr(netdev, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v6, 64); if (rc < 0) { LOGPAPN(LOGL_ERROR, apn, "Rx %s: Failed setting IPv6=%s\n", pdu_name, @@ -105,6 +109,8 @@ LOGPAPN(LOGL_INFO, apn, "Rx %s: IPv4=%s IPv6=%s [FIXME: IPv6 not yet supported!]\n", pdu_name, osmo_sockaddr_ntop(&sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4.u.sa, buf_addr), osmo_sockaddr_ntop(&sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v6.u.sa, buf_addr2)); + memcpy(&apn->pdp.pdp_addr_v4, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4, sizeof(struct osmo_sockaddr)); + memcpy(&apn->pdp.pdp_addr_v6, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v6, sizeof(struct osmo_sockaddr)); rc = osmo_netdev_add_addr(netdev, &sm_prim->smreg.pdp_act_cnf.acc.pdp_addr_v4, 30); if (rc < 0) { LOGPAPN(LOGL_ERROR, apn, "Rx %s: Failed setting IPv4=%s\n", pdu_name,