提交 2bf3a09e 编写于 作者: T Tilman Schmidt 提交者: David S. Miller

isdn/capi: handle CAPI 2.0 message parser failures

Have callers of capi_cmsg2message and capi_message2cmsg handle
non-zero return values indicating failure.
Signed-off-by: NTilman Schmidt <tilman@imap.cc>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 5510ab18
...@@ -506,7 +506,10 @@ static void send_message(capidrv_contr *card, _cmsg *cmsg) ...@@ -506,7 +506,10 @@ static void send_message(capidrv_contr *card, _cmsg *cmsg)
struct sk_buff *skb; struct sk_buff *skb;
size_t len; size_t len;
capi_cmsg2message(cmsg, cmsg->buf); if (capi_cmsg2message(cmsg, cmsg->buf)) {
printk(KERN_ERR "capidrv::send_message: parser failure\n");
return;
}
len = CAPIMSG_LEN(cmsg->buf); len = CAPIMSG_LEN(cmsg->buf);
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) { if (!skb) {
...@@ -1578,7 +1581,12 @@ static _cmsg s_cmsg; ...@@ -1578,7 +1581,12 @@ static _cmsg s_cmsg;
static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
{ {
capi_message2cmsg(&s_cmsg, skb->data); if (capi_message2cmsg(&s_cmsg, skb->data)) {
printk(KERN_ERR "capidrv: applid=%d: received invalid message\n",
ap->applid);
kfree_skb(skb);
return;
}
if (debugmode > 3) { if (debugmode > 3) {
_cdebbuf *cdb = capi_cmsg2str(&s_cmsg); _cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
...@@ -1903,7 +1911,11 @@ static int capidrv_command(isdn_ctrl *c, capidrv_contr *card) ...@@ -1903,7 +1911,11 @@ static int capidrv_command(isdn_ctrl *c, capidrv_contr *card)
NULL, /* Useruserdata */ NULL, /* Useruserdata */
NULL /* Facilitydataarray */ NULL /* Facilitydataarray */
); );
capi_cmsg2message(&cmdcmsg, cmdcmsg.buf); if (capi_cmsg2message(&cmdcmsg, cmdcmsg.buf)) {
printk(KERN_ERR "capidrv-%d: capidrv_command: parser failure\n",
card->contrnr);
return -EINVAL;
}
plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP); plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP);
send_message(card, &cmdcmsg); send_message(card, &cmdcmsg);
return 0; return 0;
...@@ -2090,7 +2102,11 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb) ...@@ -2090,7 +2102,11 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0) if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
return 0; return 0;
capi_cmsg2message(&sendcmsg, sendcmsg.buf); if (capi_cmsg2message(&sendcmsg, sendcmsg.buf)) {
printk(KERN_ERR "capidrv-%d: if_sendbuf: parser failure\n",
card->contrnr);
return -EINVAL;
}
msglen = CAPIMSG_LEN(sendcmsg.buf); msglen = CAPIMSG_LEN(sendcmsg.buf);
if (skb_headroom(skb) < msglen) { if (skb_headroom(skb) < msglen) {
struct sk_buff *nskb = skb_realloc_headroom(skb, msglen); struct sk_buff *nskb = skb_realloc_headroom(skb, msglen);
......
...@@ -647,7 +647,13 @@ int gigaset_isdn_icall(struct at_state_t *at_state) ...@@ -647,7 +647,13 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
__func__); __func__);
break; break;
} }
capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize)); if (capi_cmsg2message(&iif->hcmsg,
__skb_put(skb, msgsize))) {
dev_err(cs->dev, "%s: message parser failure\n",
__func__);
dev_kfree_skb_any(skb);
break;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
/* add to listeners on this B channel, update state */ /* add to listeners on this B channel, update state */
...@@ -693,7 +699,12 @@ static void send_disconnect_ind(struct bc_state *bcs, ...@@ -693,7 +699,12 @@ static void send_disconnect_ind(struct bc_state *bcs,
dev_err(cs->dev, "%s: out of memory\n", __func__); dev_err(cs->dev, "%s: out of memory\n", __func__);
return; return;
} }
capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN)); if (capi_cmsg2message(&iif->hcmsg,
__skb_put(skb, CAPI_DISCONNECT_IND_LEN))) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
} }
...@@ -723,8 +734,12 @@ static void send_disconnect_b3_ind(struct bc_state *bcs, ...@@ -723,8 +734,12 @@ static void send_disconnect_b3_ind(struct bc_state *bcs,
dev_err(cs->dev, "%s: out of memory\n", __func__); dev_err(cs->dev, "%s: out of memory\n", __func__);
return; return;
} }
capi_cmsg2message(&iif->hcmsg, if (capi_cmsg2message(&iif->hcmsg,
__skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN)); __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
} }
...@@ -789,7 +804,11 @@ void gigaset_isdn_connD(struct bc_state *bcs) ...@@ -789,7 +804,11 @@ void gigaset_isdn_connD(struct bc_state *bcs)
dev_err(cs->dev, "%s: out of memory\n", __func__); dev_err(cs->dev, "%s: out of memory\n", __func__);
return; return;
} }
capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize)); if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
} }
...@@ -889,7 +908,11 @@ void gigaset_isdn_connB(struct bc_state *bcs) ...@@ -889,7 +908,11 @@ void gigaset_isdn_connB(struct bc_state *bcs)
dev_err(cs->dev, "%s: out of memory\n", __func__); dev_err(cs->dev, "%s: out of memory\n", __func__);
return; return;
} }
capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize)); if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
} }
...@@ -1096,13 +1119,19 @@ static void send_conf(struct gigaset_capi_ctr *iif, ...@@ -1096,13 +1119,19 @@ static void send_conf(struct gigaset_capi_ctr *iif,
struct sk_buff *skb, struct sk_buff *skb,
u16 info) u16 info)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* /*
* _CONF replies always only have NCCI and Info parameters * _CONF replies always only have NCCI and Info parameters
* so they'll fit into the _REQ message skb * so they'll fit into the _REQ message skb
*/ */
capi_cmsg_answer(&iif->acmsg); capi_cmsg_answer(&iif->acmsg);
iif->acmsg.Info = info; iif->acmsg.Info = info;
capi_cmsg2message(&iif->acmsg, skb->data); if (capi_cmsg2message(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
__skb_trim(skb, CAPI_STDCONF_LEN); __skb_trim(skb, CAPI_STDCONF_LEN);
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
...@@ -1124,7 +1153,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif, ...@@ -1124,7 +1153,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
static u8 confparam[10]; /* max. 9 octets + length byte */ static u8 confparam[10]; /* max. 9 octets + length byte */
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* /*
...@@ -1223,6 +1256,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif, ...@@ -1223,6 +1256,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
} }
/* send FACILITY_CONF with given Info and confirmation parameter */ /* send FACILITY_CONF with given Info and confirmation parameter */
dev_kfree_skb_any(skb);
capi_cmsg_answer(cmsg); capi_cmsg_answer(cmsg);
cmsg->Info = info; cmsg->Info = info;
cmsg->FacilityConfirmationParameter = confparam; cmsg->FacilityConfirmationParameter = confparam;
...@@ -1232,7 +1266,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif, ...@@ -1232,7 +1266,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
dev_err(cs->dev, "%s: out of memory\n", __func__); dev_err(cs->dev, "%s: out of memory\n", __func__);
return; return;
} }
capi_cmsg2message(cmsg, __skb_put(cskb, msgsize)); if (capi_cmsg2message(cmsg, __skb_put(cskb, msgsize))) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(cskb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, cskb); capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
} }
...@@ -1246,8 +1284,14 @@ static void do_listen_req(struct gigaset_capi_ctr *iif, ...@@ -1246,8 +1284,14 @@ static void do_listen_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap, struct gigaset_capi_appl *ap,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* decode message */ /* decode message */
capi_message2cmsg(&iif->acmsg, skb->data); if (capi_message2cmsg(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
/* store listening parameters */ /* store listening parameters */
...@@ -1264,8 +1308,14 @@ static void do_alert_req(struct gigaset_capi_ctr *iif, ...@@ -1264,8 +1308,14 @@ static void do_alert_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap, struct gigaset_capi_appl *ap,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* decode message */ /* decode message */
capi_message2cmsg(&iif->acmsg, skb->data); if (capi_message2cmsg(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, CapiAlertAlreadySent); send_conf(iif, ap, skb, CapiAlertAlreadySent);
} }
...@@ -1290,7 +1340,11 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, ...@@ -1290,7 +1340,11 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
u16 info; u16 info;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* get free B channel & construct PLCI */ /* get free B channel & construct PLCI */
...@@ -1577,7 +1631,11 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif, ...@@ -1577,7 +1631,11 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
int channel; int channel;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
...@@ -1743,7 +1801,11 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif, ...@@ -1743,7 +1801,11 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
int channel; int channel;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number from PLCI */ /* extract and check channel number from PLCI */
...@@ -1788,7 +1850,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif, ...@@ -1788,7 +1850,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
u8 command; u8 command;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number and NCCI */ /* extract and check channel number and NCCI */
...@@ -1828,7 +1894,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif, ...@@ -1828,7 +1894,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
capi_cmsg_header(cmsg, ap->id, command, CAPI_IND, capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
ap->nextMessageNumber++, cmsg->adr.adrNCCI); ap->nextMessageNumber++, cmsg->adr.adrNCCI);
__skb_trim(skb, msgsize); __skb_trim(skb, msgsize);
capi_cmsg2message(cmsg, skb->data); if (capi_cmsg2message(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb); capi_ctr_handle_message(&iif->ctr, ap->id, skb);
} }
...@@ -1850,7 +1920,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif, ...@@ -1850,7 +1920,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
int channel; int channel;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number from PLCI */ /* extract and check channel number from PLCI */
...@@ -1906,8 +1980,14 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif, ...@@ -1906,8 +1980,14 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
kfree(b3cmsg); kfree(b3cmsg);
return; return;
} }
capi_cmsg2message(b3cmsg, if (capi_cmsg2message(b3cmsg,
__skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN)); __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
dev_err(cs->dev, "%s: message parser failure\n",
__func__);
kfree(b3cmsg);
dev_kfree_skb_any(b3skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, b3cmsg); dump_cmsg(DEBUG_CMD, __func__, b3cmsg);
kfree(b3cmsg); kfree(b3cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, b3skb); capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
...@@ -1938,7 +2018,11 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif, ...@@ -1938,7 +2018,11 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
int channel; int channel;
/* decode message */ /* decode message */
capi_message2cmsg(cmsg, skb->data); if (capi_message2cmsg(cmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, cmsg); dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number and NCCI */ /* extract and check channel number and NCCI */
...@@ -2055,8 +2139,14 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif, ...@@ -2055,8 +2139,14 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap, struct gigaset_capi_appl *ap,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* decode message */ /* decode message */
capi_message2cmsg(&iif->acmsg, skb->data); if (capi_message2cmsg(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, send_conf(iif, ap, skb,
CapiResetProcedureNotSupportedByCurrentProtocol); CapiResetProcedureNotSupportedByCurrentProtocol);
...@@ -2069,8 +2159,14 @@ static void do_unsupported(struct gigaset_capi_ctr *iif, ...@@ -2069,8 +2159,14 @@ static void do_unsupported(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap, struct gigaset_capi_appl *ap,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* decode message */ /* decode message */
capi_message2cmsg(&iif->acmsg, skb->data); if (capi_message2cmsg(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState); send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
} }
...@@ -2082,8 +2178,14 @@ static void do_nothing(struct gigaset_capi_ctr *iif, ...@@ -2082,8 +2178,14 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap, struct gigaset_capi_appl *ap,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct cardstate *cs = iif->ctr.driverdata;
/* decode message */ /* decode message */
capi_message2cmsg(&iif->acmsg, skb->data); if (capi_message2cmsg(&iif->acmsg, skb->data)) {
dev_err(cs->dev, "%s: message parser failure\n", __func__);
dev_kfree_skb_any(skb);
return;
}
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册