Commit c9a6ce50 authored by Divy Le Ray's avatar Divy Le Ray Committed by David S. Miller

cxgb3 - tighten checks on TID values

Enforce validity checks on connection ids
Signed-off-by: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent e22bb45d
...@@ -79,9 +79,17 @@ static inline struct t3c_tid_entry *lookup_tid(const struct tid_info *t, ...@@ -79,9 +79,17 @@ static inline struct t3c_tid_entry *lookup_tid(const struct tid_info *t,
static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t, static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t,
unsigned int tid) unsigned int tid)
{ {
union listen_entry *e;
if (tid < t->stid_base || tid >= t->stid_base + t->nstids) if (tid < t->stid_base || tid >= t->stid_base + t->nstids)
return NULL; return NULL;
return &(stid2entry(t, tid)->t3c_tid);
e = stid2entry(t, tid);
if ((void *)e->next >= (void *)t->tid_tab &&
(void *)e->next < (void *)&t->atid_tab[t->natids])
return NULL;
return &e->t3c_tid;
} }
/* /*
...@@ -90,9 +98,17 @@ static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t, ...@@ -90,9 +98,17 @@ static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t,
static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t, static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t,
unsigned int tid) unsigned int tid)
{ {
union active_open_entry *e;
if (tid < t->atid_base || tid >= t->atid_base + t->natids) if (tid < t->atid_base || tid >= t->atid_base + t->natids)
return NULL; return NULL;
return &(atid2entry(t, tid)->t3c_tid);
e = atid2entry(t, tid);
if ((void *)e->next >= (void *)t->tid_tab &&
(void *)e->next < (void *)&t->atid_tab[t->natids])
return NULL;
return &e->t3c_tid;
} }
int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n); int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n);
......
...@@ -57,7 +57,7 @@ static DEFINE_RWLOCK(adapter_list_lock); ...@@ -57,7 +57,7 @@ static DEFINE_RWLOCK(adapter_list_lock);
static LIST_HEAD(adapter_list); static LIST_HEAD(adapter_list);
static const unsigned int MAX_ATIDS = 64 * 1024; static const unsigned int MAX_ATIDS = 64 * 1024;
static const unsigned int ATID_BASE = 0x100000; static const unsigned int ATID_BASE = 0x10000;
static inline int offload_activated(struct t3cdev *tdev) static inline int offload_activated(struct t3cdev *tdev)
{ {
...@@ -694,10 +694,19 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb) ...@@ -694,10 +694,19 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
{ {
struct cpl_pass_accept_req *req = cplhdr(skb); struct cpl_pass_accept_req *req = cplhdr(skb);
unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
struct tid_info *t = &(T3C_DATA(dev))->tid_maps;
struct t3c_tid_entry *t3c_tid; struct t3c_tid_entry *t3c_tid;
unsigned int tid = GET_TID(req);
t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid); if (unlikely(tid >= t->ntids)) {
if (t3c_tid->ctx && t3c_tid->client->handlers && printk("%s: passive open TID %u too large\n",
dev->name, tid);
t3_fatal_err(tdev2adap(dev));
return CPL_RET_BUF_DONE;
}
t3c_tid = lookup_stid(t, stid);
if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) { t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) {
return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ] return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]
(dev, skb, t3c_tid->ctx); (dev, skb, t3c_tid->ctx);
...@@ -779,16 +788,25 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb) ...@@ -779,16 +788,25 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
{ {
struct cpl_act_establish *req = cplhdr(skb); struct cpl_act_establish *req = cplhdr(skb);
unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
struct tid_info *t = &(T3C_DATA(dev))->tid_maps;
struct t3c_tid_entry *t3c_tid; struct t3c_tid_entry *t3c_tid;
unsigned int tid = GET_TID(req);
t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid); if (unlikely(tid >= t->ntids)) {
printk("%s: active establish TID %u too large\n",
dev->name, tid);
t3_fatal_err(tdev2adap(dev));
return CPL_RET_BUF_DONE;
}
t3c_tid = lookup_atid(t, atid);
if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) { t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) {
return t3c_tid->client->handlers[CPL_ACT_ESTABLISH] return t3c_tid->client->handlers[CPL_ACT_ESTABLISH]
(dev, skb, t3c_tid->ctx); (dev, skb, t3c_tid->ctx);
} else { } else {
printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
dev->name, CPL_PASS_ACCEPT_REQ); dev->name, CPL_ACT_ESTABLISH);
return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment