aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2007-08-21 23:49:26 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:49 -0400
commitc9a6ce500d78932c43361eae28c3de81b3660c77 (patch)
treed0cb68fb610a4085ee4c28164851b7ee142aa851 /drivers
parente22bb45d772b5e5c850a6223c2a3245f520de641 (diff)
cxgb3 - tighten checks on TID values
Enforce validity checks on connection ids Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/cxgb3/cxgb3_defs.h20
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c28
2 files changed, 41 insertions, 7 deletions
diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h
index 483a594210a7..45e92164c260 100644
--- a/drivers/net/cxgb3/cxgb3_defs.h
+++ b/drivers/net/cxgb3/cxgb3_defs.h
@@ -79,9 +79,17 @@ static inline struct t3c_tid_entry *lookup_tid(const struct tid_info *t,
79static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t, 79static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t,
80 unsigned int tid) 80 unsigned int tid)
81{ 81{
82 union listen_entry *e;
83
82 if (tid < t->stid_base || tid >= t->stid_base + t->nstids) 84 if (tid < t->stid_base || tid >= t->stid_base + t->nstids)
83 return NULL; 85 return NULL;
84 return &(stid2entry(t, tid)->t3c_tid); 86
87 e = stid2entry(t, tid);
88 if ((void *)e->next >= (void *)t->tid_tab &&
89 (void *)e->next < (void *)&t->atid_tab[t->natids])
90 return NULL;
91
92 return &e->t3c_tid;
85} 93}
86 94
87/* 95/*
@@ -90,9 +98,17 @@ static inline struct t3c_tid_entry *lookup_stid(const struct tid_info *t,
90static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t, 98static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t,
91 unsigned int tid) 99 unsigned int tid)
92{ 100{
101 union active_open_entry *e;
102
93 if (tid < t->atid_base || tid >= t->atid_base + t->natids) 103 if (tid < t->atid_base || tid >= t->atid_base + t->natids)
94 return NULL; 104 return NULL;
95 return &(atid2entry(t, tid)->t3c_tid); 105
106 e = atid2entry(t, tid);
107 if ((void *)e->next >= (void *)t->tid_tab &&
108 (void *)e->next < (void *)&t->atid_tab[t->natids])
109 return NULL;
110
111 return &e->t3c_tid;
96} 112}
97 113
98int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n); 114int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n);
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index bac9214170ae..1c8eec38bde3 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -57,7 +57,7 @@ static DEFINE_RWLOCK(adapter_list_lock);
57static LIST_HEAD(adapter_list); 57static LIST_HEAD(adapter_list);
58 58
59static const unsigned int MAX_ATIDS = 64 * 1024; 59static const unsigned int MAX_ATIDS = 64 * 1024;
60static const unsigned int ATID_BASE = 0x100000; 60static const unsigned int ATID_BASE = 0x10000;
61 61
62static inline int offload_activated(struct t3cdev *tdev) 62static inline int offload_activated(struct t3cdev *tdev)
63{ 63{
@@ -694,10 +694,19 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
694{ 694{
695 struct cpl_pass_accept_req *req = cplhdr(skb); 695 struct cpl_pass_accept_req *req = cplhdr(skb);
696 unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); 696 unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
697 struct tid_info *t = &(T3C_DATA(dev))->tid_maps;
697 struct t3c_tid_entry *t3c_tid; 698 struct t3c_tid_entry *t3c_tid;
699 unsigned int tid = GET_TID(req);
698 700
699 t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid); 701 if (unlikely(tid >= t->ntids)) {
700 if (t3c_tid->ctx && t3c_tid->client->handlers && 702 printk("%s: passive open TID %u too large\n",
703 dev->name, tid);
704 t3_fatal_err(tdev2adap(dev));
705 return CPL_RET_BUF_DONE;
706 }
707
708 t3c_tid = lookup_stid(t, stid);
709 if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
701 t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) { 710 t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) {
702 return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ] 711 return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]
703 (dev, skb, t3c_tid->ctx); 712 (dev, skb, t3c_tid->ctx);
@@ -779,16 +788,25 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
779{ 788{
780 struct cpl_act_establish *req = cplhdr(skb); 789 struct cpl_act_establish *req = cplhdr(skb);
781 unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); 790 unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
791 struct tid_info *t = &(T3C_DATA(dev))->tid_maps;
782 struct t3c_tid_entry *t3c_tid; 792 struct t3c_tid_entry *t3c_tid;
793 unsigned int tid = GET_TID(req);
783 794
784 t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid); 795 if (unlikely(tid >= t->ntids)) {
796 printk("%s: active establish TID %u too large\n",
797 dev->name, tid);
798 t3_fatal_err(tdev2adap(dev));
799 return CPL_RET_BUF_DONE;
800 }
801
802 t3c_tid = lookup_atid(t, atid);
785 if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 803 if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
786 t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) { 804 t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) {
787 return t3c_tid->client->handlers[CPL_ACT_ESTABLISH] 805 return t3c_tid->client->handlers[CPL_ACT_ESTABLISH]
788 (dev, skb, t3c_tid->ctx); 806 (dev, skb, t3c_tid->ctx);
789 } else { 807 } else {
790 printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 808 printk(KERN_ERR "%s: received clientless CPL command 0x%x\n",
791 dev->name, CPL_PASS_ACCEPT_REQ); 809 dev->name, CPL_ACT_ESTABLISH);
792 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 810 return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG;
793 } 811 }
794} 812}