1 /* 2 * Coverity Scan model 3 * https://scan.coverity.com/models 4 * 5 * This is a modeling file for Coverity Scan. 6 * Modeling helps to avoid false positives. 7 * 8 * - Modeling doesn't need full structs and typedefs. Rudimentary structs 9 * and similar types are sufficient. 10 * - An uninitialized local pointer is not an error. It signifies that the 11 * variable could be either NULL or have some data. 12 * 13 * Coverity Scan doesn't pick up modifications automatically. The model file 14 * must be uploaded by an admin in the analysis settings. 15 * 16 * Some of this initially cribbed from: 17 * 18 * https://github.com/kees/coverity-linux/blob/trunk/model.c 19 * 20 * The below model was based on the original model by Brian Behlendorf for the 21 * original zfsonlinux/zfs repository. Some inspiration was taken from 22 * kees/coverity-linux, specifically involving memory copies. 23 */ 24 25 #include <stdarg.h> 26 27 #define UMEM_DEFAULT 0x0000 /* normal -- may fail */ 28 #define UMEM_NOFAIL 0x0100 /* Never fails */ 29 30 #define NULL (0) 31 32 int condition0, condition1; 33 34 int 35 ddi_copyin(const void *from, void *to, size_t len, int flags) 36 { 37 __coverity_tainted_data_argument__(from); 38 __coverity_tainted_data_argument__(to); 39 __coverity_writeall__(to); 40 } 41 42 void * 43 memset(void *dst, int c, size_t len) 44 { 45 __coverity_writeall__(dst); 46 return (dst); 47 } 48 49 void * 50 memmove(void *dst, void *src, size_t len) 51 { 52 __coverity_writeall__(dst); 53 return (dst); 54 } 55 56 void * 57 memcpy(void *dst, void *src, size_t len) 58 { 59 __coverity_writeall__(dst); 60 return (dst); 61 } 62 63 void * 64 umem_alloc_aligned(size_t size, size_t align, int kmflags) 65 { 66 (void) align; 67 68 if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) 69 return (__coverity_alloc__(size)); 70 else if (condition0) 71 return (__coverity_alloc__(size)); 72 else 73 return (NULL); 74 } 75 76 void * 77 umem_alloc(size_t size, int kmflags) 78 { 79 if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) 80 return (__coverity_alloc__(size)); 81 else if (condition0) 82 return (__coverity_alloc__(size)); 83 else 84 return (NULL); 85 } 86 87 void * 88 umem_zalloc(size_t size, int kmflags) 89 { 90 if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) 91 return (__coverity_alloc__(size)); 92 else if (condition0) 93 return (__coverity_alloc__(size)); 94 else 95 return (NULL); 96 } 97 98 void 99 umem_free(void *buf, size_t size) 100 { 101 (void) size; 102 103 __coverity_free__(buf); 104 } 105 106 typedef struct {} umem_cache_t; 107 108 void * 109 umem_cache_alloc(umem_cache_t *skc, int flags) 110 { 111 (void) skc; 112 113 if (condition1) 114 __coverity_sleep__(); 115 116 if ((UMEM_NOFAIL & flags) == UMEM_NOFAIL) 117 return (__coverity_alloc_nosize__()); 118 else if (condition0) 119 return (__coverity_alloc_nosize__()); 120 else 121 return (NULL); 122 } 123 124 void 125 umem_cache_free(umem_cache_t *skc, void *obj) 126 { 127 (void) skc; 128 129 __coverity_free__(obj); 130 } 131 132 void * 133 spl_kmem_alloc(size_t sz, int fl, const char *func, int line) 134 { 135 (void) func; 136 (void) line; 137 138 if (condition1) 139 __coverity_sleep__(); 140 141 if (fl == 0) { 142 return (__coverity_alloc__(sz)); 143 } else if (condition0) 144 return (__coverity_alloc__(sz)); 145 else 146 return (NULL); 147 } 148 149 void * 150 spl_kmem_zalloc(size_t sz, int fl, const char *func, int line) 151 { 152 (void) func; 153 (void) line; 154 155 if (condition1) 156 __coverity_sleep__(); 157 158 if (fl == 0) { 159 return (__coverity_alloc__(sz)); 160 } else if (condition0) 161 return (__coverity_alloc__(sz)); 162 else 163 return (NULL); 164 } 165 166 void 167 spl_kmem_free(const void *ptr, size_t sz) 168 { 169 (void) sz; 170 171 __coverity_free__(ptr); 172 } 173 174 typedef struct {} spl_kmem_cache_t; 175 176 void * 177 spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags) 178 { 179 (void) skc; 180 181 if (condition1) 182 __coverity_sleep__(); 183 184 if (flags == 0) { 185 return (__coverity_alloc_nosize__()); 186 } else if (condition0) 187 return (__coverity_alloc_nosize__()); 188 else 189 return (NULL); 190 } 191 192 void 193 spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj) 194 { 195 (void) skc; 196 197 __coverity_free__(obj); 198 } 199 200 void 201 malloc(size_t size) 202 { 203 __coverity_alloc__(size); 204 } 205 206 void 207 free(void *buf) 208 { 209 __coverity_free__(buf); 210 } 211 212 int 213 sched_yield(void) 214 { 215 __coverity_sleep__(); 216 } 217 218 typedef struct {} kmutex_t; 219 typedef struct {} krwlock_t; 220 typedef int krw_t; 221 222 /* 223 * Coverty reportedly does not support macros, so this only works for 224 * userspace. 225 */ 226 227 void 228 mutex_enter(kmutex_t *mp) 229 { 230 if (condition0) 231 __coverity_sleep__(); 232 233 __coverity_exclusive_lock_acquire__(mp); 234 } 235 236 int 237 mutex_tryenter(kmutex_t *mp) 238 { 239 if (condition0) { 240 __coverity_exclusive_lock_acquire__(mp); 241 return (1); 242 } 243 244 return (0); 245 } 246 247 void 248 mutex_exit(kmutex_t *mp) 249 { 250 __coverity_exclusive_lock_release__(mp); 251 } 252 253 void 254 rw_enter(krwlock_t *rwlp, krw_t rw) 255 { 256 (void) rw; 257 258 if (condition0) 259 __coverity_sleep__(); 260 261 __coverity_recursive_lock_acquire__(rwlp); 262 } 263 264 void 265 rw_exit(krwlock_t *rwlp) 266 { 267 __coverity_recursive_lock_release__(rwlp); 268 269 } 270 271 int 272 rw_tryenter(krwlock_t *rwlp, krw_t rw) 273 { 274 if (condition0) { 275 __coverity_recursive_lock_acquire__(rwlp); 276 return (1); 277 } 278 279 return (0); 280 } 281 282 /* Thus, we fallback to the Linux kernel locks */ 283 struct {} mutex; 284 struct {} rw_semaphore; 285 286 void 287 mutex_lock(struct mutex *lock) 288 { 289 if (condition0) { 290 __coverity_sleep__(); 291 } 292 __coverity_exclusive_lock_acquire__(lock); 293 } 294 295 void 296 mutex_unlock(struct mutex *lock) 297 { 298 __coverity_exclusive_lock_release__(lock); 299 } 300 301 void 302 down_read(struct rw_semaphore *sem) 303 { 304 if (condition0) { 305 __coverity_sleep__(); 306 } 307 __coverity_recursive_lock_acquire__(sem); 308 } 309 310 void 311 down_write(struct rw_semaphore *sem) 312 { 313 if (condition0) { 314 __coverity_sleep__(); 315 } 316 __coverity_recursive_lock_acquire__(sem); 317 } 318 319 int 320 down_read_trylock(struct rw_semaphore *sem) 321 { 322 if (condition0) { 323 __coverity_recursive_lock_acquire__(sem); 324 return (1); 325 } 326 327 return (0); 328 } 329 330 int 331 down_write_trylock(struct rw_semaphore *sem) 332 { 333 if (condition0) { 334 __coverity_recursive_lock_acquire__(sem); 335 return (1); 336 } 337 338 return (0); 339 } 340 341 void 342 up_read(struct rw_semaphore *sem) 343 { 344 __coverity_recursive_lock_release__(sem); 345 } 346 347 void 348 up_write(struct rw_semaphore *sem) 349 { 350 __coverity_recursive_lock_release__(sem); 351 } 352 353 int 354 __cond_resched(void) 355 { 356 if (condition0) { 357 __coverity_sleep__(); 358 } 359 } 360