Can syzkaller test kernel modules?

1,155 views
Skip to first unread message

An Lee

unread,
Dec 22, 2016, 3:47:24 AM12/22/16
to syzkaller
Hi,

    I am an embedded linux kernel driver developer, and what I want to test most is some driver

    I know enable_syscalls limit the list of syscalls, but that's still too much
  
  So how can I test a specific kernel module? 

  Thanks!
   





Dmitry Vyukov

unread,
Dec 22, 2016, 3:57:38 AM12/22/16
to syzkaller
Hello An,

Why enable_syscalls does not work for your case? What exactly do you
mean by "test a specific kernel module"? I mean what exactly would you
like syzkaller to do?

An Lee

unread,
Dec 22, 2016, 7:01:49 AM12/22/16
to syzkaller
Hi,Dmitry,

Thanks for your reply.
I would like to use syzkaller to fuzz a device driver, and the system calls used to access the driver are general system calls like open read or write.
So it will be inefficient to test my driver just use enable_syscalls
Is there any way for syzkaller to test exactly my driver?
Hope I've  make it clear

在 2016年12月22日星期四 UTC+8下午4:57:38,Dmitry Vyukov写道:

Dmitry Vyukov

unread,
Dec 22, 2016, 7:05:18 AM12/22/16
to syzkaller
enable_syscalls can contain discriminated syscalls.
Take a look at, for example, sys/tun.txt. The subsystem also uses
general syscalls like write and ioctl. enable_syscalls for only this
subsystem would be:

enable_syscalls = [
"syz_open_dev$tun",
"write$tun",
"ioctl$TUN*"
]

You can do the same for your particular driver -- describe suitable
discriminated syscalls, and then enable only them.
> --
> You received this message because you are subscribed to the Google Groups
> "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to syzkaller+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

An Lee

unread,
Dec 22, 2016, 9:37:05 PM12/22/16
to syzkaller
Got it!
Thanks!

在 2016年12月22日星期四 UTC+8下午8:05:18,Dmitry Vyukov写道:

An Lee

unread,
Dec 23, 2016, 3:05:37 AM12/23/16
to syzkaller
 Are clock_gettime and mmap always enabled?
 I don't enable them, why are they still tested?

在 2016年12月22日星期四 UTC+8下午8:05:18,Dmitry Vyukov写道:
enable_syscalls can contain discriminated syscalls.

Dmitry Vyukov

unread,
Dec 23, 2016, 3:50:48 AM12/23/16
to syzkaller
On Fri, Dec 23, 2016 at 9:05 AM, An Lee <aple...@gmail.com> wrote:
> Are clock_gettime and mmap always enabled?
> I don't enable them, why are they still tested?


Yes, they are always enabled. Mmap is required to get memory. Most
other syscalls require memory. Even if you do open, you need some
memory to store file name. Similarly, clock_gettime is required to get
time. Don't worry about them.

Actually lots of bug happen during unpredictable interactions of
various subsystems. For example, what if memory passed to your driver
is write-protected, or suddenly locked/unlocked in memory? What if
memory is actually an mmap of a floppy drive? Or what if instead of an
ordinary write into your fd, you receive a splice from pipe, or
sendfile from a CD? What if a call is suddenly interrupted by a
signal? It can make sense to add some other syscalls to the mix.

ljia...@gmail.com

unread,
Dec 27, 2016, 4:06:39 AM12/27/16
to syzkaller
I do it like you described in fuzzing android kernel. But it seems the code which about write$tun cannot be covered. 
I use the kernel linux-linaro-stable-lsk-v4.4-16.09-android 

在 2016年12月22日星期四 UTC+8下午8:05:18,Dmitry Vyukov写道:
enable_syscalls can contain discriminated syscalls.

ljia...@gmail.com

unread,
Dec 27, 2016, 4:35:03 AM12/27/16
to syzkaller
I alse write a test driver and describe the syscalls as below:

resource fd_memdev[fd]
syz_open_dev$memdev(dev strconst["/dev/memdev0"], id const[0], flags flags[open_flags]) fd_memdev
#write$memdev(fd fd_memdev, buf ptr[in, string], count len[buf])
read$memdev(fd fd_memdev, buf buffer[out], count len[buf]) len[buf] 
write$memdev(fd fd_memdev, buf buffer[in], count len[buf])
#write$memdev(fd fd_memdev, buf ptr[in, int32], count len[buf])
lseek$memdev(fd fd_memdev, offset fileoff[fd_memdev], whence flags[seek_whence])

