net, rds: convert rds_incoming.i_refcount 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: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
50d61ff789
commit
b7f0292094
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/rds.h>
|
#include <linux/rds.h>
|
||||||
#include <linux/rhashtable.h>
|
#include <linux/rhashtable.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
|
||||||
|
@ -261,7 +262,7 @@ struct rds_ext_header_rdma_dest {
|
||||||
#define RDS_MSG_RX_CMSG 3
|
#define RDS_MSG_RX_CMSG 3
|
||||||
|
|
||||||
struct rds_incoming {
|
struct rds_incoming {
|
||||||
atomic_t i_refcount;
|
refcount_t i_refcount;
|
||||||
struct list_head i_item;
|
struct list_head i_item;
|
||||||
struct rds_connection *i_conn;
|
struct rds_connection *i_conn;
|
||||||
struct rds_conn_path *i_conn_path;
|
struct rds_conn_path *i_conn_path;
|
||||||
|
|
|
@ -45,7 +45,7 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
atomic_set(&inc->i_refcount, 1);
|
refcount_set(&inc->i_refcount, 1);
|
||||||
INIT_LIST_HEAD(&inc->i_item);
|
INIT_LIST_HEAD(&inc->i_item);
|
||||||
inc->i_conn = conn;
|
inc->i_conn = conn;
|
||||||
inc->i_saddr = saddr;
|
inc->i_saddr = saddr;
|
||||||
|
@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(rds_inc_init);
|
||||||
void rds_inc_path_init(struct rds_incoming *inc, struct rds_conn_path *cp,
|
void rds_inc_path_init(struct rds_incoming *inc, struct rds_conn_path *cp,
|
||||||
__be32 saddr)
|
__be32 saddr)
|
||||||
{
|
{
|
||||||
atomic_set(&inc->i_refcount, 1);
|
refcount_set(&inc->i_refcount, 1);
|
||||||
INIT_LIST_HEAD(&inc->i_item);
|
INIT_LIST_HEAD(&inc->i_item);
|
||||||
inc->i_conn = cp->cp_conn;
|
inc->i_conn = cp->cp_conn;
|
||||||
inc->i_conn_path = cp;
|
inc->i_conn_path = cp;
|
||||||
|
@ -74,14 +74,14 @@ EXPORT_SYMBOL_GPL(rds_inc_path_init);
|
||||||
|
|
||||||
static void rds_inc_addref(struct rds_incoming *inc)
|
static void rds_inc_addref(struct rds_incoming *inc)
|
||||||
{
|
{
|
||||||
rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount));
|
rdsdebug("addref inc %p ref %d\n", inc, refcount_read(&inc->i_refcount));
|
||||||
atomic_inc(&inc->i_refcount);
|
refcount_inc(&inc->i_refcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rds_inc_put(struct rds_incoming *inc)
|
void rds_inc_put(struct rds_incoming *inc)
|
||||||
{
|
{
|
||||||
rdsdebug("put inc %p ref %d\n", inc, atomic_read(&inc->i_refcount));
|
rdsdebug("put inc %p ref %d\n", inc, refcount_read(&inc->i_refcount));
|
||||||
if (atomic_dec_and_test(&inc->i_refcount)) {
|
if (refcount_dec_and_test(&inc->i_refcount)) {
|
||||||
BUG_ON(!list_empty(&inc->i_item));
|
BUG_ON(!list_empty(&inc->i_item));
|
||||||
|
|
||||||
inc->i_conn->c_trans->inc_free(inc);
|
inc->i_conn->c_trans->inc_free(inc);
|
||||||
|
|
Loading…
Reference in New Issue