|
@@ -250,6 +250,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
|
|
|
l -= 12;
|
|
|
if (l <= 0)
|
|
|
return;
|
|
|
+ if (l > 64)
|
|
|
+ l = 64; /* arbitrary limit */
|
|
|
dbgline = kmalloc(3 * l, GFP_ATOMIC);
|
|
|
if (!dbgline)
|
|
|
return;
|
|
@@ -645,7 +647,13 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
|
|
|
__func__);
|
|
|
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);
|
|
|
|
|
|
/* add to listeners on this B channel, update state */
|
|
@@ -691,7 +699,12 @@ static void send_disconnect_ind(struct bc_state *bcs,
|
|
|
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
|
|
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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
|
}
|
|
@@ -721,8 +734,12 @@ static void send_disconnect_b3_ind(struct bc_state *bcs,
|
|
|
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
|
|
return;
|
|
|
}
|
|
|
- capi_cmsg2message(&iif->hcmsg,
|
|
|
- __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
|
|
|
+ if (capi_cmsg2message(&iif->hcmsg,
|
|
|
+ __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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
|
}
|
|
@@ -787,7 +804,11 @@ void gigaset_isdn_connD(struct bc_state *bcs)
|
|
|
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
|
|
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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
|
}
|
|
@@ -887,7 +908,11 @@ void gigaset_isdn_connB(struct bc_state *bcs)
|
|
|
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
|
|
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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
|
}
|
|
@@ -1094,13 +1119,19 @@ static void send_conf(struct gigaset_capi_ctr *iif,
|
|
|
struct sk_buff *skb,
|
|
|
u16 info)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/*
|
|
|
* _CONF replies always only have NCCI and Info parameters
|
|
|
* so they'll fit into the _REQ message skb
|
|
|
*/
|
|
|
capi_cmsg_answer(&iif->acmsg);
|
|
|
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);
|
|
|
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
@@ -1122,7 +1153,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
|
|
|
static u8 confparam[10]; /* max. 9 octets + length byte */
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/*
|
|
@@ -1180,6 +1215,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
|
|
|
confparam[3] = 2; /* length */
|
|
|
capimsg_setu16(confparam, 4,
|
|
|
CapiSupplementaryServiceNotSupported);
|
|
|
+ break;
|
|
|
}
|
|
|
info = CapiSuccess;
|
|
|
confparam[3] = 2; /* length */
|
|
@@ -1220,6 +1256,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
|
|
|
}
|
|
|
|
|
|
/* send FACILITY_CONF with given Info and confirmation parameter */
|
|
|
+ dev_kfree_skb_any(skb);
|
|
|
capi_cmsg_answer(cmsg);
|
|
|
cmsg->Info = info;
|
|
|
cmsg->FacilityConfirmationParameter = confparam;
|
|
@@ -1229,7 +1266,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
|
|
|
dev_err(cs->dev, "%s: out of memory\n", __func__);
|
|
|
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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
|
|
|
}
|
|
@@ -1243,8 +1284,14 @@ static void do_listen_req(struct gigaset_capi_ctr *iif,
|
|
|
struct gigaset_capi_appl *ap,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/* 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);
|
|
|
|
|
|
/* store listening parameters */
|
|
@@ -1261,8 +1308,14 @@ static void do_alert_req(struct gigaset_capi_ctr *iif,
|
|
|
struct gigaset_capi_appl *ap,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/* 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);
|
|
|
send_conf(iif, ap, skb, CapiAlertAlreadySent);
|
|
|
}
|
|
@@ -1287,7 +1340,11 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
|
|
|
u16 info;
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/* get free B channel & construct PLCI */
|
|
@@ -1574,7 +1631,11 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
|
|
|
int channel;
|
|
|
|
|
|
/* 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);
|
|
|
dev_kfree_skb_any(skb);
|
|
|
|
|
@@ -1740,7 +1801,11 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
|
|
|
int channel;
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/* extract and check channel number from PLCI */
|
|
@@ -1785,7 +1850,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
|
|
|
u8 command;
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/* extract and check channel number and NCCI */
|
|
@@ -1825,7 +1894,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
|
|
|
capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
|
|
|
ap->nextMessageNumber++, cmsg->adr.adrNCCI);
|
|
|
__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);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
|
|
|
}
|
|
@@ -1847,7 +1920,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
|
|
|
int channel;
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/* extract and check channel number from PLCI */
|
|
@@ -1903,8 +1980,14 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
|
|
|
kfree(b3cmsg);
|
|
|
return;
|
|
|
}
|
|
|
- capi_cmsg2message(b3cmsg,
|
|
|
- __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
|
|
|
+ if (capi_cmsg2message(b3cmsg,
|
|
|
+ __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);
|
|
|
kfree(b3cmsg);
|
|
|
capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
|
|
@@ -1935,7 +2018,11 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
|
|
|
int channel;
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
/* extract and check channel number and NCCI */
|
|
@@ -2052,8 +2139,14 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
|
|
|
struct gigaset_capi_appl *ap,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/* 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);
|
|
|
send_conf(iif, ap, skb,
|
|
|
CapiResetProcedureNotSupportedByCurrentProtocol);
|
|
@@ -2066,8 +2159,14 @@ static void do_unsupported(struct gigaset_capi_ctr *iif,
|
|
|
struct gigaset_capi_appl *ap,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/* 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);
|
|
|
send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
|
|
|
}
|
|
@@ -2079,8 +2178,14 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
|
|
|
struct gigaset_capi_appl *ap,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct cardstate *cs = iif->ctr.driverdata;
|
|
|
+
|
|
|
/* 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);
|
|
|
dev_kfree_skb_any(skb);
|
|
|
}
|
|
@@ -2357,7 +2462,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
|
|
|
struct gigaset_capi_ctr *iif;
|
|
|
int rc;
|
|
|
|
|
|
- iif = kmalloc(sizeof(*iif), GFP_KERNEL);
|
|
|
+ iif = kzalloc(sizeof(*iif), GFP_KERNEL);
|
|
|
if (!iif) {
|
|
|
pr_err("%s: out of memory\n", __func__);
|
|
|
return -ENOMEM;
|
|
@@ -2366,7 +2471,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
|
|
|
/* prepare controller structure */
|
|
|
iif->ctr.owner = THIS_MODULE;
|
|
|
iif->ctr.driverdata = cs;
|
|
|
- strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
|
|
|
+ strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name) - 1);
|
|
|
iif->ctr.driver_name = "gigaset";
|
|
|
iif->ctr.load_firmware = NULL;
|
|
|
iif->ctr.reset_ctr = NULL;
|