Skip to content
  • Nicolai Stange's avatar
    lib/mpi: mpi_read_raw_from_sgl(): fix out-of-bounds buffer access · 0bb5c9ea
    Nicolai Stange authored
    Within the copying loop in mpi_read_raw_from_sgl(), the last input SGE's
    byte count gets artificially extended as follows:
    
      if (sg_is_last(sg) && (len % BYTES_PER_MPI_LIMB))
        len += BYTES_PER_MPI_LIMB - (len % BYTES_PER_MPI_LIMB);
    
    Within the following byte copying loop, this causes reads beyond that
    SGE's allocated buffer:
    
      BUG: KASAN: slab-out-of-bounds in mpi_read_raw_from_sgl+0x331/0x650
                                         at addr ffff8801e168d4d8
      Read of size 1 by task systemd-udevd/721
      [...]
      Call Trace:
       [<ffffffff818c4d35>] dump_stack+0xbc/0x117
       [<ffffffff818c4c79>] ? _atomic_dec_and_lock+0x169/0x169
       [<ffffffff814af5d1>] ? print_section+0x61/0xb0
       [<ffffffff814b1109>] print_trailer+0x179/0x2c0
       [<ffffffff814bc524>] object_err+0x34/0x40
       [<ffffffff814bfdc7>] kasan_report_error+0x307/0x8c0
       [<ffffffff814bf315>] ? kasan_unpoison_shadow+0x35/0x50
       [<ffffffff814bf38e>] ? kasan_kmalloc+0x5e/0x70
       [<ffffffff814c0ad1>] kasan_report+0x71/0xa0
       [<ffffffff81938171>] ? mpi_read_raw_from_sgl+0x331/0x650
       [<ffffffff814bf1a6>] __asan_load1+0x46/0x50
       [<ffffffff81938171>] mpi_read_raw_from_sgl+0x331/0x650
       [<ffffffff817f41b6>] rsa_verify+0x106/0x260
       [<ffffffff817f40b0>] ? rsa_set_pub_key+0xf0/0xf0
       [<ffffffff818edc79>] ? sg_init_table+0x29/0x50
       [<ffffffff817f4d22>] ? pkcs1pad_sg_set_buf+0xb2/0x2e0
       [<ffffffff817f5b74>] pkcs1pad_verify+0x1f4/0x2b0
       [<ffffffff81831057>] public_key_verify_signature+0x3a7/0x5e0
       [<ffffffff81830cb0>] ? public_key_describe+0x80/0x80
       [<ffffffff817830f0>] ? keyring_search_aux+0x150/0x150
       [<ffffffff818334a4>] ? x509_request_asymmetric_key+0x114/0x370
       [<ffffffff814b83f0>] ? kfree+0x220/0x370
       [<ffffffff818312c2>] public_key_verify_signature_2+0x32/0x50
       [<ffffffff81830b5c>] verify_signature+0x7c/0xb0
       [<ffffffff81835d0c>] pkcs7_validate_trust+0x42c/0x5f0
       [<ffffffff813c391a>] system_verify_data+0xca/0x170
       [<ffffffff813c3850>] ? top_trace_array+0x9b/0x9b
       [<ffffffff81510b29>] ? __vfs_read+0x279/0x3d0
       [<ffffffff8129372f>] mod_verify_sig+0x1ff/0x290
      [...]
    
    The exact purpose of the len extension isn't clear to me, but due to
    its form, I suspect that it's a leftover somehow accounting for leading
    zero bytes within the most significant output limb.
    
    Note however that without that len adjustement, the total number of bytes
    ever processed by the inner loop equals nbytes and thus, the last output
    limb gets written at this point. Thus the net effect of the len adjustement
    cited above is just to keep the inner loop running for some more
    iterations, namely < BYTES_PER_MPI_LIMB ones, reading some extra bytes from
    beyond the last SGE's buffer and discarding them afterwards.
    
    Fix this issue by purging the extension of len beyond the last input SGE's
    buffer length.
    
    Fixes: 2d4d1eea
    
     ("lib/mpi: Add mpi sgl helpers")
    Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
    Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
    0bb5c9ea