Project Name | CID | Checker | Category | Developer Description |
---|---|---|---|---|
linux-next weekly scan | 1375917 | NO_EFFECT | Control flow issues | A simple decrement that wraps around causing an array overflow on lsm->lsm_oinfo[i[. The impact is double-edged - there is a read off the end of an array, and if that does not break the kernel then a bad address to kmem_cache_free is used. |
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
size_t oinfo_ptrs_size, lsm_size; struct lov_stripe_md *lsm; struct lov_oinfo *loi; unsigned int i; LASSERT(stripe_count <= LOV_MAX_STRIPE_COUNT); oinfo_ptrs_size = sizeof(struct lov_oinfo *) * stripe_count; lsm_size = sizeof(*lsm) + oinfo_ptrs_size; lsm = libcfs_kvzalloc(lsm_size, GFP_NOFS); if (!lsm) return NULL; for (i = 0; i < stripe_count; i++) { loi = kmem_cache_zalloc(lov_oinfo_slab, GFP_NOFS); if (!loi) goto err; lsm->lsm_oinfo[i] = loi; } lsm->lsm_stripe_count = stripe_count; return lsm; err: |
<<< CID 1375917: Control flow issues NO_EFFECT <<< This greater-than-or-equal-to-zero comparison of an unsigned value is always true. "--i >= 0U".
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
while (--i >= 0) kmem_cache_free(lov_oinfo_slab, lsm->lsm_oinfo[i]); kvfree(lsm); return NULL; } void lsm_free_plain(struct lov_stripe_md *lsm) { __u16 stripe_count = lsm->lsm_stripe_count; int i; for (i = 0; i < stripe_count; i++) kmem_cache_free(lov_oinfo_slab, lsm->lsm_oinfo[i]); kvfree(lsm); } /* * Find minimum stripe maxbytes value. For inactive or * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES. */ static loff_t lov_tgt_maxbytes(struct lov_tgt_desc *tgt) { loff_t maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; struct obd_import *imp; if (!tgt->ltd_active) return maxbytes; |
unsigned_compare | lov_ea.c:105 |