• Nicolai Stange's avatar
    lib/mpi: mpi_write_sgl(): fix out-of-bounds stack access · cece762f
    Nicolai Stange authored
    Within the copying loop in mpi_write_sgl(), we have
      if (lzeros) {
        mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
        mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
                                   + lzeros;
        *limb1 = *limb2;
    where p points past the end of alimb2 which lives on the stack and contains
    the current limb in BE order.
    The purpose of the above is to shift the non-zero bytes of alimb2 to its
    beginning in memory, i.e. to skip its leading zero bytes.
    However, limb2 points somewhere into the middle of alimb2 and thus, reading
    *limb2 pulls in lzero bytes from somewhere.
    Indeed, KASAN splats:
      BUG: KASAN: stack-out-of-bounds in mpi_write_to_sgl+0x4e3/0x6f0
                                          at addr ffff8800cb04f601
      Read of size 8 by task systemd-udevd/391
      page:ffffea00032c13c0 count:0 mapcount:0 mapping:   (null) index:0x0
      flags: 0x3fff8000000000()
      page dumped because: kasan: bad access detected
      CPU: 3 PID: 391 Comm: systemd-udevd Tainted: G  B  L
                                                  4.5.0-next-20160316+ #12
      Call Trace:
       [<ffffffff8194889e>] dump_stack+0xdc/0x15e
       [<ffffffff819487c2>] ? _atomic_dec_and_lock+0xa2/0xa2
       [<ffffffff814892b5>] ? __dump_page+0x185/0x330
       [<ffffffff8150ffd6>] kasan_report_error+0x5e6/0x8b0
       [<ffffffff814724cd>] ? kzfree+0x2d/0x40
       [<ffffffff819c5bce>] ? mpi_free_limb_space+0xe/0x20
       [<ffffffff819c469e>] ? mpi_powm+0x37e/0x16f0
       [<ffffffff815109f1>] kasan_report+0x71/0xa0
       [<ffffffff819c0353>] ? mpi_write_to_sgl+0x4e3/0x6f0
       [<ffffffff8150ed34>] __asan_load8+0x64/0x70
       [<ffffffff819c0353>] mpi_write_to_sgl+0x4e3/0x6f0
       [<ffffffff819bfe70>] ? mpi_set_buffer+0x620/0x620
       [<ffffffff819c0e6f>] ? mpi_cmp+0xbf/0x180
       [<ffffffff8186e282>] rsa_verify+0x202/0x260
    What's more, since lzeros can be anything from 1 to sizeof(mpi_limb_t)-1,
    the above will cause unaligned accesses which is bad on non-x86 archs.
    Fix the issue, by preparing the starting point p for the upcoming copy
    operation instead of shifting the source memory, i.e. alimb2.
    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>