pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-sigtran/+/43394?usp=email )
Change subject: xua_rkm: Validate IE lengths of RKM inner messages
......................................................................
xua_rkm: Validate IE lengths of RKM inner messages
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, 140 insertions(+), 39 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran
refs/changes/94/43394/1
diff --git a/src/m3ua.c b/src/m3ua.c
index d1a7e27..46282c4 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -202,14 +202,32 @@
XUA_MSG_PART_CLASS(M3UA_IEI_ROUT_KEY, (mandatory), 0, UINT16_MAX)
#define M3UA_MSG_PART_CLASS_REG_RESULT(mandatory) \
- XUA_MSG_PART_CLASS(M3UA_IEI_REG_RESULT, (mandatory), 0, UINT16_MAX)
+ XUA_MSG_PART_CLASS(M3UA_IEI_REG_RESULT, (mandatory), 24, UINT16_MAX)
#define M3UA_MSG_PART_CLASS_DEREG_RESULT(mandatory) \
- XUA_MSG_PART_CLASS(M3UA_IEI_DEREG_RESULT, (mandatory), 0, UINT16_MAX)
+ XUA_MSG_PART_CLASS(M3UA_IEI_DEREG_RESULT, (mandatory), 16, UINT16_MAX)
+
+#define M3UA_MSG_PART_CLASS_LOC_RKEY_ID(mandatory) \
+ XUA_MSG_PART_CLASS_U32(M3UA_IEI_LOC_RKEY_ID, (mandatory))
+
+#define M3UA_MSG_PART_CLASS_DEST_PC(mandatory) \
+ XUA_MSG_PART_CLASS_U32(M3UA_IEI_DEST_PC, (mandatory))
+
+#define M3UA_MSG_PART_CLASS_SVC_IND(mandatory) \
+ XUA_MSG_PART_CLASS(M3UA_IEI_SVC_IND, (mandatory), 0, UINT16_MAX)
+
+#define M3UA_MSG_PART_CLASS_ORIG_PC(mandatory) \
+ XUA_MSG_PART_CLASS(M3UA_IEI_ORIG_PC, (mandatory), 0, UINT16_MAX)
#define M3UA_MSG_PART_CLASS_PROT_DATA(mandatory) \
XUA_MSG_PART_CLASS(M3UA_IEI_PROT_DATA, (mandatory), 0, UINT16_MAX)
+#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),
@@ -452,6 +470,34 @@
},
};
+/* 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(true),
+ M3UA_MSG_PART_CLASS_NET_APPEAR(false),
+ M3UA_MSG_PART_CLASS_SVC_IND(false),
+ M3UA_MSG_PART_CLASS_ORIG_PC(false),
+ 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 5195b35..47c4974 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 value_string m3ua_snm_msgt_names[];
extern const struct value_string m3ua_err_names[];
diff --git a/src/xua_msg.c b/src/xua_msg.c
index 44b173d..1b37c89 100644
--- a/src/xua_msg.c
+++ b/src/xua_msg.c
@@ -535,6 +535,47 @@
return buf;
}
+
+/* Validate incoming xua_msg. returns 0 on success, M3UA_ERR_* on failure. */
+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, bool
repeated_parts)
+{
+ const struct xua_msg_part_class *ie;
+
+ for (ie = ies; ie->tag; ie = ies++) {
+ struct xua_msg_part *part;
+ bool found = false;
+ llist_for_each_entry(part, &xua->headers, entry) {
+ if (part->tag != ie->tag)
+ continue;
+ found = true;
+ if (part->len < ie->len_min || part->len > ie->len_max)
{
+ LOGP(dialect->log_subsys, LOGL_ERROR,
+ "%s Message %s:%s IE %s length %" PRIu16
+ " out of range [%" PRIu16 ", %" PRIu16
"]\n",
+ dialect->name, xmc->name,
+ xua_class_msg_name(xmc, msg_type),
+ xua_class_iei_name(xmc, ie->tag),
+ part->len, ie->len_min, ie->len_max);
+ return M3UA_ERR_PARAM_FIELD_ERR;
+ }
+ if (!repeated_parts)
+ break;
+ }
+ if (ie->mandatory && !found) {
+ LOGP(dialect->log_subsys, LOGL_ERROR,
+ "%s Message %s:%s should contain IE %s, but
doesn't\n",
+ dialect->name, xmc->name,
+ xua_class_msg_name(xmc, msg_type),
+ xua_class_iei_name(xmc, ie->tag));
+ return M3UA_ERR_MISSING_PARAM;
+ }
+ }
+
+ return 0;
+}
+
/* Validate incoming xua_msg. returns 0 on success, M3UA_ERR_* on failure. */
int xua_dialect_check_all_ies(const struct xua_dialect *dialect, const struct
xua_msg *xua)
{
@@ -542,7 +583,6 @@
uint8_t msg_type = xua->hdr.msg_type;
const struct xua_msg_class *xmc = dialect->class[msg_class];
const struct xua_msg_part_class *ies;
- const struct xua_msg_part_class *ie;
/* unknown class? */
if (!xmc)
@@ -553,32 +593,7 @@
if (!ies)
return 0;
- for (ie = ies; ie->tag; ie = ies++) {
- struct xua_msg_part *part = xua_msg_find_tag(xua, ie->tag);
- if (!part) {
- if (!ie->mandatory)
- continue;
- LOGP(dialect->log_subsys, LOGL_ERROR,
- "%s Message %s:%s should contain IE %s, but
doesn't\n",
- dialect->name, xmc->name,
- xua_class_msg_name(xmc, msg_type),
- xua_class_iei_name(xmc, ie->tag));
- return M3UA_ERR_MISSING_PARAM;
- }
-
- if (part->len < ie->len_min || part->len > ie->len_max) {
- LOGP(dialect->log_subsys, LOGL_ERROR,
- "%s Message %s:%s IE %s length %" PRIu16
- " out of range [%" PRIu16 ", %" PRIu16 "]\n",
- dialect->name, xmc->name,
- xua_class_msg_name(xmc, msg_type),
- xua_class_iei_name(xmc, ie->tag),
- part->len, ie->len_min, ie->len_max);
- return M3UA_ERR_PARAM_FIELD_ERR;
- }
- }
-
- return 0;
+ return xua_dialect_check_all_ies_ext(dialect, xmc, msg_type, ies, xua,
false);
}
char *xua_msg_dump(const struct xua_msg *xua, const struct xua_dialect
*dialect)
diff --git a/src/xua_msg.h b/src/xua_msg.h
index 3070435..6e36a7b 100644
--- a/src/xua_msg.h
+++ b/src/xua_msg.h
@@ -126,6 +126,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, bool
repeated_parts);
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..6f2efc2 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, true);
+ 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, false);
+ 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, false);
+ 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 https://gerrit.osmocom.org/c/libosmo-sigtran/+/43394?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: Ibe7e446b1a537c0c09f8049add3460e37cdd58e8
Gerrit-Change-Number: 43394
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>