This shows you the differences between two versions of the page.
ep:labs:03:contents:tasks:ex5 [2021/10/23 00:50] radu.mantu |
ep:labs:03:contents:tasks:ex5 [2022/10/24 00:11] (current) andrei.mirciu [03. [30p] RAM disk] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ==== 03. [30p] perf ==== | + | ==== 03. [30p] RAM disk ==== |
- | The purpose of this exercise is to identify where bottlenecks appear in a program. For this we will use perf and American Fuzzy Lop (AFL). | + | Linux allows you to use part of your RAM as a block device, viewing it as a hard disk partition. The advantage of using a RAM disk is the **extremely low latency** (even when compared to SSDs). The disadvantage is that all contents will be lost after a reboot. |
<note tip> | <note tip> | ||
- | Perf is a linux performance analysis tool that we will use to analyze what events occur when running a program. | + | There are two main types of RAM disks: |
- | + | * **ramfs** - cannot be limited in size and will continue to grow until you run out of RAM. Its size can not be determined precisely with tools like **df**. Instead, you have to estimate it by looking at the "cached" entry from **free**'s output. | |
- | AFL is a fuzzing tool from google. Fuzzers are used to test programs and applications, using as input all kinds of random data, valid or invalid to map the behavior of the program. To this end, monitoring where and in which area of the program crashes or errors occur. Valid input data is altered little by little, in order to discover as many branches as possible for the given the program. | + | * **tmpfs** - newer than **ramfs**. Can set a size limit. Behaves exactly like a hard disk partition but can't be monitored through conventional means (i.e. **iostat**). Size can be precisely estimated using **df**. |
</note> | </note> | ||
- | === [5p] Task A - Install Prerequisites and AFL === | + | === [15p] Task A - Create RAM Disk === |
- | <note> | + | Before getting started, let's find out the file system that our root partition uses. Run the following command (T - print file system type, h - human readable): |
- | Before getting started, install and download all the needed tools. | + | |
<code bash> | <code bash> | ||
- | $ sudo apt-get update | + | $ df -Th |
- | $ sudo apt-get install clang llvm | + | |
</code> | </code> | ||
- | </note> | + | The result should look like this: |
- | + | <code> | |
- | <code bash> | + | Filesystem Type Size Used Avail Use% Mounted on |
- | $ git clone https://github.com/google/AFL | + | udev devtmpfs 1.1G 0 1.1G 0% /dev |
- | $ cd AFL | + | tmpfs tmpfs 214M 3.8M 210M 2% /run |
- | $ cd llvm_mode && make && cd .. | + | /dev/sda1 ext4 218G 4.1G 202G 2% / <- root partition |
- | $ cd libdislocator && make && sudo cp libdislocator.so /usr/local/lib/ && cd .. | + | tmpfs tmpfs 1.1G 252K 1.1G 1% /dev/shm |
- | $ sudo make install | + | tmpfs tmpfs 5.0M 4.0K 5.0M 1% /run/lock |
+ | tmpfs tmpfs 1.1G 0 1.1G 0% /sys/fs/cgroup | ||
+ | /dev/sda2 ext4 923M 73M 787M 9% /boot | ||
+ | /dev/sda4 ext4 266G 62M 253G 1% /home | ||
</code> | </code> | ||
- | === [10p] Task B - Fuzzing a program === | + | From the results, we will assume in the following commands that the file system is **ext4**. If it's not your case, just replace with what you have: |
- | + | ||
- | The target program will be fuzzgoat, a vulnerable program made to be an example for fuzzing. To prepare the program for fuzzing, the source code has to be compiled with the appropriate compiler offerd by AFL: | + | |
<code bash> | <code bash> | ||
- | $ git clone https://github.com/fuzzstati0n/fuzzgoat.git | + | $ sudo mkdir /mnt/ramdisk |
- | $ cd fuzzgoat | + | $ sudo mount -t tmpfs -o size=1G ext4 /mnt/ramdisk |
- | $ export CC=afl-clang-fast | + | |
- | $ make # creates the fuzzable executable | + | |
</code> | </code> | ||
<note> | <note> | ||
- | <code bash> | + | If you want the RAM disk to persist after a reboot, you can add the following line to ///etc/fstab//. Remember that its contents will still be lost. |
- | afl-fuzz -i <input directory> -o <output directory> -- <path to program> @@ | + | |
+ | <code> | ||
+ | tmpfs /mnt/ramdisk tmpfs rw,nodev,nosuid,size=1G 0 0 | ||
</code> | </code> | ||
</note> | </note> | ||
- | <code bash> | + | That's it. We just created a 1Gb **tmpfs** ramdisk with an **ext4** file system and mounted it at ///mnt/ramdisk//. Use **df** again to check this yourself. |
- | $ mkdir afl_out | + | |
- | $ afl-fuzz -i in -o afl_out -- ./fuzzgoat/fuzzgoat @@ | + | === [15p] Task B - Pipe View & RAM Disk === |
- | </code> | + | |
+ | As we mentioned before, you can't get I/O statistics regarding **tmpfs** since it is not a real partition. One solution to this problem is using **pv** to monitor the progress of data transfer through a pipe. This is a valid approach only if we consider the disk I/O being the bottleneck. | ||
+ | |||
+ | Next, we will generate 512Mb of random data and place it in ///mnt/ramdisk/file// first and then in ///home/student/file//. The transfer is done using **dd** with 2048-byte blocks. | ||
- | === [15p] Task C - Run perf over it === | ||
- | <note> | ||
- | We will analyze the fuzzing by recording the cpu cycles as main event with perf. | ||
<code bash> | <code bash> | ||
- | $ perf record -e <event> <command recorded> | + | $ pv /dev/urandom | dd of=/mnt/ramdisk/rand bs=2048 count=$((512 * 1024 * 1024 / 2048)) |
+ | $ pv /dev/urandom | dd of=/home/student/rand bs=2048 count=$((512 * 1024 * 1024 / 2048)) | ||
</code> | </code> | ||
- | </note> | ||
- | <code bash> | ||
- | $ perf record -e cycles afl-fuzz -i ./fuzzgoat/in -o afl_out -- ./fuzzgoat/fuzzgoat @@ #and let it run for a few minutes | ||
- | $ perf report #to print the recorded info | ||
- | </code> | ||
- | |||
- | As a result you should get a report showing a list of the most used functions. | ||
- | :!: Make sure to add a ss of it. | ||
- | |||
+ | Look at the elapsed time and average transfer speed. What conclusion can you draw? | ||
+ | :!: Put one screenshot with the tmpfs partition in df output and one screenshot of both pv commands and write your conclusion. | ||