and 

 "enable_syscalls": [
       "syz_open_dev$memdev",
      "read$memdev",
        "write$memdev"
     ]

I find  the codes of read  are covered very fast, but the  codes of write are never coverd ,even fuzzing all the night
I have tested the driver  in qemu ,the read and write are availble.I also test lseek,it also can be covered fast
Does the syscall of write need some spical handle?  


在 2016年12月23日星期五 UTC+8下午4:50:48,Dmitry Vyukov写道:

Dmitry Vyukov

unread,
Dec 27, 2016, 7:43:14 AM12/27/16
to syzkaller
On Tue, Dec 27, 2016 at 10:35 AM, <ljia...@gmail.com> wrote:
> I alse write a test driver and describe the syscalls as below:
>
> resource fd_memdev[fd]
> syz_open_dev$memdev(dev strconst["/dev/memdev0"], id const[0], flags
> flags[open_flags]) fd_memdev
> #write$memdev(fd fd_memdev, buf ptr[in, string], count len[buf])
> read$memdev(fd fd_memdev, buf buffer[out], count len[buf]) len[buf]
> write$memdev(fd fd_memdev, buf buffer[in], count len[buf])
> #write$memdev(fd fd_memdev, buf ptr[in, int32], count len[buf])
> lseek$memdev(fd fd_memdev, offset fileoff[fd_memdev], whence
> flags[seek_whence])
>
> and
>
> "enable_syscalls": [
> "syz_open_dev$memdev",
> "read$memdev",
> "write$memdev"
> ]
>
> I find the codes of read are covered very fast, but the codes of write
> are never coverd ,even fuzzing all the night
> I have tested the driver in qemu ,the read and write are availble.I also
> test lseek,it also can be covered fast
> Does the syscall of write need some spical handle?

No, it does not. It should be covered as well.

The first question is your device was write permissions?

On the main web page, what is read coverage and what is write
coverage? Is write coverage 0?

One thing you can try is:
take a program that contains a read call from work workdir/corpus.
change read to write and try to manually execute it using syz-execprog tool:
https://github.com/google/syzkaller/wiki/How-to-execute-syzkaller-programs
If you run syz-execprog with -debug flag, it will print coverage from
each syscall and also will print syscall return values. If write
returns e.g. EACCES, then it will give some hint as to why you see no
coverage on write.
Message has been deleted

ljia...@gmail.com

unread,
Dec 28, 2016, 1:10:13 AM12/28/16
to syzkaller
Thanks for your replay.

On the main web page, the code of read is covered,but the write of code is never covered
In fact ,I have ssh the qemu to  run a test program. The test program can cover the code of my own device .

I also have tested the example you give ,enable_syscalls as below:

