laforge submitted this change.
xua_rkm: Validate IE lengths of M3UA RKM inner messages
SUA RKM is not yet implemented, and the existing functions are only
expected to be used by M3UA.
Related: OS#7074
Reported-By: Tristan Madani <tristan@talencesecurity.com>
Change-Id: Ibe7e446b1a537c0c09f8049add3460e37cdd58e8
---
M src/m3ua.c
M src/xua_internal.h
M src/xua_msg.c
M src/xua_msg.h
M src/xua_rkm.c
5 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/src/m3ua.c b/src/m3ua.c
index 79e654d..52bf12e 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -207,9 +207,30 @@
#define M3UA_MSG_PART_CLASS_DEREG_RESULT(mandatory) \
XUA_MSG_PART_CLASS(M3UA_IEI_DEREG_RESULT, (mandatory), true, 16, XUA_MSG_PART_CLASS_MAX_LEN)
+#define M3UA_MSG_PART_CLASS_LOC_RKEY_ID(mandatory) \
+ XUA_MSG_PART_CLASS_U32(M3UA_IEI_LOC_RKEY_ID, (mandatory))
+
+/* Only used (up to multiple times) inside Routing Key group IE: */
+#define M3UA_MSG_PART_CLASS_DEST_PC \
+ XUA_MSG_PART_CLASS(M3UA_IEI_DEST_PC, true, true, sizeof(uint32_t), sizeof(uint32_t))
+
+/* Only used (up to multiple times) inside Routing Key group IE: */
+#define M3UA_MSG_PART_CLASS_SVC_IND \
+ XUA_MSG_PART_CLASS(M3UA_IEI_SVC_IND, false, true, 0, XUA_MSG_PART_CLASS_MAX_LEN)
+
+/* Only used (up to multiple times) inside Routing Key group IE: */
+#define M3UA_MSG_PART_CLASS_ORIG_PC \
+ XUA_MSG_PART_CLASS(M3UA_IEI_ORIG_PC, false, true, 0, XUA_MSG_PART_CLASS_MAX_LEN)
+
#define M3UA_MSG_PART_CLASS_PROT_DATA(mandatory) \
XUA_MSG_PART_CLASS_UNBOUND(M3UA_IEI_PROT_DATA, (mandatory))
+#define M3UA_MSG_PART_CLASS_REG_STATUS(mandatory) \
+ XUA_MSG_PART_CLASS_U32(M3UA_IEI_REG_STATUS, (mandatory))
+
+#define M3UA_MSG_PART_CLASS_DEREG_STATUS(mandatory) \
+ XUA_MSG_PART_CLASS_U32(M3UA_IEI_DEREG_STATUS, (mandatory))
+
/* XFER */
static const struct xua_msg_part_class data_ies[] = {
M3UA_MSG_PART_CLASS_NET_APPEAR(false),
@@ -456,6 +477,33 @@
},
};
+/* Inner RKM messages: RKM REG REQ "Routing Key" */
+const struct xua_msg_part_class m3ua_rkm_reg_req_routing_key_ies[] = {
+ M3UA_MSG_PART_CLASS_LOC_RKEY_ID(true),
+ M3UA_MSG_PART_CLASS_ROUTE_CTX1(false),
+ M3UA_MSG_PART_CLASS_TRAF_MODE_TYP(false),
+ M3UA_MSG_PART_CLASS_DEST_PC,
+ M3UA_MSG_PART_CLASS_NET_APPEAR(false),
+ M3UA_MSG_PART_CLASS_SVC_IND,
+ M3UA_MSG_PART_CLASS_ORIG_PC,
+ XUA_MSG_PART_CLASS_EOF
+};
+
+/* Inner RKM messages: RKM REG RSP "Registration Result" */
+const struct xua_msg_part_class m3ua_rkm_reg_rsp_registration_result_ies[] = {
+ M3UA_MSG_PART_CLASS_LOC_RKEY_ID(true),
+ M3UA_MSG_PART_CLASS_ROUTE_CTX1(true),
+ M3UA_MSG_PART_CLASS_REG_STATUS(true),
+ XUA_MSG_PART_CLASS_EOF
+};
+
+/* Inner RKM messages: RKM DEREG RSP "Deregistration Result" */
+const struct xua_msg_part_class m3ua_rkm_dereg_rsp_deregistration_result_ies[] = {
+ M3UA_MSG_PART_CLASS_ROUTE_CTX1(true),
+ M3UA_MSG_PART_CLASS_DEREG_STATUS(true),
+ XUA_MSG_PART_CLASS_EOF
+};
+
/* M3UA dialect of XUA, MGMT,XFER,SNM,ASPSM,ASPTM,RKM */
const struct xua_dialect xua_dialect_m3ua = {
.name = "M3UA",
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 5422161..a2e4fc1 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -90,6 +90,9 @@
extern const struct xua_msg_class m3ua_msg_class_rkm;
extern const struct xua_msg_class m3ua_msg_class_aspsm;
extern const struct xua_msg_class m3ua_msg_class_asptm;
+extern const struct xua_msg_part_class m3ua_rkm_reg_req_routing_key_ies[];
+extern const struct xua_msg_part_class m3ua_rkm_reg_rsp_registration_result_ies[];
+extern const struct xua_msg_part_class m3ua_rkm_dereg_rsp_deregistration_result_ies[];
extern const struct xua_msg_part_class m3ua_ntfy_req_ies[];
extern const struct xua_msg_part_class m3ua_asp_inact_ies[];
diff --git a/src/xua_msg.c b/src/xua_msg.c
index 59e5995..61281c4 100644
--- a/src/xua_msg.c
+++ b/src/xua_msg.c
@@ -536,9 +536,9 @@
}
/* Validate incoming xua_msg. returns 0 on success, M3UA_ERR_* on failure. */
-static int xua_dialect_check_all_ies_ext(const struct xua_dialect *dialect, const struct xua_msg_class *xmc,
- uint8_t msg_type, const struct xua_msg_part_class *ies,
- const struct xua_msg *xua)
+int xua_dialect_check_all_ies_ext(const struct xua_dialect *dialect, const struct xua_msg_class *xmc,
+ uint8_t msg_type, const struct xua_msg_part_class *ies,
+ const struct xua_msg *xua)
{
const struct xua_msg_part_class *ie;
diff --git a/src/xua_msg.h b/src/xua_msg.h
index 3c6a8aa..9b968a6 100644
--- a/src/xua_msg.h
+++ b/src/xua_msg.h
@@ -132,6 +132,9 @@
char *xua_hdr_dump(const struct xua_msg *xua, const struct xua_dialect *dialect);
char *xua_msg_dump(const struct xua_msg *xua, const struct xua_dialect *dialect);
int xua_dialect_check_all_ies(const struct xua_dialect *dialect, const struct xua_msg *xua);
+int xua_dialect_check_all_ies_ext(const struct xua_dialect *dialect, const struct xua_msg_class *xmc,
+ uint8_t msg_type, const struct xua_msg_part_class *ies,
+ const struct xua_msg *xua);
int xua_msg_event_map(const struct xua_msg *xua,
const struct xua_msg_event_map *maps,
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index 92fbdac..acd548d 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -349,6 +349,7 @@
struct msgb *resp = m3ua_msgb_alloc(__func__);
struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS];
unsigned int i, num_newly_assigned_as = 0;
+ int rc;
memset(newly_assigned_as, 0, sizeof(newly_assigned_as));
@@ -362,7 +363,17 @@
inner = xua_from_nested(part);
if (!inner) {
LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
- "nested IE for Routing Key\n");
+ "nested IEs in Routing Key\n");
+ /* FIXME: ERROR to peer */
+ continue;
+ }
+ rc = xua_dialect_check_all_ies_ext(&xua_dialect_m3ua, &m3ua_msg_class_rkm, M3UA_RKM_REG_REQ,
+ m3ua_rkm_reg_req_routing_key_ies, inner);
+ if (rc > 0) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
+ "nested IEs in Routing Key\n");
+ xua_msg_free(inner);
+ /* FIXME: ERROR to peer */
continue;
}
/* handle single registration and append result to
@@ -502,6 +513,7 @@
{
struct xua_msg_part *part;
struct xua_msg *inner = NULL;
+ int rc;
llist_for_each_entry(part, &xua->headers, entry) {
/* skip other IEs and/or short REG_RES IEs */
@@ -512,8 +524,22 @@
* registration result (we only support one AS per ASP
* for now) */
inner = xua_from_nested(part);
- if (!inner)
+ if (!inner) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
+ "nested IEs in Registration Result\n");
+ /* FIXME: ERROR to peer */
continue;
+ }
+
+ rc = xua_dialect_check_all_ies_ext(&xua_dialect_m3ua, &m3ua_msg_class_rkm, M3UA_RKM_REG_RSP,
+ m3ua_rkm_reg_rsp_registration_result_ies, inner);
+ if (rc > 0) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
+ "nested IEs in Registration Result\n");
+ xua_msg_free(inner);
+ /* FIXME: ERROR to peer */
+ continue;
+ }
handle_rkey_reg_resp(asp, inner);
xua_msg_free(inner);
@@ -526,13 +552,6 @@
{
struct osmo_xlm_prim *oxp;
- if (!xua_msg_find_tag(inner, M3UA_IEI_DEREG_STATUS) ||
- !xua_msg_find_tag(inner, M3UA_IEI_ROUTE_CTX)) {
- LOGPASP(asp, DLSS7, LOGL_NOTICE, "Missing Inner IE in DEREG RESP\n");
- /* FIXME: ERROR to peer */
- return -1;
- }
-
oxp = xua_xlm_prim_alloc_m_rk_dereg_cfm(xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX),
xua_msg_get_u32(inner, M3UA_IEI_DEREG_STATUS));
@@ -551,6 +570,7 @@
{
struct xua_msg_part *part;
struct xua_msg *inner = NULL;
+ int rc;
llist_for_each_entry(part, &xua->headers, entry) {
/* skip other IEs and/or short REG_RES IEs */
@@ -561,8 +581,22 @@
* registration result (we only support one AS per ASP
* for now) */
inner = xua_from_nested(part);
- if (!inner)
+ if (!inner) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
+ "nested IEs in Deregistration Result\n");
+ /* FIXME: ERROR to peer */
continue;
+ }
+
+ rc = xua_dialect_check_all_ies_ext(&xua_dialect_m3ua, &m3ua_msg_class_rkm, M3UA_RKM_DEREG_RSP,
+ m3ua_rkm_dereg_rsp_deregistration_result_ies, inner);
+ if (rc > 0) {
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse "
+ "nested IEs in Deregistration Result\n");
+ xua_msg_free(inner);
+ /* FIXME: ERROR to peer */
+ continue;
+ }
handle_rkey_dereg_resp(asp, inner);
xua_msg_free(inner);
To view, visit change 43394. To unsubscribe, or for help writing mail filters, visit settings.