• Will Deacon's avatar
    mm: vmalloc: ensure vmap_block is initialised before adding to queue · 3e3de794
    Will Deacon authored
    Commit 8c61291f ("mm: fix incorrect vbq reference in
    purge_fragmented_block") extended the 'vmap_block' structure to contain a
    'cpu' field which is set at allocation time to the id of the initialising
    CPU.
    
    When a new 'vmap_block' is being instantiated by new_vmap_block(), the
    partially initialised structure is added to the local 'vmap_block_queue'
    xarray before the 'cpu' field has been initialised.  If another CPU is
    concurrently walking the xarray (e.g.  via vm_unmap_aliases()), then it
    may perform an out-of-bounds access to the remote queue thanks to an
    uninitialised index.
    
    This has been observed as UBSAN errors in Android:
    
     | Internal error: UBSAN: array index out of bounds: 00000000f2005512 [#1] PREEMPT SMP
     |
     | Call trace:
     |  purge_fragmented_block+0x204/0x21c
     |  _vm_unmap_aliases+0x170/0x378
     |  vm_unmap_aliases+0x1c/0x28
     |  change_memory_common+0x1dc/0x26c
     |  set_memory_ro+0x18/0x24
     |  module_enable_ro+0x98/0x238
     |  do_init_module+0x1b0/0x310
    
    Move the initialisation of 'vb->cpu' in new_vmap_block() ahead of the
    addition to the xarray.
    
    Link: https://lkml.kernel.org/r/20240812171606.17486-1-will@kernel.org
    Fixes: 8c61291f ("mm: fix incorrect vbq reference in purge_fragmented_block")
    Signed-off-by: default avatarWill Deacon <will@kernel.org>
    Reviewed-by: default avatarBaoquan He <bhe@redhat.com>
    Reviewed-by: default avatarUladzislau Rezki (Sony) <urezki@gmail.com>
    Cc: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
    Cc: Hailong.Liu <hailong.liu@oppo.com>
    Cc: Christoph Hellwig <hch@infradead.org>
    Cc: Lorenzo Stoakes <lstoakes@gmail.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    3e3de794
vmalloc.c 132 KB