From 9fbb6008e0b50e5e531d448492e2d05d0cf5adf0 Mon Sep 17 00:00:00 2001 From: Stefan Sperling Date: Mon, 25 Jun 2018 17:31:59 +0200 Subject: VLR: reject overlong IMSIs in ID RESP messages Overlong IMSIs in ID RESP messages were accepted and used in truncated form. Log an error when truncation occurs, and prevent truncated IMSIs from being installed for a subscriber via ID RESP messages. Other code paths leading to vlr_subscr_set_imsi() with truncated IMSIs will only a leave a trail of log entries for now, because vlr_subscr_set_imsi() is currently unable to return an error code. Change-Id: I785c994f41a646d8d83d3d82f5a9ae6b572eb641 Related: OS#2864 --- src/libvlr/vlr.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index 29098b15b..cff2e1204 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -396,7 +396,13 @@ void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi) { if (!vsub) return; - OSMO_STRLCPY_ARRAY(vsub->imsi, imsi); + + if (OSMO_STRLCPY_ARRAY(vsub->imsi, imsi) >= sizeof(vsub->imsi)) { + LOGP(DVLR, LOGL_NOTICE, "IMSI was truncated: full IMSI=%s, truncated IMSI=%s\n", + imsi, vsub->imsi); + /* XXX Set truncated IMSI anyway, we currently cannot return an error from here. */ + } + vsub->id = atoll(vsub->imsi); DEBUGP(DVLR, "set IMSI on subscriber; IMSI=%s id=%llu\n", vsub->imsi, vsub->id); @@ -1062,10 +1068,15 @@ int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, /* update the vlr_subscr with the given identity */ switch (mi_type) { case GSM_MI_TYPE_IMSI: - if (vsub->imsi[0] + if (strlen(mi_string) >= sizeof(vsub->imsi)) { + LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP too long (>%zu bytes): %s\n", + sizeof(vsub->imsi) - 1, mi_string); + return -ENOSPC; /* ignore message; do not avance LU FSM */ + } else if (vsub->imsi[0] && !vlr_subscr_matches_imsi(vsub, mi_string)) { LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:" " %s\n", mi_string); + /* XXX Should we return an error, e.g. -EINVAL ? */ } else vlr_subscr_set_imsi(vsub, mi_string); break; -- cgit v1.2.3