diff options
| author | Matthieu Darbois <mayeut@users.noreply.github.com> | 2016-04-28 13:16:43 +0200 |
|---|---|---|
| committer | Matthieu Darbois <mayeut@users.noreply.github.com> | 2016-04-28 13:16:43 +0200 |
| commit | 29313eb5f1b2c01c7493087fa2d8f1a20495a34e (patch) | |
| tree | 8692044fc432188990ac74aa0aef440321cbb12d /src/lib/openjp2/bio.c | |
| parent | e982d0396607a16ca0c373020cc93449504eb4e8 (diff) | |
Fix unsigned int overflow reported by UBSan (#761)
* Fix unsigned int overflow reported by UBSan
Please add -DOPJ_UBSAN_BUILD to CFLAGS when building with
-fsanitize=undefined,unsigned-integer-overflow
It seems clang/gcc do not allow to disable checking for block of code
other than function or file.
Diffstat (limited to 'src/lib/openjp2/bio.c')
| -rw-r--r-- | src/lib/openjp2/bio.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/lib/openjp2/bio.c b/src/lib/openjp2/bio.c index e4edb372..269769b4 100644 --- a/src/lib/openjp2/bio.c +++ b/src/lib/openjp2/bio.c @@ -151,19 +151,31 @@ void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) { bio->ct = 0; } +OPJ_NOSANITIZE("unsigned-integer-overflow") void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) { OPJ_UINT32 i; - for (i = n - 1; i < n; i--) { + + assert((n > 0U) && (n <= 32U)); + for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */ opj_bio_putbit(bio, (v >> i) & 1); } } +OPJ_NOSANITIZE("unsigned-integer-overflow") OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) { OPJ_UINT32 i; - OPJ_UINT32 v; - v = 0; - for (i = n - 1; i < n; i--) { - v += opj_bio_getbit(bio) << i; + OPJ_UINT32 v; + + assert((n > 0U) /* && (n <= 32U)*/); +#ifdef OPJ_UBSAN_BUILD + /* This assert fails for some corrupted images which are gracefully rejected */ + /* Add this assert only for ubsan build. */ + /* This is the condition for overflow not to occur below which is needed because of OPJ_NOSANITIZE */ + assert(n <= 32U); +#endif + v = 0U; + for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */ + v |= opj_bio_getbit(bio) << i; /* can't overflow, opj_bio_getbit returns 0 or 1 */ } return v; } |
