Patch "net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed" has been added to the 4.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-fix-uaf-issue-in-nfqnl_nf_hook_drop-when-ops_ini.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 7dfbf45becd80618a5552e885761eb8a363c77a9
Author: Zhengchao Shao <shaozhengchao@xxxxxxxxxx>
Date:   Thu Oct 20 10:42:13 2022 +0800

    net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed
    
    [ Upstream commit d266935ac43d57586e311a087510fe6a084af742 ]
    
    When the ops_init() interface is invoked to initialize the net, but
    ops->init() fails, data is released. However, the ptr pointer in
    net->gen is invalid. In this case, when nfqnl_nf_hook_drop() is invoked
    to release the net, invalid address access occurs.
    
    The process is as follows:
    setup_net()
            ops_init()
                    data = kzalloc(...)   ---> alloc "data"
                    net_assign_generic()  ---> assign "date" to ptr in net->gen
                    ...
                    ops->init()           ---> failed
                    ...
                    kfree(data);          ---> ptr in net->gen is invalid
            ...
            ops_exit_list()
                    ...
                    nfqnl_nf_hook_drop()
                            *q = nfnl_queue_pernet(net) ---> q is invalid
    
    The following is the Call Trace information:
    BUG: KASAN: use-after-free in nfqnl_nf_hook_drop+0x264/0x280
    Read of size 8 at addr ffff88810396b240 by task ip/15855
    Call Trace:
    <TASK>
    dump_stack_lvl+0x8e/0xd1
    print_report+0x155/0x454
    kasan_report+0xba/0x1f0
    nfqnl_nf_hook_drop+0x264/0x280
    nf_queue_nf_hook_drop+0x8b/0x1b0
    __nf_unregister_net_hook+0x1ae/0x5a0
    nf_unregister_net_hooks+0xde/0x130
    ops_exit_list+0xb0/0x170
    setup_net+0x7ac/0xbd0
    copy_net_ns+0x2e6/0x6b0
    create_new_namespaces+0x382/0xa50
    unshare_nsproxy_namespaces+0xa6/0x1c0
    ksys_unshare+0x3a4/0x7e0
    __x64_sys_unshare+0x2d/0x40
    do_syscall_64+0x35/0x80
    entry_SYSCALL_64_after_hwframe+0x46/0xb0
    </TASK>
    
    Allocated by task 15855:
    kasan_save_stack+0x1e/0x40
    kasan_set_track+0x21/0x30
    __kasan_kmalloc+0xa1/0xb0
    __kmalloc+0x49/0xb0
    ops_init+0xe7/0x410
    setup_net+0x5aa/0xbd0
    copy_net_ns+0x2e6/0x6b0
    create_new_namespaces+0x382/0xa50
    unshare_nsproxy_namespaces+0xa6/0x1c0
    ksys_unshare+0x3a4/0x7e0
    __x64_sys_unshare+0x2d/0x40
    do_syscall_64+0x35/0x80
    entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    Freed by task 15855:
    kasan_save_stack+0x1e/0x40
    kasan_set_track+0x21/0x30
    kasan_save_free_info+0x2a/0x40
    ____kasan_slab_free+0x155/0x1b0
    slab_free_freelist_hook+0x11b/0x220
    __kmem_cache_free+0xa4/0x360
    ops_init+0xb9/0x410
    setup_net+0x5aa/0xbd0
    copy_net_ns+0x2e6/0x6b0
    create_new_namespaces+0x382/0xa50
    unshare_nsproxy_namespaces+0xa6/0x1c0
    ksys_unshare+0x3a4/0x7e0
    __x64_sys_unshare+0x2d/0x40
    do_syscall_64+0x35/0x80
    entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    Fixes: f875bae06533 ("net: Automatically allocate per namespace data.")
    Signed-off-by: Zhengchao Shao <shaozhengchao@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 34fd852fe3ca..3c90890816b8 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -101,6 +101,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
 
 static int ops_init(const struct pernet_operations *ops, struct net *net)
 {
+	struct net_generic *ng;
 	int err = -ENOMEM;
 	void *data = NULL;
 
@@ -119,7 +120,13 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
 	if (!err)
 		return 0;
 
+	if (ops->id && ops->size) {
 cleanup:
+		ng = rcu_dereference_protected(net->gen,
+					       lockdep_is_held(&pernet_ops_rwsem));
+		ng->ptr[*ops->id] = NULL;
+	}
+
 	kfree(data);
 
 out:



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux