Back to success stories

Sample of Defect

Project Name CID Checker Category Developer Description
FreeBSD 1352776 UNINIT Memory - illegal accesses It is pretty easy to miss such things when adding a new feature. It even looked as a false positive at first.
File: /sys/kern/vfs_aio.c
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
                if (start != NULL)
                        (*start)--;
                mtx_unlock(&aio_job_mtx);
        } else {
                free_unr(aiod_unr, id);
        }
        return (error);
}

/*
 * Try the high-performance, low-overhead physio method for eligible
 * VCHR devices.  This method doesn't use an aio helper thread, and
 * thus has very low overhead.
 *
 * Assumes that the caller, aio_aqueue(), has incremented the file
 * structure's reference count, preventing its deallocation for the
 * duration of this call.
 */
static int
aio_qphysio(struct proc *p, struct kaiocb *job)
{
        struct aiocb *cb;
        struct file *fp;
        struct bio *bp;
 << 1. Declaring variable "pbuf" without initializer.
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
        struct buf *pbuf;
        struct vnode *vp;
        struct cdevsw *csw;
        struct cdev *dev;
        struct kaioinfo *ki;
        int error, ref, unmap, poff;
        vm_prot_t prot;

        cb = &job->uaiocb;
        fp = job->fd_file;
 < 2. Condition "fp == NULL", taking false branch
 < 3. Condition "fp->f_type != 1", taking false branch
1182
1183
1184
1185
        if (fp == NULL || fp->f_type != DTYPE_VNODE)
                return (-1);

        vp = fp->f_vnode;
 < 4. Condition "vp->v_type != VCHR", taking false branch
1186
1187
        if (vp->v_type != VCHR)
                return (-1);
 < 5. Condition "vp->v_bufobj.bo_bsize == 0", taking false branch
1188
1189
        if (vp->v_bufobj.bo_bsize == 0)
                return (-1);
 < 6. Condition "cb->aio_nbytes % vp->v_bufobj.bo_bsize", taking false branch
1190
1191
1192
1193
1194
        if (cb->aio_nbytes % vp->v_bufobj.bo_bsize)
                return (-1);

        ref = 0;
        csw = devvn_refthread(vp, &dev, &ref);
 < 7. Condition "csw == NULL", taking false branch
1195
1196
        if (csw == NULL)
                return (ENXIO);
 < 8. Condition "(csw->d_flags & 2) == 0", taking false branch
1198
1199
1200
1201
        if ((csw->d_flags & D_DISK) == 0) {
                error = -1;
                goto unref;
        }
 < 9. Condition "cb->aio_nbytes > dev->si_iosize_max", taking false branch
1202
1203
1204
1205
1206
1207
1208
        if (cb->aio_nbytes > dev->si_iosize_max) {
                error = -1;
                goto unref;
        }

        ki = p->p_aioinfo;
        poff = (vm_offset_t)cb->aio_buf & PAGE_MASK;
 < 10. Condition "dev->si_flags & 1024", taking true branch
 < 11. Condition "unmapped_buf_allowed", taking true branch
1209
        unmap = ((dev->si_flags & SI_UNMAPPED) && unmapped_buf_allowed);
 < 12. Condition "unmap", taking true branch
1210
        if (unmap) {
 < 13. Condition "cb->aio_nbytes > 131072UL /* 128 * 1024 */", taking false branch
1211
1212
1213
1214
                if (cb->aio_nbytes > MAXPHYS) {
                        error = -1;
                        goto unref;
                }
 < 14. Falling through to end of if statement
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
        } else {
                if (cb->aio_nbytes > MAXPHYS - poff) {
                        error = -1;
                        goto unref;
                }
                if (ki->kaio_buffer_count >= ki->kaio_ballowed_count) {
                        error = -1;
                        goto unref;
                }
        }
        job->bp = bp = g_alloc_bio();
 < 15. Condition "!unmap", taking false branch
1226
1227
1228
1229
1230
1231
        if (!unmap) {
                job->pbuf = pbuf = (struct buf *)getpbuf(NULL);
                BUF_KERNPROC(pbuf);
        }

        AIO_LOCK(ki);
 < 16. Condition "!unmap", taking false branch
1232
1233
1234
1235
1236
1237
1238
1239
1240
        if (!unmap)
                ki->kaio_buffer_count++;
        AIO_UNLOCK(ki);

        bp->bio_length = cb->aio_nbytes;
        bp->bio_bcount = cb->aio_nbytes;
        bp->bio_done = aio_physwakeup;
        bp->bio_data = (void *)(uintptr_t)cb->aio_buf;
        bp->bio_offset = cb->aio_offset;
 < 17. Condition "cb->aio_lio_opcode == 1", taking true branch
1241
1242
1243
1244
1245
        bp->bio_cmd = cb->aio_lio_opcode == LIO_WRITE ? BIO_WRITE : BIO_READ;
        bp->bio_dev = dev;
        bp->bio_caller1 = (void *)job;

        prot = VM_PROT_READ;
 < 18. Condition "cb->aio_lio_opcode == 2", taking false branch
1246
1247
        if (cb->aio_lio_opcode == LIO_READ)
                prot |= VM_PROT_WRITE;        /* Less backwards than it looks */
 < 19. Condition "(job->npages = vm_fault_quick_hold_pages(&__curthread()->td_proc->p_vmspace->vm_map, (vm_offset_t)bp->bio_data, bp->bio_length, prot, job->pages, 33 /* sizeof (job->pages) / sizeof (job->pages[0]) */)) < 0", taking true branch
1248
1249
1250
1251
1252
        if ((job->npages = vm_fault_quick_hold_pages(
            &curproc->p_vmspace->vm_map,
            (vm_offset_t)bp->bio_data, bp->bio_length, prot, job->pages,
            sizeof(job->pages)/sizeof(job->pages[0]))) < 0) {
                error = EFAULT;
 < 20. Jumping to label "doerror"
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
                goto doerror;
        }
        if (!unmap) {
                pmap_qenter((vm_offset_t)pbuf->b_data,
                    job->pages, job->npages);
                bp->bio_data = pbuf->b_data + poff;
        } else {
                bp->bio_ma = job->pages;
                bp->bio_ma_n = job->npages;
                bp->bio_ma_offset = poff;
                bp->bio_data = unmapped_buf;
                bp->bio_flags |= BIO_UNMAPPED;
        }

        if (!unmap)
                atomic_add_int(&num_buf_aio, 1);

        /* Perform transfer. */
        csw->d_strategy(bp);
        dev_relthread(dev, ref);
        return (0);

doerror:
        AIO_LOCK(ki);
 < 21. Condition "!unmap", taking false branch
1277
1278
1279
        if (!unmap)
                ki->kaio_buffer_count--;
        AIO_UNLOCK(ki);
 <<< CID 1352776: Memory - illegal accesses UNINIT
 <<< 22. Using uninitialized value "pbuf".
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
        if (pbuf) {
                relpbuf(pbuf, NULL);
                job->pbuf = NULL;
        }
        g_destroy_bio(bp);
        job->bp = NULL;
unref:
        dev_relthread(dev, ref);
        return (error);
}

#ifdef COMPAT_FREEBSD6
static int
convert_old_sigevent(struct osigevent *osig, struct sigevent *nsig)
{

        /*
         * Only SIGEV_NONE, SIGEV_SIGNAL, and SIGEV_KEVENT are
         * supported by AIO with the old sigevent structure.
         */
        nsig->sigev_notify = osig->sigev_notify;
        switch (nsig->sigev_notify) {
        case SIGEV_NONE:
                break;
        case SIGEV_SIGNAL:
                nsig->sigev_signo = osig->__sigev_u.__sigev_signo;
                break;
Events:
1. var_decl vfs_aio.c:1171
22. uninit_use vfs_aio.c:1280