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