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: Elena Reshetova <elena.reshet...@intel.com> Signed-off-by: Hans Liljestrand <ishkam...@gmail.com> Signed-off-by: Kees Cook <keesc...@chromium.org> Signed-off-by: David Windsor <dwind...@gmail.com> --- drivers/tty/serial/sb1250-duart.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index 771f361..041625c 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -41,7 +41,7 @@ #include <linux/tty_flip.h> #include <linux/types.h> -#include <linux/atomic.h> +#include <linux/refcount.h> #include <asm/io.h> #include <asm/war.h> @@ -103,7 +103,7 @@ struct sbd_port { struct sbd_duart { struct sbd_port sport[2]; unsigned long mapctrl; - atomic_t map_guard; + refcount_t map_guard; }; #define to_sport(uport) container_of(uport, struct sbd_port, port) @@ -654,15 +654,13 @@ static void sbd_release_port(struct uart_port *uport) { struct sbd_port *sport = to_sport(uport); struct sbd_duart *duart = sport->duart; - int map_guard; iounmap(sport->memctrl); sport->memctrl = NULL; iounmap(uport->membase); uport->membase = NULL; - map_guard = atomic_add_return(-1, &duart->map_guard); - if (!map_guard) + if(refcount_dec_and_test(&duart->map_guard)) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); release_mem_region(uport->mapbase, DUART_CHANREG_SPACING); } @@ -698,7 +696,6 @@ static int sbd_request_port(struct uart_port *uport) { const char *err = KERN_ERR "sbd: Unable to reserve MMIO resource\n"; struct sbd_duart *duart = to_sport(uport)->duart; - int map_guard; int ret = 0; if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING, @@ -706,11 +703,11 @@ static int sbd_request_port(struct uart_port *uport) printk(err); return -EBUSY; } - map_guard = atomic_add_return(1, &duart->map_guard); - if (map_guard == 1) { + refcount_inc(&duart->map_guard); + if (refcount_read(&duart->map_guard) == 1) { if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING, "sb1250-duart")) { - atomic_add(-1, &duart->map_guard); + refcount_dec(&duart->map_guard); printk(err); ret = -EBUSY; } @@ -718,8 +715,7 @@ static int sbd_request_port(struct uart_port *uport) if (!ret) { ret = sbd_map_port(uport); if (ret) { - map_guard = atomic_add_return(-1, &duart->map_guard); - if (!map_guard) + if (refcount_dec_and_test(&duart->map_guard)) release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING); } -- 2.7.4