aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi/kcapi.c
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@suse.de>2007-02-28 23:13:50 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-01 17:53:39 -0500
commit17f0cd2f350b90b28301e27fe0e39f34bfe7e730 (patch)
tree6baba85d4f3b83398dc5a412b328bfcef1633548 /drivers/isdn/capi/kcapi.c
parent34bbd704051c9d053d69e90569a3a2365f4c7b50 (diff)
[PATCH] Fix buffer overflow and races in capi debug functions
The CAPI trace debug functions were using a fixed size buffer, which can be overflowed if wrong formatted CAPI messages were sent to the kernel capi layer. The code was also not protected against multiple callers. This fix bug 8028. Additionally the patch make the CAPI trace functions optional. Signed-off-by: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/isdn/capi/kcapi.c')
-rw-r--r--drivers/isdn/capi/kcapi.c77
1 files changed, 55 insertions, 22 deletions
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 783a25526315..3ed34f7a1c4f 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -276,10 +276,17 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
276 int showctl = 0; 276 int showctl = 0;
277 u8 cmd, subcmd; 277 u8 cmd, subcmd;
278 unsigned long flags; 278 unsigned long flags;
279 _cdebbuf *cdb;
279 280
280 if (card->cardstate != CARD_RUNNING) { 281 if (card->cardstate != CARD_RUNNING) {
281 printk(KERN_INFO "kcapi: controller %d not active, got: %s", 282 cdb = capi_message2str(skb->data);
282 card->cnr, capi_message2str(skb->data)); 283 if (cdb) {
284 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
285 card->cnr, cdb->buf);
286 cdebbuf_free(cdb);
287 } else
288 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
289 card->cnr);
283 goto error; 290 goto error;
284 } 291 }
285 292
@@ -295,15 +302,21 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
295 showctl |= (card->traceflag & 1); 302 showctl |= (card->traceflag & 1);
296 if (showctl & 2) { 303 if (showctl & 2) {
297 if (showctl & 1) { 304 if (showctl & 1) {
298 printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", 305 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
299 (unsigned long) card->cnr, 306 card->cnr, CAPIMSG_APPID(skb->data),
300 CAPIMSG_APPID(skb->data),
301 capi_cmd2str(cmd, subcmd), 307 capi_cmd2str(cmd, subcmd),
302 CAPIMSG_LEN(skb->data)); 308 CAPIMSG_LEN(skb->data));
303 } else { 309 } else {
304 printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", 310 cdb = capi_message2str(skb->data);
305 (unsigned long) card->cnr, 311 if (cdb) {
306 capi_message2str(skb->data)); 312 printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
313 card->cnr, cdb->buf);
314 cdebbuf_free(cdb);
315 } else
316 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
317 card->cnr, CAPIMSG_APPID(skb->data),
318 capi_cmd2str(cmd, subcmd),
319 CAPIMSG_LEN(skb->data));
307 } 320 }
308 321
309 } 322 }
@@ -312,8 +325,15 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
312 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 325 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
313 if ((!ap) || (ap->release_in_progress)) { 326 if ((!ap) || (ap->release_in_progress)) {
314 read_unlock_irqrestore(&application_lock, flags); 327 read_unlock_irqrestore(&application_lock, flags);
315 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 328 cdb = capi_message2str(skb->data);
316 CAPIMSG_APPID(skb->data), capi_message2str(skb->data)); 329 if (cdb) {
330 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
331 CAPIMSG_APPID(skb->data), cdb->buf);
332 cdebbuf_free(cdb);
333 } else
334 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
335 CAPIMSG_APPID(skb->data),
336 capi_cmd2str(cmd, subcmd));
317 goto error; 337 goto error;
318 } 338 }
319 skb_queue_tail(&ap->recv_queue, skb); 339 skb_queue_tail(&ap->recv_queue, skb);
@@ -332,7 +352,7 @@ void capi_ctr_ready(struct capi_ctr * card)
332{ 352{
333 card->cardstate = CARD_RUNNING; 353 card->cardstate = CARD_RUNNING;
334 354
335 printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", 355 printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
336 card->cnr, card->name); 356 card->cnr, card->name);
337 357
338 notify_push(KCI_CONTRUP, card->cnr, 0, 0); 358 notify_push(KCI_CONTRUP, card->cnr, 0, 0);
@@ -364,7 +384,7 @@ void capi_ctr_reseted(struct capi_ctr * card)
364 capi_ctr_put(card); 384 capi_ctr_put(card);
365 } 385 }
366 386
367 printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr); 387 printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr);
368 388
369 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 389 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
370} 390}
@@ -374,7 +394,7 @@ EXPORT_SYMBOL(capi_ctr_reseted);
374void capi_ctr_suspend_output(struct capi_ctr *card) 394void capi_ctr_suspend_output(struct capi_ctr *card)
375{ 395{
376 if (!card->blocked) { 396 if (!card->blocked) {
377 printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr); 397 printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr);
378 card->blocked = 1; 398 card->blocked = 1;
379 } 399 }
380} 400}
@@ -384,7 +404,7 @@ EXPORT_SYMBOL(capi_ctr_suspend_output);
384void capi_ctr_resume_output(struct capi_ctr *card) 404void capi_ctr_resume_output(struct capi_ctr *card)
385{ 405{
386 if (card->blocked) { 406 if (card->blocked) {
387 printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr); 407 printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr);
388 card->blocked = 0; 408 card->blocked = 0;
389 } 409 }
390} 410}
@@ -432,7 +452,7 @@ attach_capi_ctr(struct capi_ctr *card)
432 } 452 }
433 453
434 ncards++; 454 ncards++;
435 printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", 455 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",
436 card->cnr, card->name); 456 card->cnr, card->name);
437 return 0; 457 return 0;
438} 458}
@@ -451,7 +471,7 @@ int detach_capi_ctr(struct capi_ctr *card)
451 card->procent = NULL; 471 card->procent = NULL;
452 } 472 }
453 capi_cards[card->cnr - 1] = NULL; 473 capi_cards[card->cnr - 1] = NULL;
454 printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", 474 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n",
455 card->cnr, card->name); 475 card->cnr, card->name);
456 476
457 return 0; 477 return 0;
@@ -623,17 +643,25 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
623 showctl |= (card->traceflag & 1); 643 showctl |= (card->traceflag & 1);
624 if (showctl & 2) { 644 if (showctl & 2) {
625 if (showctl & 1) { 645 if (showctl & 1) {
626 printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", 646 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
627 CAPIMSG_CONTROLLER(skb->data), 647 CAPIMSG_CONTROLLER(skb->data),
628 CAPIMSG_APPID(skb->data), 648 CAPIMSG_APPID(skb->data),
629 capi_cmd2str(cmd, subcmd), 649 capi_cmd2str(cmd, subcmd),
630 CAPIMSG_LEN(skb->data)); 650 CAPIMSG_LEN(skb->data));
631 } else { 651 } else {
632 printk(KERN_DEBUG "kcapi: put [%#x] %s\n", 652 _cdebbuf *cdb = capi_message2str(skb->data);
633 CAPIMSG_CONTROLLER(skb->data), 653 if (cdb) {
634 capi_message2str(skb->data)); 654 printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
655 CAPIMSG_CONTROLLER(skb->data),
656 cdb->buf);
657 cdebbuf_free(cdb);
658 } else
659 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
660 CAPIMSG_CONTROLLER(skb->data),
661 CAPIMSG_APPID(skb->data),
662 capi_cmd2str(cmd, subcmd),
663 CAPIMSG_LEN(skb->data));
635 } 664 }
636
637 } 665 }
638 return card->send_message(card, skb); 666 return card->send_message(card, skb);
639} 667}
@@ -894,7 +922,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
894 return -ESRCH; 922 return -ESRCH;
895 923
896 card->traceflag = fdef.flag; 924 card->traceflag = fdef.flag;
897 printk(KERN_INFO "kcapi: contr %d set trace=%d\n", 925 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
898 card->cnr, card->traceflag); 926 card->cnr, card->traceflag);
899 return 0; 927 return 0;
900 } 928 }
@@ -967,7 +995,11 @@ static int __init kcapi_init(void)
967{ 995{
968 char *p; 996 char *p;
969 char rev[32]; 997 char rev[32];
998 int ret;
970 999
1000 ret = cdebug_init();
1001 if (ret)
1002 return ret;
971 kcapi_proc_init(); 1003 kcapi_proc_init();
972 1004
973 if ((p = strchr(revision, ':')) != 0 && p[1]) { 1005 if ((p = strchr(revision, ':')) != 0 && p[1]) {
@@ -988,6 +1020,7 @@ static void __exit kcapi_exit(void)
988 1020
989 /* make sure all notifiers are finished */ 1021 /* make sure all notifiers are finished */
990 flush_scheduled_work(); 1022 flush_scheduled_work();
1023 cdebug_exit();
991} 1024}
992 1025
993module_init(kcapi_init); 1026module_init(kcapi_init);