Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dab6b5da authored by Elena Reshetova's avatar Elena Reshetova Committed by Marcel Holtmann
Browse files

Bluetooth: convert rfcomm_dlc.refcnt from atomic_t to refcount_t



refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 92322599
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
   SOFTWARE IS DISCLAIMED.
*/

#include <linux/refcount.h>

#ifndef __RFCOMM_H
#define __RFCOMM_H

@@ -174,7 +176,7 @@ struct rfcomm_dlc {
	struct mutex  lock;
	unsigned long state;
	unsigned long flags;
	atomic_t      refcnt;
	refcount_t    refcnt;
	u8            dlci;
	u8            addr;
	u8            priority;
@@ -247,12 +249,12 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel);

static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
{
	atomic_inc(&d->refcnt);
	refcount_inc(&d->refcnt);
}

static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
{
	if (atomic_dec_and_test(&d->refcnt))
	if (refcount_dec_and_test(&d->refcnt))
		rfcomm_dlc_free(d);
}

+2 −2
Original line number Diff line number Diff line
@@ -311,7 +311,7 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)

	skb_queue_head_init(&d->tx_queue);
	mutex_init(&d->lock);
	atomic_set(&d->refcnt, 1);
	refcount_set(&d->refcnt, 1);

	rfcomm_dlc_clear_state(d);

@@ -342,7 +342,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
{
	struct rfcomm_session *s = d->session;

	BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
	BT_DBG("dlc %p refcnt %d session %p", d, refcount_read(&d->refcnt), s);

	list_del(&d->list);
	d->session = NULL;