Fix off-by-one access in base64_decode_value if called with 80
Fix off-by-one access in base64_decode_value if called with 80

Easily triggered by:

$ cat base64_decode_value.c

int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
  for(size_t i = 0; i < size; ++i) {
    (void)base64_decode_value((signed char)data[i]);
  }

  return 0;
}
$ clang -Wall -g -O1 -fsanitize=fuzzer,address,signed-integer-overflow -I.. base64_decode_value.c ../cdecode.c
$ ./a.out in
INFO: Seed: 1960469195
INFO: Loaded 1 modules   (27 inline 8-bit counters): 27 [0x536f30, 0x536f4b),
INFO: Loaded 1 PC tables (27 PCs): 27 [0x511c58,0x511e08),
INFO:       58 files found in in
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: seed corpus: files: 58 min: 1b max: 129b total: 2419b rss: 26Mb
=================================================================
==29036==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000511bf0 at pc 0x0000004fa6f0 bp 0x7ffde37a2770 sp 0x7ffde37a2768
READ of size 1 at 0x000000511bf0 thread T0
    #0 0x4fa6ef in base64_decode_value /user/kode/yubico-c-client/fuzz/../cdecode.c:19:9
    #1 0x4fa5a9 in LLVMFuzzerTestOneInput /user/kode/yubico-c-client/fuzz/base64_decode_value.c:15:11
    #2 0x43a6b1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/user/kode/yubico-c-client/fuzz/a.out+0x43a6b1)
    #3 0x439da5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/user/kode/yubico-c-client/fuzz/a.out+0x439da5)
    #4 0x43c34b in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/user/kode/yubico-c-client/fuzz/a.out+0x43c34b)
    #5 0x43c960 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/user/kode/yubico-c-client/fuzz/a.out+0x43c960)
    #6 0x42a43b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/user/kode/yubico-c-client/fuzz/a.out+0x42a43b)
    #7 0x453032 in main (/user/kode/yubico-c-client/fuzz/a.out+0x453032)
    #8 0x7feac6d991e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
    #9 0x41e8fd in _start (/user/kode/yubico-c-client/fuzz/a.out+0x41e8fd)

0x000000511bf0 is located 0 bytes to the right of global variable 'decoding' defined in '../cdecode.c:14:27' (0x511ba0) of size 80
SUMMARY: AddressSanitizer: global-buffer-overflow /user/kode/yubico-c-client/fuzz/../cdecode.c:19:9 in base64_decode_value
Shadow bytes around the buggy address:
  0x00008009a320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00008009a370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[f9]f9
  0x00008009a380: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a3a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a3b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008009a3c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==29036==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
0x7f,0x7f,0x7f,0x7f,0x7b,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7b,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
\x7f\x7f\x7f\x7f{\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f{\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f
artifact_prefix='./'; Test unit written to ./crash-cee03fa98e6a73cd4bcb3e54ba84401e1ce56451
Base64: f39/f3t/f39/f39/f3t/f39/f39/f39/f39/f39/f38=
$

Yubico/yubico-c-client,Yubico/yubico-c-client,Yubico/yubico-c-client