diff --git a/fuzz/README.md b/fuzz/README.md index a4b4f90a..f2812e11 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -7,7 +7,39 @@ So far the backend and cli can be fuzzed. Some issues are as follows: - Static linking. Fuzzing requires static linking. You can statically link clixon using: `LINKAGE=static ./configure` but that does not work with Clixon plugins (at least yet). Therefore fuzzing has been made with no plugins using the hello example only. - Multiple processes. Only the backend can run stand-alone, cli/netconf/restconf requires a backend. When you fuzz eg clixon_cli, the backend must be running and it will be slow due to IPC. Possibly one could link them together and run as a monolith by making a threaded image. -- Internal protocol 1: The internal protocol uses XML but deviates from netconf by using a (binary) header where the length is encoded, instead of ']]>]]>' as a terminating string. AFL does not like that. By setting CLIXON_PROTO_PLAIN the internal protocol uses pure netconf (with some limitations). -- Internal protocol 2: The internal protocol uses TCP unix sockets while AFL requires stdio. One can use a package called "preeny" to translate stdio into sockets. But it is slow. -Restconf also has the extra problem of running TLS sockets. \ No newline at end of file +Restconf also has the extra problem of running TLS sockets. + +## Prereqs + +See [AFL docs](https://afl-1.readthedocs.io/en/latest) for installing afl. +On ubuntu this may be enough: +``` + sudo apt install afl +``` + +You may have to change cpu frequency: +``` + cd /sys/devices/system/cpu + echo performance | tee cpu?/cpufreq/scaling_governor +``` + +And possibly change core behaviour: +``` + echo core >/proc/sys/kernel/core_pattern +``` + +### backend/restconf + +Backend and restconf requires the preeny package to change sockets to stdio. + +Preeny has a "desocketizing" module necessary to map stdio to the internal sockets that the backend uses. Install preeny example: +``` + sudo apt install libini-config-dev # debian/ubuntu + sudo apt install libseccomp-dev # debian/ubuntu + git clone https://github.com/zardus/preeny.git + cd preeny + make + sudo cp x86_64-linux-gnu/desock.so /usr/local/lib/ # install +``` + diff --git a/fuzz/backend/README.md b/fuzz/backend/README.md index e9d16aed..65a32524 100644 --- a/fuzz/backend/README.md +++ b/fuzz/backend/README.md @@ -1,6 +1,6 @@ # Clixon fuzzing -This dir contains code for fuzzing clixon backend. +This dir contains code for fuzzing clixon backend. (NOTE DOES NOT WORK) It requires the preeny package to change sockets to stdio. @@ -8,32 +8,7 @@ Plugins do not work ## Prereqs -Preeny has a "desocketizing" module necessary to map stdio to the internal sockets that the backend uses. Install preeny example: -``` - sudo apt install libini-config-dev # debian/ubuntu - sudo apt install libseccomp-dev # debian/ubuntu - git clone https://github.com/zardus/preeny.git - cd preeny - make - sudo cp x86_64-linux-gnu/desock.so /usr/local/lib/ # install -``` - -See [AFL docs](https://afl-1.readthedocs.io/en/latest) for installing afl. -On ubuntu this may be enough: -``` - sudo apt install afl -``` - -You may have to change cpu frequency: -``` - cd /sys/devices/system/cpu - echo performance | tee cpu?/cpufreq/scaling_governor -``` - -And possibly change core behaviour: -``` - echo core >/proc/sys/kernel/core_pattern -``` +Install AFL and preeny, see [..](..) ## Build diff --git a/fuzz/cli/README.md b/fuzz/cli/README.md index c6d6998d..ada92cb6 100644 --- a/fuzz/cli/README.md +++ b/fuzz/cli/README.md @@ -6,28 +6,15 @@ Note: cli plugins do not work. ## Prereqs -See [AFL docs](https://afl-1.readthedocs.io/en/latest) for installing afl. -On ubuntu this may be enough: -``` - sudo apt install afl -``` +Install AFL, see [..](..) -You may have to change cpu frequency: -``` - cd /sys/devices/system/cpu - echo performance | tee cpu?/cpufreq/scaling_governor -``` - -And possibly change core behaviour: -``` - echo core >/proc/sys/kernel/core_pattern -``` +Build and install a clixon system (in particular the backend, the CLI will be replaced) ## Build -Build clixon statically with the afl-clang compiler: +Build clixon cli statically with the afl-clang compiler: ``` - CC=/usr/bin/afl-clang-fast LINKAGE=static ./configure + CC=/usr/bin/afl-clang-fast LINKAGE=static ./configure # Dont care about restconf make clean cd apps/cli make clixon_cli @@ -36,9 +23,9 @@ Build clixon statically with the afl-clang compiler: ## Run tests -Start the backend and Use the script `runfuzz.sh` to run one test with a cli spec and an input string, eg: +Run the script `runfuzz.sh` to run one test with a cli spec and an input string, eg: ``` - ./runfuzz.sh /usr/local/etc/hello.xml "set table parameter a value 23" + ./runfuzz.sh ``` After (or during) the test, investigate results in the output dir. diff --git a/fuzz/cli/runfuzz.sh b/fuzz/cli/runfuzz.sh index f9a41d56..a67d7320 100755 --- a/fuzz/cli/runfuzz.sh +++ b/fuzz/cli/runfuzz.sh @@ -15,18 +15,23 @@ cat < $cfg $cfg *:* /usr/local/share/clixon - clixon-hello - hello - /usr/local/var/hello.sock - /usr/local/lib/hello/clispec + clixon-example + /usr/local/var/example/example.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME init false + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + 1 + VARS + clixon-restconf + 0 + 0 EOF -#cfg=/usr/local/etc/hello.xml # XXX # Kill previous sudo clixon_backend -z -f $cfg -s init diff --git a/fuzz/restconf/README.md b/fuzz/restconf/README.md new file mode 100644 index 00000000..fab6d0ab --- /dev/null +++ b/fuzz/restconf/README.md @@ -0,0 +1,31 @@ +# Clixon fuzzing + +This dir contains code for fuzzing clixon restconf + +It requires the preeny package to change sockets to stdio. + +## Prereqs + +Install AFL and preeny, see [..](..) + +Build and install a clixon system (in particular the backend, RESTCONF binary will be replaced) + +## Build + +Build clixon restconf statically with the afl-clang compiler: +``` + CC=/usr/bin/afl-clang-fast LINKAGE=static ./configure --with-restconf=native + make clean + cd apps/restconf + make clixon_restconf + sudo make install +``` + +## Run tests + +Use the script `runfuzz.sh` to run one test: +``` + ./runfuzz.sh +``` + +After (or during) the test, investigate results in the output dir. diff --git a/fuzz/restconf/input/1.http b/fuzz/restconf/input/1.http new file mode 100644 index 00000000..2e0183fe --- /dev/null +++ b/fuzz/restconf/input/1.http @@ -0,0 +1,5 @@ +GET /.well-known/host-meta HTTP/1.1 +Host: localhost +Accept: application/yang-data+xml + + diff --git a/fuzz/restconf/input/2.http b/fuzz/restconf/input/2.http new file mode 100644 index 00000000..9bb0ee9b --- /dev/null +++ b/fuzz/restconf/input/2.http @@ -0,0 +1,10 @@ +PUT /restconf/data/ietf-interfaces:interfaces/interface=eth%2f0%2f0 HTTP/1.1 +Host: 127.0.0.1 +Accept: */* +Content-Type: application/yang-data+json +Content-Length: 91 + +{"ietf-interfaces:interface":{"name":"eth/0/0","type":"clixon-example:eth","enabled":true}} + + + diff --git a/fuzz/restconf/input/3.http b/fuzz/restconf/input/3.http new file mode 100644 index 00000000..5293183a --- /dev/null +++ b/fuzz/restconf/input/3.http @@ -0,0 +1,5 @@ +GET /restconf/data/ HTTP/1.1 +Host: localhost +Accept: application/yang-data+xml + + diff --git a/fuzz/restconf/runfuzz.sh b/fuzz/restconf/runfuzz.sh new file mode 100755 index 00000000..6602434a --- /dev/null +++ b/fuzz/restconf/runfuzz.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# Run a fuzzing test using american fuzzy lop +# Add input strings in input +set -eux + +if [ $# -ne 0 ]; then + echo "usage: $0" + exit 255 +fi + +if [ ! -x /usr/local/lib/desock.so ] ; then + echo "preeny desock.so not found" + exit 255 +fi + +MEGS=500 # memory limit for child process (50 MB) + +# remove input and input dirs +#test ! -d input || rm -rf input +test ! -d output || sudo rm -rf output + +# create if dirs dont exists +#test -d input || mkdir input +test -d output || mkdir output + +APPNAME=example +cfg=conf.xml + +cat < $cfg + + $cfg + *:* + /usr/local/share/clixon + clixon-example + /usr/local/var/hello.sock + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.pidfile + /usr/local/var/$APPNAME + init + false + truenonedefault
0.0.0.0
80false
+
+EOF + +# Kill previous +echo "cfg: $cfg" +sudo clixon_backend -z -f $cfg -s init + +# Start backend +sudo clixon_backend -f $cfg -s init + +# Run script +# CC=/usr/bin/afl-clang +sudo LD_PRELOAD="/usr/local/lib/desock.so" afl-fuzz -i input -o output -d -m $MEGS -- /usr/local/sbin/clixon_restconf -rf $cfg + +# Dryrun without afl: +#echo "sudo LD_PRELOAD=\"/usr/local/lib/desock.so\" +#sudo LD_PRELOAD="/usr/local/lib/desock.so" clixon_restconf -rf $cfg < input/1.http diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index 0e8361a6..aa2bcc3b 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -95,12 +95,12 @@ static const map_str2int cli_genmodel_map[] = { /* Mapping between Clicon startup modes string <--> constants, see clixon-config.yang type startup_mode */ static const map_str2int startup_mode_map[] = { - {"none", SM_NONE}, - {"init", SM_INIT}, - {"running", SM_RUNNING}, - {"startup", SM_STARTUP}, - {"startup", SM_RUNNING_STARTUP}, - {NULL, -1} + {"none", SM_NONE}, + {"init", SM_INIT}, + {"running", SM_RUNNING}, + {"startup", SM_STARTUP}, + {"running-startup", SM_RUNNING_STARTUP}, + {NULL, -1} }; /* Mapping between Clicon privileges modes string <--> constants, diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 81077079..517f5432 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -373,7 +373,7 @@ clicon_msg_rcv(int s, int retval = -1; struct clicon_msg hdr; int hlen; - uint32_t len2; + ssize_t len2; sigfn_t oldhandler; uint32_t mlen; @@ -638,7 +638,7 @@ clicon_rpc(int sock, return retval; } -/*! Send a netconf message and recevive result. +/*! Send a netconf message and recieve result. * * TBD: timeout, interrupt? * retval may be -1 and