File U_xkb-Fix-heap-overflow-caused-by-optimized-away-min.patch of Package xorg-x11-server.28361
Git-commit: ba1e6eaea84b73e6ccd5f73acb93110eadb1a640
Author: Michal Srb <msrb@suse.com>
Subject: xkb: Fix heap overflow caused by optimized away min.
Patch-mainline: Upstream
References: boo#1099113
Calling strlen on char[4] that does not need to contain '\0' is wrong and X
server may end up running into invalid memory.
In addition GCC 8 is clever enough that it knows that strlen on char[4] can
return 0, 1, 2, 3 or cause undefined behavior. With this knowledge it can
optimize away the min(..., 4). When the undefined behavior happens, any long
value can be passed as size to the memcpy which will overflow the destination
buffer.
Fixes: 83913de25d35 (xkb: Silence some compiler warnings)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86259
---
xkb/XKBGAlloc.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/xkb/XKBGAlloc.c b/xkb/XKBGAlloc.c
index 8958b0c52..f0cda24fe 100644
--- a/xkb/XKBGAlloc.c
+++ b/xkb/XKBGAlloc.c
@@ -588,8 +588,7 @@ XkbAddGeomKeyAlias(XkbGeometryPtr geom, char *aliasStr, char *realStr)
i++, alias++) {
if (strncmp(alias->alias, aliasStr, XkbKeyNameLength) == 0) {
memset(alias->real, 0, XkbKeyNameLength);
- memcpy(alias->real, realStr,
- min(XkbKeyNameLength, strlen(realStr)));
+ memcpy(alias->real, realStr, strnlen(realStr, XkbKeyNameLength));
return alias;
}
}
@@ -599,8 +598,8 @@ XkbAddGeomKeyAlias(XkbGeometryPtr geom, char *aliasStr, char *realStr)
}
alias = &geom->key_aliases[geom->num_key_aliases];
memset(alias, 0, sizeof(XkbKeyAliasRec));
- memcpy(alias->alias, aliasStr, min(XkbKeyNameLength, strlen(aliasStr)));
- memcpy(alias->real, realStr, min(XkbKeyNameLength, strlen(realStr)));
+ memcpy(alias->alias, aliasStr, strnlen(aliasStr, XkbKeyNameLength));
+ memcpy(alias->real, realStr, strnlen(realStr, XkbKeyNameLength));
geom->num_key_aliases++;
return alias;
}
@@ -815,8 +814,8 @@ XkbAddGeomOverlayKey(XkbOverlayPtr overlay,
(_XkbAllocOverlayKeys(row, 1) != Success))
return NULL;
key = &row->keys[row->num_keys];
- memcpy(key->under.name, under, min(XkbKeyNameLength, strlen(under)));
- memcpy(key->over.name, over, min(XkbKeyNameLength, strlen(over)));
+ memcpy(key->under.name, under, strnlen(under, XkbKeyNameLength));
+ memcpy(key->over.name, over, strnlen(over, XkbKeyNameLength));
row->num_keys++;
return key;
}
--
2.13.6