lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Mon, 4 May 2020 17:36:29 -0500
From:   Navid Emamdoost <emamd001@....edu>
To:     Boris Pismenny <borisp@...lanox.com>,
        Aviad Yehezkel <aviadye@...lanox.com>,
        Dave Watson <davejwatson@...com>,
        John Fastabend <john.fastabend@...il.com>,
        Daniel Borkmann <daniel@...earbox.net>,
        Jakub Kicinski <jakub.kicinski@...ronome.com>,
        "David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     Stephen McCamant <mccamant@...umn.edu>, Kangjie Lu <kjlu@....edu>,
        Qiushi Wu <wu000273@....edu>
Subject: Potential Race Condition in tls_hw_hash() and alike

Hi,

I was wondering if a race condition in net/tls/tls_main.c may lead to
a UAF or not?

The scenario can be like this:
1) device is initialized and registered via chtls_register_dev()
2) while tls_hw_hash() is executed in one thread, the device gets
detached (CPU2), and another thread tries to acquire the pointer
(CPU3):

        CPU1:  tls_hw_hash()
        CPU2: chtls_uld_state_change()
                  CPU3: can be tls_hw_hash() or tls_hw_unhash()
        //<assume kref == 1>
        spin_lock_bh(&device_spinlock);
        list_for_each_entry(dev, &device_list, dev_list) {
                if (dev->hash) {
                        kref_get(&dev->kref);  //kref == 2
                        spin_unlock_bh(&device_spinlock);
 kref_put(&cdev->tlsdev.kref, cdev->tlsdev.release); //kref == 1
                        err |= dev->hash(dev, sk);


spin_lock_bh(&device_spinlock);
                        kref_put(&dev->kref, dev->release);   //kref
== 0, release
                         kref_get(&dev->kref);  //BUG: kref 0 to 1!




Basically, the problem comes from the fact that kref_put is not lock protected.
Do you agree that such a race condition may happen? If yes, then is
moving kref_put inside the lock a practical solution?

Thank you,
--
Navid.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