From 3ae18d4bd71a6c1c446fa1e857d72acbef6853b8 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 20 Mar 2021 16:25:50 +0200 Subject: [PATCH] EAP-SIM/AKA: Fix check for anonymous decorated identity eap_sim_anonymous_username() gets called with an argument that is not a null terminated C string and as such, os_strrchr() and os_strlen() cannot be used with it. The previous implementation resulted in use of uninitialized values and a potential read beyond the end of the buffer. Credit to OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32277 Fixes: 73d9891bd722 ("EAP-SIM/AKA peer: Support decorated anonymous identity prefix") Signed-off-by: Jouni Malinen --- src/eap_common/eap_sim_common.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c index 7f82fdd2e..ab9bd8677 100644 --- a/src/eap_common/eap_sim_common.c +++ b/src/eap_common/eap_sim_common.c @@ -1210,10 +1210,24 @@ void eap_sim_report_notification(void *msg_ctx, int notification, int aka) } +static const u8 * get_last_char(const u8 *val, size_t len, char c) +{ + while (len > 0) { + const u8 *pos = &val[len - 1]; + + if (*pos == (u8) c) + return pos; + len--; + } + + return NULL; +} + + int eap_sim_anonymous_username(const u8 *id, size_t id_len) { static const char *anonymous_id_prefix = "anonymous@"; - const char *decorated; + const u8 *decorated; size_t anonymous_id_len = os_strlen(anonymous_id_prefix); if (id_len > anonymous_id_len && @@ -1229,11 +1243,11 @@ int eap_sim_anonymous_username(const u8 *id, size_t id_len) /* RFC 7542 decorated username, for example: * homerealm.example.org!anonymous@otherrealm.example.net */ - decorated = os_strrchr((const char *) id, '!'); + decorated = get_last_char(id, id_len, '!'); if (decorated) { decorated++; - return eap_sim_anonymous_username((const u8 *) decorated, - os_strlen(decorated)); + return eap_sim_anonymous_username(decorated, + id + id_len - decorated); } return 0;