Add fuzzing infrastructure
Though text formats aren't exactly fuzzer's strong suit, fuzzers can catch many surface-level bugs. The fuzz/ directory contains target programs, testcases and dictionaries to drive the afl fuzzer. This commit adds a fuzzer for the XKB keymap text format and the Compose text format. On my slow machine, using a single core, a full cycle of the XKB fuzzer takes 5 hours. For Compose, it takes a few minutes. Fuzzing for the other file formats (rules files mostly) will be added later. To do some fuzzing, run `./fuzz/fuzz.sh`. Signed-off-by: Ran Benita <ran234@gmail.com>master
parent
a54cfe087a
commit
2cb5c2a3f3
|
@ -0,0 +1 @@
|
|||
findings/
|
|
@ -0,0 +1,8 @@
|
|||
"Ctrl"
|
||||
"Lock"
|
||||
"Caps"
|
||||
"Shift"
|
||||
"Alt"
|
||||
"Meta"
|
||||
"None"
|
||||
"acute"
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* A target program for fuzzing the Compose text format.
|
||||
*
|
||||
* Currently, just parses an input file, and hopefully doesn't crash or hang.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "xkbcommon/xkbcommon-compose.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
FILE *file;
|
||||
struct xkb_compose_table *table;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES | XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
assert(ctx);
|
||||
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
|
||||
while (__AFL_LOOP(1000))
|
||||
#endif
|
||||
{
|
||||
file = fopen(argv[1], "r");
|
||||
assert(file);
|
||||
table = xkb_compose_table_new_from_file(ctx, file,
|
||||
"en_US.UTF-8",
|
||||
XKB_COMPOSE_FORMAT_TEXT_V1,
|
||||
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
xkb_compose_table_unref(table);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
puts(table ? "OK" : "FAIL");
|
||||
xkb_context_unref(ctx);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<dead_tilde> <space> : "~" asciitilde # X
|
||||
Meta <Multi_key> !Alt ~Shift <apostrophe> <apostrophe> : "\"\'\x43\123abc" acute # Y
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
keymap|compose)
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 keymap|compose" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
export CC=afl-clang-fast
|
||||
export AFL_HARDEN=1
|
||||
test -d fuzz/build || meson setup -Db_lto=true fuzz/build
|
||||
ninja -C fuzz/build
|
||||
afl-fuzz -i fuzz/$1/testcases -x fuzz/$1/dict -o fuzz/$1/findings -t 200 -m 10 -- ./fuzz/build/fuzz-$1 @@
|
|
@ -0,0 +1,120 @@
|
|||
"Control"
|
||||
"Group1"
|
||||
"Group5"
|
||||
"Lock"
|
||||
"Mod1"
|
||||
"Mod9"
|
||||
"Shift"
|
||||
"U1"
|
||||
"0x1"
|
||||
"Up"
|
||||
"accel"
|
||||
"action"
|
||||
"actions"
|
||||
"affect"
|
||||
"alias"
|
||||
"all"
|
||||
"allowexplicit"
|
||||
"allownone"
|
||||
"alphanumeric_keys"
|
||||
"alternate"
|
||||
"alternate_group"
|
||||
"any"
|
||||
"augment"
|
||||
"both"
|
||||
"button"
|
||||
"clearLocks"
|
||||
"clearmods"
|
||||
"controls"
|
||||
"count"
|
||||
"ctrls"
|
||||
"data"
|
||||
"default"
|
||||
"dev"
|
||||
"device"
|
||||
"dfltbtn"
|
||||
"driveskbd"
|
||||
"false"
|
||||
"foo"
|
||||
"function_keys"
|
||||
"genKeyEvent"
|
||||
"group"
|
||||
"groupname"
|
||||
"groups"
|
||||
"groupsclamp"
|
||||
"groupsredirect"
|
||||
"groupswrap"
|
||||
"hidden"
|
||||
"include"
|
||||
"increment"
|
||||
"index"
|
||||
"indicator"
|
||||
"indicatordriveskbd"
|
||||
"interpret"
|
||||
"kc"
|
||||
"key"
|
||||
"keycode"
|
||||
"keypad_keys"
|
||||
"keys"
|
||||
"latchToLock"
|
||||
"leddriveskbd"
|
||||
"levelname"
|
||||
"lock"
|
||||
"locking"
|
||||
"logo"
|
||||
"map"
|
||||
"mod_map"
|
||||
"modifier_keys"
|
||||
"modifier_map"
|
||||
"modifiers"
|
||||
"modmap"
|
||||
"modmapmods"
|
||||
"mods"
|
||||
"name"
|
||||
"neither"
|
||||
"no"
|
||||
"none"
|
||||
"nosymbol"
|
||||
"off"
|
||||
"on"
|
||||
"outline"
|
||||
"overlay"
|
||||
"override"
|
||||
"partial"
|
||||
"preserve"
|
||||
"radiogroup"
|
||||
"repeat"
|
||||
"replace"
|
||||
"report"
|
||||
"row"
|
||||
"same"
|
||||
"sameServer"
|
||||
"screen"
|
||||
"section"
|
||||
"shape"
|
||||
"solid"
|
||||
"symbols"
|
||||
"text"
|
||||
"true"
|
||||
"type"
|
||||
"unlock"
|
||||
"usemodmap"
|
||||
"value"
|
||||
"virtual"
|
||||
"virtual_modifiers"
|
||||
"virtualmod"
|
||||
"vmods"
|
||||
"voidsymbol"
|
||||
"whichgroupstate"
|
||||
"whichmodstate"
|
||||
"x"
|
||||
"xkb_compat"
|
||||
"xkb_geometry"
|
||||
"xkb_keycodes"
|
||||
"xkb_keymap"
|
||||
"xkb_layout"
|
||||
"xkb_semantics"
|
||||
"xkb_symbols"
|
||||
"xkb_types"
|
||||
"y"
|
||||
"yes"
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* A target program for fuzzing the XKB keymap text format.
|
||||
*
|
||||
* Currently, just parses an input file, and hopefully doesn't crash or hang.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
FILE *file;
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES | XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
assert(ctx);
|
||||
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
|
||||
while (__AFL_LOOP(1000))
|
||||
#endif
|
||||
{
|
||||
file = fopen(argv[1], "r");
|
||||
assert(file);
|
||||
keymap = xkb_keymap_new_from_file(ctx, file,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_keymap_unref(keymap);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
puts(keymap ? "OK" : "FAIL");
|
||||
xkb_context_unref(ctx);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
xkb_keymap{
|
||||
xkb_keycodes"0"{
|
||||
minimum=0;
|
||||
maximum=500;
|
||||
<a>=0;
|
||||
indicator 1="X";
|
||||
alias<X>=<Y>;
|
||||
};
|
||||
xkb_types"X"{
|
||||
virtual_modifiers NumLock;
|
||||
type"X"{
|
||||
modifiers=Shift;
|
||||
map[Shift]=Level2;
|
||||
level_name[Level1]="X";
|
||||
preserve[Shift]=Shift;
|
||||
};
|
||||
};
|
||||
partial xkb_compat{
|
||||
virtual_modifiers Alt;
|
||||
interpret.useModMapMods=AnyLevel;
|
||||
interpret.repeat=False;
|
||||
interpret.locking=False;
|
||||
interpret ISO_Level2_Latch+Exactly(Shift){
|
||||
repeat=True;
|
||||
virtualModifier=NumLock;
|
||||
useModMapMods=level1;
|
||||
action=LatchMods(modifiers=Shift,clearLocks,latchToLock);
|
||||
action=MovePtr(x=+0,y=-0);
|
||||
action=SwitchScreen(screen=00,!same);
|
||||
action=Private(type=0x80,data[0]=0x00);
|
||||
};
|
||||
indicator"X"{whichModState=locked;modifiers=Lock;};
|
||||
};
|
||||
xkb_symbols{
|
||||
name[group1]="X";
|
||||
key<Y>{type[group2]="X",symbols[Group1]=[0,exclam],symbols[Group2]=[0xff,U00],symbols[Group3]=[z]};
|
||||
modifier_map Control{<a>};
|
||||
};
|
||||
default xkb_geometry"X"{
|
||||
description="X";
|
||||
width=470;
|
||||
shape.cornerRadius=1;
|
||||
shape"NORM"{cornerRadius=0,{[0.0,0]},{[0,0],[0,0.0]}};
|
||||
solid"X"{shape="X";top=00;left=00;color="X";};
|
||||
indicator.onColor="X";
|
||||
indicator.top=00.0;
|
||||
indicator.shape="X";
|
||||
indicator"X"{left=0;};
|
||||
text.top=00;
|
||||
text.color="X";
|
||||
text"X"{left=0;text="X";};
|
||||
section.left=00;
|
||||
row.left=0;
|
||||
key.shape="X";
|
||||
key.gap=1;
|
||||
section"X"{top=22;row{top=1;keys{{<X>,color="X"},{<X>,00.0},<X>,<X>,<X>};};};
|
||||
alias<AC00>=<CAPS>;
|
||||
};
|
||||
};
|
|
@ -383,6 +383,11 @@ if get_option('enable-x11')
|
|||
endif
|
||||
|
||||
|
||||
# Fuzzing target programs.
|
||||
executable('fuzz-keymap', 'fuzz/keymap/target.c', dependencies: test_dep)
|
||||
executable('fuzz-compose', 'fuzz/compose/target.c', dependencies: test_dep)
|
||||
|
||||
|
||||
# Demo programs.
|
||||
executable('rmlvo-to-kccgst', 'test/rmlvo-to-kccgst.c', dependencies: test_dep)
|
||||
executable('print-compiled-keymap', 'test/print-compiled-keymap.c', dependencies: test_dep)
|
||||
|
|
Loading…
Reference in New Issue