enable_syscalls = [ 
  "syz_open_dev$tun", 
  "write$tun", 
  "ioctl$TUN*" 


after several hours,on the main web page ,the code about tun is still not covered .
The drive/net/tun.c is not in the cover list. I 

on the web page ,I can see the write input as below:

mmap-syz_open_dev$tun-syz_open_dev$tun-mmap-mmap-write$tun cover:384 unique:0 

but the drive/net/tun.c is not covered. Is there something wrong? 




在 2016年12月27日星期二 UTC+8下午8:43:14,Dmitry Vyukov写道:

Dmitry Vyukov

unread,
Dec 28, 2016, 2:24:50 AM12/28/16
to syzkaller
On Wed, Dec 28, 2016 at 7:10 AM, <ljia...@gmail.com> wrote:
> Thanks for your replay.
>
> On the main web page, the code of read is covered,but the write of code is
> never covered
> In fact ,I have ssh the qemu to run a test program. The test program can
> cover the code of my own device .
>
> I also have tested the example you give ,enable_syscalls as below:
>
> enable_syscalls = [
> "syz_open_dev$tun",
> "write$tun",
> "ioctl$TUN*"
> ]
>
> after several hours,on the main web page ,the code about tun is still not
> covered .
> The drive/net/tun.c is not in the cover list. I
>
> on the web page ,I can see the write input as below:
>
> mmap-syz_open_dev$tun-syz_open_dev$tun-mmap-mmap-write$tun cover:384
> unique:0

/\/\/\/\/\/\

This suggests that write$tun is covered.
How do you understand that it is not covered?
Do you have CONFIG_RANDOMIZE_BASE enabled?

ljia...@gmail.com

unread,
Dec 28, 2016, 3:38:44 AM12/28/16
to syzkaller
In my opinion, write$tun  covered  means that the source codes which implement the tun write are covered.
but the source code drivers/net/tun.c is not covered.

I have checked my kernel, the CONFIG_RANDOMIZE_BASE  is not enabled.

In fact, I have make a bug in the write function of my own device drive,it cannot make crash all the time .
but when I make a bug in the read function ,it will make crash quickly
so I think the function of write is not covered,the function of read is covered.


在 2016年12月28日星期三 UTC+8下午3:24:50,Dmitry Vyukov写道:

ljia...@gmail.com

unread,
Dec 29, 2016, 7:08:37 AM12/29/16
to syzkaller
I do it like you describe:
I  change read to write and execute it using syz-execprog.
the read log is like this :

#0: syz_open_dev$memdev(0x20000ff3, 0x0, 0x0)
mem_open,22
mem_open, num=0
#0: syz_open_dev$memdev = 0x3
completion of call 1 [syz_open_dev$memdev] on thread 0
scheduling call 2 [read$memdev] on thread 0
#0: read$memdev(0x3, 0x20000f35, 0xcb)
mem_read,51
men_read, p=0,count=203
mem_read, ret=20
#0: read$memdev = 0x14
completion of call 2 [read$memdev] on thread 0
scheduling call 3 [lseek$memdev] on thread 0
#0: lseek$memdev(0x3, 0x0, 0x1)
mem_llseek,146
mem_llseek...

and write log like this:

#0: syz_open_dev$memdev(0x20000ff3, 0x0, 0x0)
mem_open,22
mem_open, num=0
#0: syz_open_dev$memdev = 0x3
completion of call 1 [syz_open_dev$memdev] on thread 0
copyin to 0x20000f35
scheduling call 2 [write$memdev] on thread 0
#0: write$memdev(0x3, 0x20000f35, 0xcb)
#0: write$memdev = errno(9)
completion of call 2 [write$memdev] on thread 0
scheduling call 3 [lseek$memdev] on thread 0
#0: lseek$memdev(0x3, 0x0, 0x1)
mem_llseek,146
mem_llseek...

when execute write$memdev it return errno(9).
what may be the reason of the error?

Another question I want ask:
what will cause the right problem? Need I do some special config?


在 2016年12月27日星期二 UTC+8下午8:43:14,Dmitry Vyukov写道:
On Tue, Dec 27, 2016 at 10:35 AM,  <ljia...@gmail.com> wrote:

Dmitry Vyukov

unread,
Dec 29, 2016, 7:56:05 AM12/29/16
to syzkaller
Humm... this is weird. I never saw this before.

Just to make sure, you are using x86_64, right?

Several suggestions:
1. If you write an equivalent C program and print all return values,
does it successfully invoke write?

2. If you write a syzkaller program that contains both read$memdev and
write$memdev, read succeeds but write fails, right?

3. Run execprog under strace as:
strace -f -o /tmp/log ./syz-execprog ...
and then find the open of /tmp/log and write in the strace output.
What are the arguments to the write call?

ljia...@gmail.com

unread,
Dec 29, 2016, 8:13:03 AM12/29/16
to syzkaller
Thank you for your replay :

Finally I find the reason which cause the problem:
when I check the device node  in /dev,  I find the  permission of device node is  664
after I changed it to 666 ,the write is covered.

I thought syz-executor is executed  by root ,but it turn out to be not . 
it seems that it is executed by other user. which user execute it? 




在 2016年12月29日星期四 UTC+8下午8:56:05,Dmitry Vyukov写道:

Dmitry Vyukov

unread,
Dec 29, 2016, 8:22:06 AM12/29/16
to syzkaller
On Thu, Dec 29, 2016 at 2:13 PM, <ljia...@gmail.com> wrote:
> Thank you for your replay :
>
> Finally I find the reason which cause the problem:
> when I check the device node in /dev, I find the permission of device
> node is 664
> after I changed it to 666 ,the write is covered.

Great!

> I thought syz-executor is executed by root ,but it turn out to be not .
> it seems that it is executed by other user. which user execute it?

Syzkaller has 3 sandboxing modes: none, setuid and namespace:
https://github.com/google/syzkaller/blob/master/config/config.go#L48
By default it uses setuid mode in which it executes setuid(64534)
before fuzzing.
Add "sandbox": "none" to config file, then it will fuzz under root.
Reply all
Reply to author
Forward
0 new messages