- Fuzz for restconf and cli updated

This commit is contained in:
Olof hagsand 2021-05-27 20:39:49 +02:00
parent 965cce5e5d
commit af88b974fd
11 changed files with 172 additions and 62 deletions

View file

@ -7,7 +7,39 @@ So far the backend and cli can be fuzzed.
Some issues are as follows: 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. - 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. - 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. 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
```

View file

@ -1,6 +1,6 @@
# Clixon fuzzing # 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. It requires the preeny package to change sockets to stdio.
@ -8,32 +8,7 @@ Plugins do not work
## Prereqs ## Prereqs
Preeny has a "desocketizing" module necessary to map stdio to the internal sockets that the backend uses. Install preeny example: Install AFL and preeny, see [..](..)
```
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
```
## Build ## Build

View file

@ -6,28 +6,15 @@ Note: cli plugins do not work.
## Prereqs ## Prereqs
See [AFL docs](https://afl-1.readthedocs.io/en/latest) for installing afl. Install AFL, see [..](..)
On ubuntu this may be enough:
```
sudo apt install afl
```
You may have to change cpu frequency: Build and install a clixon system (in particular the backend, the CLI will be replaced)
```
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 ## 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 make clean
cd apps/cli cd apps/cli
make clixon_cli make clixon_cli
@ -36,9 +23,9 @@ Build clixon statically with the afl-clang compiler:
## Run tests ## 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. After (or during) the test, investigate results in the output dir.

View file

@ -15,18 +15,23 @@ cat <<EOF > $cfg
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE> <CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_FEATURE>*:*</CLICON_FEATURE> <CLICON_FEATURE>*:*</CLICON_FEATURE>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR> <CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>clixon-hello</CLICON_YANG_MODULE_MAIN> <CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
<CLICON_CLI_MODE>hello</CLICON_CLI_MODE> <CLICON_SOCK>/usr/local/var/example/example.sock</CLICON_SOCK>
<CLICON_SOCK>/usr/local/var/hello.sock</CLICON_SOCK>
<CLICON_CLISPEC_DIR>/usr/local/lib/hello/clispec</CLICON_CLISPEC_DIR>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE> <CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR> <CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_STARTUP_MODE>init</CLICON_STARTUP_MODE> <CLICON_STARTUP_MODE>init</CLICON_STARTUP_MODE>
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895> <CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
<CLICON_CLI_GENMODEL_TYPE>VARS</CLICON_CLI_GENMODEL_TYPE>
<CLICON_CLI_AUTOCLI_EXCLUDE>clixon-restconf</CLICON_CLI_AUTOCLI_EXCLUDE>
<CLICON_CLI_LINESCROLLING>0</CLICON_CLI_LINESCROLLING>
<CLICON_CLI_TAB_MODE>0</CLICON_CLI_TAB_MODE>
</clixon-config> </clixon-config>
EOF EOF
#cfg=/usr/local/etc/hello.xml # XXX
# Kill previous # Kill previous
sudo clixon_backend -z -f $cfg -s init sudo clixon_backend -z -f $cfg -s init

31
fuzz/restconf/README.md Normal file
View file

@ -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.

View file

@ -0,0 +1,5 @@
GET /.well-known/host-meta HTTP/1.1
Host: localhost
Accept: application/yang-data+xml

View file

@ -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}}

View file

@ -0,0 +1,5 @@
GET /restconf/data/ HTTP/1.1
Host: localhost
Accept: application/yang-data+xml

60
fuzz/restconf/runfuzz.sh Executable file
View file

@ -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 <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config">
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
<CLICON_FEATURE>*:*</CLICON_FEATURE>
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
<CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
<CLICON_SOCK>/usr/local/var/hello.sock</CLICON_SOCK>
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
<CLICON_STARTUP_MODE>init</CLICON_STARTUP_MODE>
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
<restconf><enable>true</enable><auth-type>none</auth-type><socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket></restconf>
</clixon-config>
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

View file

@ -99,7 +99,7 @@ static const map_str2int startup_mode_map[] = {
{"init", SM_INIT}, {"init", SM_INIT},
{"running", SM_RUNNING}, {"running", SM_RUNNING},
{"startup", SM_STARTUP}, {"startup", SM_STARTUP},
{"startup", SM_RUNNING_STARTUP}, {"running-startup", SM_RUNNING_STARTUP},
{NULL, -1} {NULL, -1}
}; };

View file

@ -373,7 +373,7 @@ clicon_msg_rcv(int s,
int retval = -1; int retval = -1;
struct clicon_msg hdr; struct clicon_msg hdr;
int hlen; int hlen;
uint32_t len2; ssize_t len2;
sigfn_t oldhandler; sigfn_t oldhandler;
uint32_t mlen; uint32_t mlen;
@ -638,7 +638,7 @@ clicon_rpc(int sock,
return retval; return retval;
} }
/*! Send a netconf message and recevive result. /*! Send a netconf message and recieve result.
* *
* TBD: timeout, interrupt? * TBD: timeout, interrupt?
* retval may be -1 and * retval may be -1 and