1*387f9dfdSAndroid Build Coastguard WorkerSome examples for inject 2*387f9dfdSAndroid Build Coastguard Worker 3*387f9dfdSAndroid Build Coastguard Workerinject guarantees the appropriate erroneous return of the specified injection 4*387f9dfdSAndroid Build Coastguard Workermode (kmalloc,bio,etc) given a call chain and an optional set of predicates. You 5*387f9dfdSAndroid Build Coastguard Workercan also optionally print out the generated BPF program for 6*387f9dfdSAndroid Build Coastguard Workermodification/debugging purposes. 7*387f9dfdSAndroid Build Coastguard Worker 8*387f9dfdSAndroid Build Coastguard WorkerAs a simple example, let's say you wanted to fail all mounts. As of 4.17 we can 9*387f9dfdSAndroid Build Coastguard Workerfail syscalls directly, so let's do that: 10*387f9dfdSAndroid Build Coastguard Worker 11*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'SyS_mount()' 12*387f9dfdSAndroid Build Coastguard Worker 13*387f9dfdSAndroid Build Coastguard WorkerThe first argument indicates the mode (or what to fail). Appropriate headers are 14*387f9dfdSAndroid Build Coastguard Workerspecified, if necessary. The verbosity flag prints the generated program. Note 15*387f9dfdSAndroid Build Coastguard Workerthat some syscalls will be available as 'SyS_xyz' and some will be available as 16*387f9dfdSAndroid Build Coastguard Worker'sys_xyz'. This is largely dependent on the number of arguments each syscall 17*387f9dfdSAndroid Build Coastguard Workertakes. 18*387f9dfdSAndroid Build Coastguard Worker 19*387f9dfdSAndroid Build Coastguard WorkerTrying to mount various filesystems will fail and report an inability to 20*387f9dfdSAndroid Build Coastguard Workerallocate memory, as expected. 21*387f9dfdSAndroid Build Coastguard Worker 22*387f9dfdSAndroid Build Coastguard WorkerWhenever a predicate is missing, an implicit "(true)" is inserted. The example 23*387f9dfdSAndroid Build Coastguard Workerabove can be explicitly written as: 24*387f9dfdSAndroid Build Coastguard Worker 25*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v '(true) => SyS_mount()(true)' 26*387f9dfdSAndroid Build Coastguard Worker 27*387f9dfdSAndroid Build Coastguard WorkerThe "(true)" without an associated function is a predicate for the error 28*387f9dfdSAndroid Build Coastguard Workerinjection mechanism of the current mode. In the case of kmalloc, the predicate 29*387f9dfdSAndroid Build Coastguard Workerwould have access to the arguments of: 30*387f9dfdSAndroid Build Coastguard Worker 31*387f9dfdSAndroid Build Coastguard Worker should_failslab(struct kmem_cache *s, gfp_t gfpflags) 32*387f9dfdSAndroid Build Coastguard Worker 33*387f9dfdSAndroid Build Coastguard WorkerOther modes work similarly. 34*387f9dfdSAndroid Build Coastguard Worker"bio" has access to the arguments of: 35*387f9dfdSAndroid Build Coastguard Worker 36*387f9dfdSAndroid Build Coastguard Worker should_fail_bio(struct bio *bio) 37*387f9dfdSAndroid Build Coastguard Worker 38*387f9dfdSAndroid Build Coastguard Worker"alloc_page" has access to the arguments of: 39*387f9dfdSAndroid Build Coastguard Worker 40*387f9dfdSAndroid Build Coastguard Worker should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) 41*387f9dfdSAndroid Build Coastguard Worker 42*387f9dfdSAndroid Build Coastguard WorkerWe also note that it's unnecessary to state the arguments of the function if you 43*387f9dfdSAndroid Build Coastguard Workerhave no intention to reference them in the associated predicate. 44*387f9dfdSAndroid Build Coastguard Worker 45*387f9dfdSAndroid Build Coastguard WorkerNow let's say we want to be a bit more specific; suppose you want to fail 46*387f9dfdSAndroid Build Coastguard Workerkmalloc() from mount_subtree() when called from btrfs_mount(). This will fail 47*387f9dfdSAndroid Build Coastguard Workeronly btrfs mounts: 48*387f9dfdSAndroid Build Coastguard Worker 49*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'mount_subtree() => btrfs_mount()' 50*387f9dfdSAndroid Build Coastguard Worker 51*387f9dfdSAndroid Build Coastguard WorkerAttempting to mount btrfs filesystem during the execution of this command will 52*387f9dfdSAndroid Build Coastguard Workeryield an error, but other filesystems will be fine. 53*387f9dfdSAndroid Build Coastguard Worker 54*387f9dfdSAndroid Build Coastguard WorkerNext, lets say we want to hit one of the BUG_ONs in fs/btrfs. As of 4.16-rc3, 55*387f9dfdSAndroid Build Coastguard Workerthere is a BUG_ON in btrfs_prepare_close_one_device() at fs/btrfs/volumes.c:1002 56*387f9dfdSAndroid Build Coastguard Worker 57*387f9dfdSAndroid Build Coastguard WorkerTo hit this, we can use the following: 58*387f9dfdSAndroid Build Coastguard Worker 59*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'btrfs_alloc_device() => btrfs_close_devices()' 60*387f9dfdSAndroid Build Coastguard Worker 61*387f9dfdSAndroid Build Coastguard WorkerWhile the script was executing, I mounted and unmounted btrfs, causing a 62*387f9dfdSAndroid Build Coastguard Workersegfault on umount(since that satisfied the call path indicated). A look at 63*387f9dfdSAndroid Build Coastguard Workerdmesg will confirm that the erroneous return value injected by the script 64*387f9dfdSAndroid Build Coastguard Workertripped the BUG_ON, causing a segfault down the line. 65*387f9dfdSAndroid Build Coastguard Worker 66*387f9dfdSAndroid Build Coastguard WorkerIn general, it's worth noting that the required specificity of the call chain is 67*387f9dfdSAndroid Build Coastguard Workerdependent on how much granularity you need. The example above might have 68*387f9dfdSAndroid Build Coastguard Workerperformed as expected without the intermediate btrfs_alloc_device, but might 69*387f9dfdSAndroid Build Coastguard Workerhave also done something unexpected(an earlier kmalloc could have failed before 70*387f9dfdSAndroid Build Coastguard Workerthe one we were targeting). 71*387f9dfdSAndroid Build Coastguard Worker 72*387f9dfdSAndroid Build Coastguard WorkerFor hot paths, the approach outlined above isn't enough. If a path is traversed 73*387f9dfdSAndroid Build Coastguard Workervery often, we can distinguish distinct calls with function arguments. Let's say 74*387f9dfdSAndroid Build Coastguard Workerwe want to fail the dentry allocation of a file creatively named 'bananas'. We 75*387f9dfdSAndroid Build Coastguard Workercan do the following: 76*387f9dfdSAndroid Build Coastguard Worker 77*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'd_alloc_parallel(struct dentry *parent, const struct 78*387f9dfdSAndroid Build Coastguard Workerqstr *name)(STRCMP(name->name, 'bananas'))' 79*387f9dfdSAndroid Build Coastguard Worker 80*387f9dfdSAndroid Build Coastguard WorkerWhile this script is executing, any operation that would cause a dentry 81*387f9dfdSAndroid Build Coastguard Workerallocation where the name is 'bananas' fails, as expected. 82*387f9dfdSAndroid Build Coastguard Worker 83*387f9dfdSAndroid Build Coastguard WorkerHere, since we're referencing a function argument in our predicate, we need to 84*387f9dfdSAndroid Build Coastguard Workerprovide the function signature up to the argument we're using. 85*387f9dfdSAndroid Build Coastguard Worker 86*387f9dfdSAndroid Build Coastguard WorkerTo note, STRCMP is a workaround for some rewriter issues. It will take input of 87*387f9dfdSAndroid Build Coastguard Workerthe form (x->...->z, 'literal'), and generate some equivalent code that the 88*387f9dfdSAndroid Build Coastguard Workerverifier is more friendly about. It's not horribly robust, but works for the 89*387f9dfdSAndroid Build Coastguard Workerpurposes of making string comparisons a bit easier. 90*387f9dfdSAndroid Build Coastguard Worker 91*387f9dfdSAndroid Build Coastguard WorkerFinally, we briefly demonstrate how to inject bio failures. The mechanism is 92*387f9dfdSAndroid Build Coastguard Workeridentical, so any information from above will apply. 93*387f9dfdSAndroid Build Coastguard Worker 94*387f9dfdSAndroid Build Coastguard WorkerLet's say we want to fail bio requests when the request is to some specific 95*387f9dfdSAndroid Build Coastguard Workersector. An example use case would be to fail superblock writes in btrfs. For 96*387f9dfdSAndroid Build Coastguard Workerbtrfs, we know that there must be a superblock at 65536 bytes, or sector 128. 97*387f9dfdSAndroid Build Coastguard WorkerThis allows us to run the following: 98*387f9dfdSAndroid Build Coastguard Worker 99*387f9dfdSAndroid Build Coastguard Worker# ./inject.py bio -v -I 'linux/blkdev.h' '(({struct gendisk *d = bio->bi_disk; 100*387f9dfdSAndroid Build Coastguard Workerstruct disk_part_tbl *tbl = d->part_tbl; struct hd_struct **parts = (void *)tbl + 101*387f9dfdSAndroid Build Coastguard Workersizeof(struct disk_part_tbl); struct hd_struct **partp = parts + bio->bi_partno; 102*387f9dfdSAndroid Build Coastguard Workerstruct hd_struct *p = *partp; dev_t disk = p->__dev.devt; disk == 103*387f9dfdSAndroid Build Coastguard WorkerMKDEV(254,16);}) && bio->bi_iter.bi_sector == 128)' 104*387f9dfdSAndroid Build Coastguard Worker 105*387f9dfdSAndroid Build Coastguard WorkerThe predicate in the command above has two parts. The first is a compound 106*387f9dfdSAndroid Build Coastguard Workerstatement which shortens to "only if the system is btrfs", but is long due 107*387f9dfdSAndroid Build Coastguard Workerto rewriter/verifier shenanigans. The major/minor information can be found 108*387f9dfdSAndroid Build Coastguard Workerhowever; I used Python. The second part simply checks the starting 109*387f9dfdSAndroid Build Coastguard Workeraddress of bi_iter. While executing, this script effectively fails superblock 110*387f9dfdSAndroid Build Coastguard Workerwrites to the superblock at sector 128 without affecting other filesystems. 111*387f9dfdSAndroid Build Coastguard Worker 112*387f9dfdSAndroid Build Coastguard WorkerAs an extension to the above, one could easily fail all btrfs superblock writes 113*387f9dfdSAndroid Build Coastguard Worker(we only fail the primary) by calculating the sector number of the mirrors and 114*387f9dfdSAndroid Build Coastguard Workeramending the predicate accordingly. 115*387f9dfdSAndroid Build Coastguard Worker 116*387f9dfdSAndroid Build Coastguard WorkerInject also provides a probability option; this allows you to fail the 117*387f9dfdSAndroid Build Coastguard Workerpath+predicates some percentage of the time. For example, let's say we want to 118*387f9dfdSAndroid Build Coastguard Workerfail our mounts half the time: 119*387f9dfdSAndroid Build Coastguard Worker 120*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v -P 0.01 'SyS_mount()' 121*387f9dfdSAndroid Build Coastguard Worker 122*387f9dfdSAndroid Build Coastguard WorkerUSAGE message: 123*387f9dfdSAndroid Build Coastguard Workerusage: inject.py [-h] [-I header] [-P probability] [-v] [-c COUNT] 124*387f9dfdSAndroid Build Coastguard Worker {kmalloc,bio,alloc_page} spec 125*387f9dfdSAndroid Build Coastguard Worker 126*387f9dfdSAndroid Build Coastguard WorkerFail specified kernel functionality when call chain and predicates are met 127*387f9dfdSAndroid Build Coastguard Worker 128*387f9dfdSAndroid Build Coastguard Workerpositional arguments: 129*387f9dfdSAndroid Build Coastguard Worker {kmalloc,bio,alloc_page} 130*387f9dfdSAndroid Build Coastguard Worker indicate which base kernel function to fail 131*387f9dfdSAndroid Build Coastguard Worker spec specify call chain 132*387f9dfdSAndroid Build Coastguard Worker 133*387f9dfdSAndroid Build Coastguard Workeroptional arguments: 134*387f9dfdSAndroid Build Coastguard Worker -h, --help show this help message and exit 135*387f9dfdSAndroid Build Coastguard Worker -I header, --include header 136*387f9dfdSAndroid Build Coastguard Worker additional header files to include in the BPF program 137*387f9dfdSAndroid Build Coastguard Worker -P probability, --probability probability 138*387f9dfdSAndroid Build Coastguard Worker probability that this call chain will fail 139*387f9dfdSAndroid Build Coastguard Worker -v, --verbose print BPF program 140*387f9dfdSAndroid Build Coastguard Worker -c COUNT, --count COUNT 141*387f9dfdSAndroid Build Coastguard Worker Number of fails before bypassing the override 142*387f9dfdSAndroid Build Coastguard Worker 143*387f9dfdSAndroid Build Coastguard WorkerEXAMPLES: 144*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'SyS_mount()' 145*387f9dfdSAndroid Build Coastguard Worker Fails all calls to syscall mount 146*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v '(true) => SyS_mount()(true)' 147*387f9dfdSAndroid Build Coastguard Worker Explicit rewriting of above 148*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'mount_subtree() => btrfs_mount()' 149*387f9dfdSAndroid Build Coastguard Worker Fails btrfs mounts only 150*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v 'd_alloc_parallel(struct dentry *parent, const struct \ 151*387f9dfdSAndroid Build Coastguard Worker qstr *name)(STRCMP(name->name, 'bananas'))' 152*387f9dfdSAndroid Build Coastguard Worker Fails dentry allocations of files named 'bananas' 153*387f9dfdSAndroid Build Coastguard Worker# ./inject.py kmalloc -v -P 0.01 'SyS_mount()' 154*387f9dfdSAndroid Build Coastguard Worker Fails calls to syscall mount with 1% probability 155