• Changbin Du's avatar
    modules: wait do_free_init correctly · 8f8cd6c0
    Changbin Du authored
    The synchronization here is to ensure the ordering of freeing of a module
    init so that it happens before W+X checking.  It is worth noting it is not
    that the freeing was not happening, it is just that our sanity checkers
    raced against the permission checkers which assume init memory is already
    gone.
    
    Commit 1a7b7d92 ("modules: Use vmalloc special flag") moved calling
    do_free_init() into a global workqueue instead of relying on it being
    called through call_rcu(..., do_free_init), which used to allowed us call
    do_free_init() asynchronously after the end of a subsequent grace period. 
    The move to a global workqueue broke the gaurantees for code which needed
    to be sure the do_free_init() would complete with rcu_barrier().  To fix
    this callers which used to rely on rcu_barrier() must now instead use
    flush_work(&init_free_wq).
    
    Without this fix, we still could encounter false positive reports in W+X
    checking since the rcu_barrier() here can not ensure the ordering now.
    
    Even worse, the rcu_barrier() can introduce significant delay.  Eric
    Chanudet reported that the rcu_barrier introduces ~0.1s delay on a
    PREEMPT_RT kernel.
    
      [    0.291444] Freeing unused kernel memory: 5568K
      [    0.402442] Run /sbin/init as init process
    
    With this fix, the above delay can be eliminated.
    
    Link: https://lkml.kernel.org/r/20240227023546.2490667-1-changbin.du@huawei.com
    Fixes: 1a7b7d92 ("modules: Use vmalloc special flag")
    Signed-off-by: default avatarChangbin Du <changbin.du@huawei.com>
    Tested-by: default avatarEric Chanudet <echanude@redhat.com>
    Acked-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
    Cc: Xiaoyi Su <suxiaoyi@huawei.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    8f8cd6c0
main.c 85.7 KB