vmur: convert urdev.ref_count from atomic_t to refcount_t
atomic_t variables are currently used to implement reference counters with the following properties: - counter is initialized to 1 using atomic_set() - a resource is freed upon counter reaching zero - once counter reaches zero, its further increments aren't allowed - counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.) Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable. The variable urdev.ref_count is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by: Kees Cook <keescook@chromium.org> Reviewed-by: David Windsor <dwindsor@gmail.com> Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
3593eb944c
commit
0462d9921e
|
@ -110,7 +110,7 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev)
|
|||
mutex_init(&urd->io_mutex);
|
||||
init_waitqueue_head(&urd->wait);
|
||||
spin_lock_init(&urd->open_lock);
|
||||
atomic_set(&urd->ref_count, 1);
|
||||
refcount_set(&urd->ref_count, 1);
|
||||
urd->cdev = cdev;
|
||||
get_device(&cdev->dev);
|
||||
return urd;
|
||||
|
@ -126,7 +126,7 @@ static void urdev_free(struct urdev *urd)
|
|||
|
||||
static void urdev_get(struct urdev *urd)
|
||||
{
|
||||
atomic_inc(&urd->ref_count);
|
||||
refcount_inc(&urd->ref_count);
|
||||
}
|
||||
|
||||
static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev)
|
||||
|
@ -159,7 +159,7 @@ static struct urdev *urdev_get_from_devno(u16 devno)
|
|||
|
||||
static void urdev_put(struct urdev *urd)
|
||||
{
|
||||
if (atomic_dec_and_test(&urd->ref_count))
|
||||
if (refcount_dec_and_test(&urd->ref_count))
|
||||
urdev_free(urd);
|
||||
}
|
||||
|
||||
|
@ -945,7 +945,7 @@ static int ur_set_offline_force(struct ccw_device *cdev, int force)
|
|||
rc = -EBUSY;
|
||||
goto fail_urdev_put;
|
||||
}
|
||||
if (!force && (atomic_read(&urd->ref_count) > 2)) {
|
||||
if (!force && (refcount_read(&urd->ref_count) > 2)) {
|
||||
/* There is still a user of urd (e.g. ur_open) */
|
||||
TRACE("ur_set_offline: BUSY\n");
|
||||
rc = -EBUSY;
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#ifndef _VMUR_H_
|
||||
#define _VMUR_H_
|
||||
|
||||
#include <linux/refcount.h>
|
||||
|
||||
#define DEV_CLASS_UR_I 0x20 /* diag210 unit record input device class */
|
||||
#define DEV_CLASS_UR_O 0x10 /* diag210 unit record output device class */
|
||||
/*
|
||||
|
@ -69,7 +71,7 @@ struct urdev {
|
|||
size_t reclen; /* Record length for *write* CCWs */
|
||||
int class; /* VM device class */
|
||||
int io_request_rc; /* return code from I/O request */
|
||||
atomic_t ref_count; /* reference counter */
|
||||
refcount_t ref_count; /* reference counter */
|
||||
wait_queue_head_t wait; /* wait queue to serialize open */
|
||||
int open_flag; /* "urdev is open" flag */
|
||||
spinlock_t open_lock; /* serialize critical sections */
|
||||
|
|
Loading…
Reference in New Issue