1#!/bin/bash 2 3db_file=$1 4cat << EOF | sqlite3 $db_file 5/* we only care about the main ->read/write() functions. */ 6delete from caller_info where function = '(struct file_operations)->read' and file != 'fs/read_write.c'; 7delete from caller_info where function = '(struct file_operations)->write' and file != 'fs/read_write.c'; 8delete from caller_info where function = '(struct file_operations)->read' and caller != '__vfs_read'; 9delete from caller_info where function = '(struct file_operations)->write' and caller != '__vfs_write'; 10delete from function_ptr where function = '(struct file_operations)->read'; 11delete from function_ptr where function = '(struct file_operations)->write'; 12delete from caller_info where function = '__vfs_write' and caller != 'vfs_write'; 13delete from caller_info where function = '__vfs_read' and caller != 'vfs_read'; 14delete from caller_info where function = '(struct file_operations)->write' and caller = 'do_loop_readv_writev'; 15delete from caller_info where function = 'do_splice_from' and caller = 'direct_splice_actor'; 16 17/* delete these function pointers which cause false positives */ 18delete from caller_info where function = '(struct file_operations)->open' and type != 0; 19delete from caller_info where function = '(struct notifier_block)->notifier_call' and type != 0; 20delete from caller_info where function = '(struct mISDNchannel)->send' and type != 0; 21delete from caller_info where function = '(struct irq_router)->get' and type != 0; 22delete from caller_info where function = '(struct irq_router)->set' and type != 0; 23delete from caller_info where function = '(struct net_device_ops)->ndo_change_mtu' and caller = 'i40e_dbg_netdev_ops_write'; 24delete from caller_info where function = '(struct timer_list)->function' and type != 0; 25 26/* type 1003 is USER_DATA */ 27delete from caller_info where caller = 'hid_input_report' and type = 1003; 28delete from caller_info where caller = 'nes_process_iwarp_aeqe' and type = 1003; 29delete from caller_info where caller = 'oz_process_ep0_urb' and type = 1003; 30delete from caller_info where function = 'dev_hard_start_xmit' and key = '\$' and type = 1003; 31delete from caller_info where function like '%->ndo_start_xmit' and key = '\$' and type = 1003; 32delete from caller_info where caller = 'packet_rcv_fanout' and function = '(struct packet_type)->func' and parameter = 1 and type = 1003; 33delete from caller_info where caller = 'hptiop_probe' and type = 1003; 34delete from caller_info where caller = 'p9_fd_poll' and function = '(struct file_operations)->poll' and type = 1003; 35delete from caller_info where caller = 'proc_reg_poll' and function = 'proc_reg_poll ptr poll' and type = 1003; 36delete from caller_info where function = 'blkdev_ioctl' and type = 1003 and parameter = 0 and key = '\$'; 37/* 9017 is USER_DATA3_SET */ 38delete from return_states where function='vscnprintf' and type = 9017; 39delete from return_states where function='scnprintf' and type = 9017; 40delete from return_states where function='vsnprintf' and type = 9017; 41delete from return_states where function='snprintf' and type = 9017; 42delete from return_states where function='sprintf' and type = 9017; 43delete from return_states where function='vscnprintf' and type = 8017; 44delete from return_states where function='scnprintf' and type = 8017; 45delete from return_states where function='vsnprintf' and type = 8017; 46delete from return_states where function='snprintf' and type = 8017; 47delete from return_states where function='sprintf' and type = 8017; 48/* There is something setting skb->sk->sk_mark and friends to user_data and */ 49/* because of recursion it gets passed to everything and is impossible to debug */ 50delete from caller_info where function = '__dev_queue_xmit' and type = 8017; 51delete from caller_info where function = '__netdev_start_xmit' and type = 8017; 52/* comparison doesn't deal with chunks, I guess. */ 53delete from return_states where function='get_tty_driver' and type = 8017; 54delete from caller_info where caller = 'snd_ctl_elem_write' and function = '(struct snd_kcontrol)->put' and type = 8017; 55delete from caller_info where caller = 'snd_ctl_elem_read' and function = '(struct snd_kcontrol)->get' and type = 8017; 56delete from caller_info where function = 'nf_tables_newexpr' and type = 8017 and key = '\$->family'; 57delete from caller_info where caller = 'fb_set_var' and function = '(struct fb_ops)->fb_set_par' and type = 8017 and parameter = 0; 58delete from return_states where function = 'tty_lookup_driver' and parameter = 2 and type = 8017; 59 60insert into caller_info values ('userspace', '', 'compat_sys_ioctl', 0, 0, 1003, 0, '\$', '1'); 61insert into caller_info values ('userspace', '', 'compat_sys_ioctl', 0, 0, 1003, 1, '\$', '1'); 62insert into caller_info values ('userspace', '', 'compat_sys_ioctl', 0, 0, 1003, 2, '\$', '1'); 63 64delete from caller_info where function = '(struct timer_list)->function' and parameter = 0; 65 66/* 67 * rw_verify_area is a very central function for the kernel. The 1000000000 68 * isn't accurate but I've picked it so that we can add "pos + count" without 69 * wrapping on 32 bits. 70 */ 71delete from return_states where function = 'rw_verify_area'; 72insert into return_states values ('faked', 'rw_verify_area', 0, 1, '0-1000000000[<=\$3]', 0, 0, -1, '', ''); 73insert into return_states values ('faked', 'rw_verify_area', 0, 1, '0-1000000000[<=\$3]', 0, 104, 2, '*\$', '0-1000000000'); 74insert into return_states values ('faked', 'rw_verify_area', 0, 1, '0-1000000000[<=\$3]', 0, 103, 3, '\$', '0-1000000000'); 75insert into return_states values ('faked', 'rw_verify_area', 0, 2, '(-4095)-(-1)', 0, 0, -1, '', ''); 76 77delete from return_states where function = 'is_kernel_rodata'; 78insert into return_states values ('faked', 'is_kernel_rodata', 0, 1, '1', 0, 0, -1, '', ''); 79insert into return_states values ('faked', 'is_kernel_rodata', 0, 1, '1', 0, 103, 0, '\$', '100000000-177777777'); 80insert into return_states values ('faked', 'is_kernel_rodata', 0, 2, '0', 0, 0, -1, '', ''); 81 82/* 83 * I am a bad person for doing this to __kmalloc() which is a very deep function 84 * and can easily be removed instead of to kmalloc(). But kmalloc() is an 85 * inline function so it ends up being recorded thousands of times in the 86 * database. Doing this is easier. 87 * 88 */ 89delete from return_states where function = '__kmalloc'; 90insert into return_states values ('faked', '__kmalloc', 0, 1, '16', 0, 0, -1, '', ''); 91insert into return_states values ('faked', '__kmalloc', 0, 1, '16', 0, 103, 0, '\$', '0'); 92insert into return_states values ('faked', '__kmalloc', 0, 2, '0,500000000-577777777', 0, 0, -1, '', ''); 93insert into return_states values ('faked', '__kmalloc', 0, 2, '0,500000000-577777777', 0, 103, 0, '\$', '1-4000000'); 94insert into return_states values ('faked', '__kmalloc', 0, 2, '0,500000000-577777777', 0, 1037, -1, '', 400); 95insert into return_states values ('faked', '__kmalloc', 0, 3, '0', 0, 0, -1, '', ''); 96insert into return_states values ('faked', '__kmalloc', 0, 3, '0', 0, 103, 0, '\$', '4000000-long_max'); 97 98/* 99 * Other kmalloc hacking. 100 */ 101update return_states set return = '0,500000000-577777777' where function = 'kmalloc_slab' and return = 's64min-s64max'; 102update return_states set return = '0,500000000-577777777' where function = 'slab_alloc_node' and return = 's64min-s64max'; 103update return_states set return = '0,500000000-577777777' where function = 'kmalloc_large' and return != '0'; 104update return_states set return = '0,500000000-577777777' where function = 'kmalloc_order_trace' and return != '0'; 105 106delete from return_states where function = 'vmalloc'; 107insert into return_states values ('faked', 'vmalloc', 0, 1, '0,600000000-677777777', 0, 0, -1, '', ''); 108insert into return_states values ('faked', 'vmalloc', 0, 1, '0,600000000-677777777', 0, 103, 0, '\$', '1-128000000'); 109insert into return_states values ('faked', 'vmalloc', 0, 2, '0', 0, 0, -1, '', ''); 110 111delete from return_states where function = 'ksize'; 112insert into return_states values ('faked', 'ksize', 0, 1, '0', 0, 0, -1, '', ''); 113insert into return_states values ('faked', 'ksize', 0, 1, '0', 0, 103, 0, '\$', '16'); 114insert into return_states values ('faked', 'ksize', 0, 2, '1-4000000', 0, 0, -1, '', ''); 115 116/* store a bunch of capped functions */ 117update return_states set return = '0-u32max[<=\$2]' where function = 'copy_to_user'; 118update return_states set return = '0-u32max[<=\$2]' where function = '_copy_to_user'; 119update return_states set return = '0-u32max[<=\$2]' where function = '__copy_to_user'; 120update return_states set return = '0-u32max[<=\$2]' where function = 'copy_from_user'; 121update return_states set return = '0-u32max[<=\$2]' where function = '_copy_from_user'; 122update return_states set return = '0-u32max[<=\$2]' where function = '__copy_from_user'; 123 124update return_states set return = '0-8' where function = '__arch_hweight8'; 125update return_states set return = '0-16' where function = '__arch_hweight16'; 126update return_states set return = '0-32' where function = '__arch_hweight32'; 127update return_states set return = '0-64' where function = '__arch_hweight64'; 128 129/* 130 * Preserve the value across byte swapping. By the time we use it for math it 131 * will be byte swapped back to CPU endian. 132 */ 133update return_states set return = '0-u64max[==\$0]' where function = '__fswab64'; 134update return_states set return = '0-u32max[==\$0]' where function = '__fswab32'; 135update return_states set return = '0-u16max[==\$0]' where function = '__fswab16'; 136update return_states set return = '0-u64max[==\$0]' where function = '__builtin_bswap64'; 137update return_states set return = '0-u32max[==\$0]' where function = '__builtin_bswap32'; 138update return_states set return = '0-u16max[==\$0]' where function = '__builtin_bswap16'; 139 140delete from return_states where function = 'bitmap_allocate_region' and return = '1'; 141/* Just delete a lot of returns that everyone ignores */ 142delete from return_states where file = 'drivers/pci/access.c' and (return >= 129 and return <= 137); 143 144update return_states set return = '(-4095)-s32max[<=\$1]' where function = 'get_user_pages' and return = 's32min-s32max'; 145update return_states set return = '(-4095)-s64max[<=\$1]' where function = 'get_user_pages' and return = 's64min-s64max'; 146 147/* Smatch can't parse wait_for_completion() */ 148update return_states set return = '(-108),(-22),0' where function = '__spi_sync' and return = '(-115),(-108),(-22)'; 149 150delete from caller_info where caller = '__kernel_write'; 151 152/* We sometimes use pre-allocated 4097 byte buffers for performance critical code but pretend it is always PAGE_SIZE */ 153update caller_info set value = 4096 where caller='kernfs_file_direct_read' and function='(struct kernfs_ops)->read' and type = 1002 and parameter = 1; 154/* let's pretend firewire doesn't exist */ 155delete from caller_info where caller='init_fw_attribute_group' and function='(struct device_attribute)->show'; 156/* and let's fake the next dev_attr_show() call entirely */ 157delete from caller_info where caller='sysfs_kf_seq_show' and function='(struct sysfs_ops)->show'; 158insert into caller_info values ('fake', 'sysfs_kf_seq_show', '(struct sysfs_ops)->show', 0, 0, 1001, 0, '\$', '4096-2117777777777777777'); 159insert into caller_info values ('fake', 'sysfs_kf_seq_show', '(struct sysfs_ops)->show', 0, 0, 1002, 2, '\$', '4096'); 160insert into caller_info values ('fake', 'sysfs_kf_seq_show', '(struct sysfs_ops)->show', 0, 0, 1001, 2, '\$', '4096-2117777777777777777'); 161insert into caller_info values ('fake', 'sysfs_kf_seq_show', '(struct sysfs_ops)->show', 0, 0, 0, -1, '' , ''); 162/* config fs confuses smatch a little */ 163update caller_info set value = 4096 where caller='fill_read_buffer' and function='(struct configfs_item_operations)->show_attribute' and type = 1002 and parameter = 2; 164 165/* smatch sees the memset() but not the subsequent changes */ 166update return_states set value = "" where function = 'gfs2_ea_find' and return = '0' and type = 101 and parameter = 3; 167 168delete from type_value where type = '(struct fd)->file'; 169delete from type_value where type = '(struct fd)->flags'; 170 171/* This is sometimes an enum or a u64 */ 172delete from type_value where type = '(struct mc_cmd_header)->status'; 173 174/* this is handled in check_kernel.c */ 175delete from return_states where function = "__write_once_size"; 176 177update return_states set value = "s32min-s32max[\$1]" where function = 'atomic_set' and parameter = 0 and type = 1025; 178 179/* handled in the check itself */ 180delete from return_states where function = 'atomic_inc_return' and (type = 8023 or type = 8024); 181delete from return_states where function = 'atomic_add_return' and (type = 8023 or type = 8024); 182delete from return_states where function = 'atomic_sub_return' and (type = 8023 or type = 8024); 183delete from return_states where function = 'atomic_sub_and_test' and (type = 8023 or type = 8024); 184delete from return_states where function = 'atomic_dec_and_test' and (type = 8023 or type = 8024); 185delete from return_states where function = 'atomic_dec' and (type = 8023 or type = 8024); 186delete from return_states where function = 'atomic_inc' and (type = 8023 or type = 8024); 187delete from return_states where function = 'atomic_sub' and (type = 8023 or type = 8024); 188delete from return_states where function = 'refcount_add_not_zero' and (type = 8023 or type = 8024); 189delete from return_states where function = 'refcount_inc_not_zero' and (type = 8023 or type = 8024); 190delete from return_states where function = 'refcount_sub_and_test' and (type = 8023 or type = 8024); 191 192update return_states set return = '0-32,2147483648-2147483690' where function = '_parse_integer' and return = '0'; 193update return_states set value = '0-u64max' where function = '_parse_integer' and type = 1025 and parameter = 2 and key = '*$'; 194 195/* delete some function pointers which are sometimes byte units */ 196delete from caller_info where function = '(struct i2c_algorithm)->master_xfer' and type = 1027; 197 198/* this if from READ_ONCE(). We can't know anything about the data. */ 199delete from type_info where key = '(union anonymous)->__val'; 200 201EOF 202 203# fixme: this is totally broken 204call_id=$(echo "select distinct call_id from caller_info where function = '__kernel_write';" | sqlite3 $db_file) 205for id in $call_id ; do 206 echo "insert into caller_info values ('fake', '', '__kernel_write', $id, 0, 1003, 1, '*\$', '');" | sqlite3 $db_file 207done 208 209for i in $(echo "select distinct return from return_states where function = 'clear_user';" | sqlite3 $db_file ) ; do 210 echo "update return_states set return = \"$i[<=\$1]\" where return = \"$i\" and function = 'clear_user';" | sqlite3 $db_file 211done 212 213echo "select distinct file, function from function_ptr where ptr='(struct rtl_hal_ops)->set_hw_reg';" \ 214 | sqlite3 $db_file | sed -e 's/|/ /' | while read file function ; do 215 216 drv=$(echo $file | perl -ne 's/.*\/rtlwifi\/(.*?)\/sw.c/$1/; print') 217 if [ $drv = "" ] ; then 218 continue 219 fi 220 221 echo "update caller_info 222 set function = '$drv (struct rtl_hal_ops)->set_hw_reg' 223 where function = '(struct rtl_hal_ops)->set_hw_reg' and file like 'drivers/net/wireless/rtlwifi/$drv/%';" \ 224 | sqlite3 $db_file 225 226 echo "insert into function_ptr values ('$file', '$function', '$drv (struct rtl_hal_ops)->set_hw_reg', 1);" \ 227 | sqlite3 $db_file 228done 229 230