CVE-2018-15855: NULL Pointer Dereference (CWE-476)
value: Unchecked NULL pointer usage in xkbcommon before 0.8.1 could be used by local attackers to crash (NULL pointer dereference) the xkbcommon parser by supplying a crafted keymap file, because the XkbFile for an xkb_geometry section was mishandled.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2018-08-25T21:29Z
Repository: https://github.com/xkbcommon/libxkbcommon
Language: C
Files changed: src/xkbcomp/keymap.c, src/xkbcomp/parser.y
Commit date: 2018-07-30 10:35:10 +0300
Commit message: xkbcomp: fix crash when parsing an xkb_geometry section

xkb_geometry sections are ignored; previously the had done so by
returning NULL for the section's XkbFile, however some sections of the
code do not expect this. Instead, create an XkbFile for it, it will
never be processes and discarded later.

Caught with the afl fuzzer.

Signed-off-by: Ran Benita <ran234@gmail.com>

Diff: diff --git a/src/xkbcomp/keymap.c b/src/xkbcomp/keymap.c
index 45098c24..e95e50c3 100644
--- a/src/xkbcomp/keymap.c
+++ b/src/xkbcomp/keymap.c
@@ -239,12 +239,17 @@ CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
     /* Collect section files and check for duplicates. */
     for (file = (XkbFile *) file->defs; file;
          file = (XkbFile *) file->common.next) {
         if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
             file->file_type > LAST_KEYMAP_FILE_TYPE) {
-            log_err(ctx, "Cannot define %s in a keymap file\n",
-                    xkb_file_type_to_string(file->file_type));
+            if (file->file_type == FILE_TYPE_GEOMETRY) {
+                log_vrb(ctx, 1,
+                        "Geometry sections are not supported; ignoring\n");
+            } else {
+                log_err(ctx, "Cannot define %s in a keymap file\n",
+                        xkb_file_type_to_string(file->file_type));
+            }
             continue;
         }
 
         if (files[file->file_type]) {
             log_err(ctx,
diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y
index d15d24b3..b555bc25 100644
--- a/src/xkbcomp/parser.y
+++ b/src/xkbcomp/parser.y
@@ -271,18 +271,11 @@ XkbMapConfigList :      XkbMapConfigList XkbMapConfig
 
 XkbMapConfig    :       OptFlags FileType OptMapName OBRACE
                             DeclList
                         CBRACE SEMI
                         {
-                            if ($2 == FILE_TYPE_GEOMETRY) {
-                                free($3);
-                                FreeStmt($5);
-                                $$ = NULL;
-                            }
-                            else {
-                                $$ = XkbFileCreate($2, $3, $5, $1);
-                            }
+                            $$ = XkbFileCreate($2, $3, $5, $1);
                         }
                 ;
 
 FileType        :       XKB_KEYCODES            { $$ = FILE_TYPE_KEYCODES; }
                 |       XKB_TYPES               { $$ = FILE_TYPE_TYPES; }

Vulnerable code:             log_err(ctx, "Cannot define %s in a keymap file\n",
                    xkb_file_type_to_string(file->file_type));
                            if ($2 == FILE_TYPE_GEOMETRY) {
                                free($3);
                                FreeStmt($5);
                                $$ = NULL;
                            }
                            else {
                                $$ = XkbFileCreate($2, $3, $5, $1);
                            }
Fixed code:             if (file->file_type == FILE_TYPE_GEOMETRY) {
                log_vrb(ctx, 1,
                        "Geometry sections are not supported; ignoring\n");
            } else {
                log_err(ctx, "Cannot define %s in a keymap file\n",
                        xkb_file_type_to_string(file->file_type));
            }
                            $$ = XkbFileCreate($2, $3, $5, $1);