[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>

authored by Karsten Keil and committed by Linus Torvalds 17f0cd2f 34bbd704

+318 -78
+14 -2
drivers/isdn/capi/Kconfig
··· 2 2 # Config.in for the CAPI subsystem 3 3 # 4 4 config ISDN_DRV_AVMB1_VERBOSE_REASON 5 - bool "Verbose reason code reporting (kernel size +=7K)" 5 + bool "Verbose reason code reporting" 6 6 depends on ISDN_CAPI 7 + default y 7 8 help 8 - If you say Y here, the AVM B1 driver will give verbose reasons for 9 + If you say Y here, the CAPI drivers will give verbose reasons for 9 10 disconnecting. This will increase the size of the kernel by 7 KB. If 10 11 unsure, say Y. 12 + 13 + config CAPI_TRACE 14 + bool "CAPI trace support" 15 + depends on ISDN_CAPI 16 + default y 17 + help 18 + If you say Y here, the kernelcapi driver can make verbose traces 19 + of CAPI messages. This feature can be enabled/disabled via IOCTL for 20 + every controler (default disabled). 21 + This will increase the size of the kernelcapi module by 20 KB. 22 + If unsure, say Y. 11 23 12 24 config ISDN_CAPI_MIDDLEWARE 13 25 bool "CAPI2.0 Middleware support (EXPERIMENTAL)"
+22 -6
drivers/isdn/capi/capidrv.c
··· 990 990 capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); 991 991 capidrv_plci *plcip; 992 992 isdn_ctrl cmd; 993 + _cdebbuf *cdb; 993 994 994 995 if (!card) { 995 996 printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", ··· 1123 1122 break; 1124 1123 } 1125 1124 } 1126 - printk(KERN_ERR "capidrv-%d: %s\n", 1127 - card->contrnr, capi_cmsg2str(cmsg)); 1125 + cdb = capi_cmsg2str(cmsg); 1126 + if (cdb) { 1127 + printk(KERN_WARNING "capidrv-%d: %s\n", 1128 + card->contrnr, cdb->buf); 1129 + cdebbuf_free(cdb); 1130 + } else 1131 + printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n", 1132 + card->contrnr, cmsg->InfoNumber); 1133 + 1128 1134 break; 1129 1135 1130 1136 case CAPI_CONNECT_ACTIVE_CONF: /* plci */ ··· 1379 1371 static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) 1380 1372 { 1381 1373 capi_message2cmsg(&s_cmsg, skb->data); 1382 - if (debugmode > 3) 1383 - printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n", 1384 - ap->applid, capi_cmsg2str(&s_cmsg)); 1385 - 1374 + if (debugmode > 3) { 1375 + _cdebbuf *cdb = capi_cmsg2str(&s_cmsg); 1376 + 1377 + if (cdb) { 1378 + printk(KERN_DEBUG "%s: applid=%d %s\n", __FUNCTION__, 1379 + ap->applid, cdb->buf); 1380 + cdebbuf_free(cdb); 1381 + } else 1382 + printk(KERN_DEBUG "%s: applid=%d %s not traced\n", 1383 + __FUNCTION__, ap->applid, 1384 + capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand)); 1385 + } 1386 1386 if (s_cmsg.Command == CAPI_DATA_B3 1387 1387 && s_cmsg.Subcommand == CAPI_IND) { 1388 1388 handle_data(&s_cmsg, skb);
+208 -46
drivers/isdn/capi/capiutil.c
··· 648 648 649 649 650 650 /*-------------------------------------------------------*/ 651 + 652 + #ifdef CONFIG_CAPI_TRACE 653 + 651 654 /*-------------------------------------------------------*/ 652 655 653 656 static char *pnames[] = ··· 706 703 }; 707 704 708 705 709 - static char buf[8192]; 710 - static char *p = NULL; 711 706 712 707 #include <stdarg.h> 713 708 714 709 /*-------------------------------------------------------*/ 715 - static void bufprint(char *fmt,...) 710 + static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...) 716 711 { 717 712 va_list f; 713 + size_t n,r; 714 + 715 + if (!cdb) 716 + return NULL; 718 717 va_start(f, fmt); 719 - vsprintf(p, fmt, f); 718 + r = cdb->size - cdb->pos; 719 + n = vsnprintf(cdb->p, r, fmt, f); 720 720 va_end(f); 721 - p += strlen(p); 721 + if (n >= r) { 722 + /* truncated, need bigger buffer */ 723 + size_t ns = 2 * cdb->size; 724 + u_char *nb; 725 + 726 + while ((ns - cdb->pos) <= n) 727 + ns *= 2; 728 + nb = kmalloc(ns, GFP_ATOMIC); 729 + if (!nb) { 730 + cdebbuf_free(cdb); 731 + return NULL; 732 + } 733 + memcpy(nb, cdb->buf, cdb->pos); 734 + kfree(cdb->buf); 735 + nb[cdb->pos] = 0; 736 + cdb->buf = nb; 737 + cdb->p = cdb->buf + cdb->pos; 738 + cdb->size = ns; 739 + va_start(f, fmt); 740 + r = cdb->size - cdb->pos; 741 + n = vsnprintf(cdb->p, r, fmt, f); 742 + va_end(f); 743 + } 744 + cdb->p += n; 745 + cdb->pos += n; 746 + return cdb; 722 747 } 723 748 724 - static void printstructlen(u8 * m, unsigned len) 749 + static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len) 725 750 { 726 751 unsigned hex = 0; 752 + 753 + if (!cdb) 754 + return NULL; 727 755 for (; len; len--, m++) 728 756 if (isalnum(*m) || *m == ' ') { 729 757 if (hex) 730 - bufprint(">"); 731 - bufprint("%c", *m); 758 + cdb = bufprint(cdb, ">"); 759 + cdb = bufprint(cdb, "%c", *m); 732 760 hex = 0; 733 761 } else { 734 762 if (!hex) 735 - bufprint("<%02x", *m); 763 + cdb = bufprint(cdb, "<%02x", *m); 736 764 else 737 - bufprint(" %02x", *m); 765 + cdb = bufprint(cdb, " %02x", *m); 738 766 hex = 1; 739 767 } 740 768 if (hex) 741 - bufprint(">"); 769 + cdb = bufprint(cdb, ">"); 770 + return cdb; 742 771 } 743 772 744 - static void printstruct(u8 * m) 773 + static _cdebbuf *printstruct(_cdebbuf *cdb, u8 * m) 745 774 { 746 775 unsigned len; 776 + 747 777 if (m[0] != 0xff) { 748 778 len = m[0]; 749 779 m += 1; ··· 784 748 len = ((u16 *) (m + 1))[0]; 785 749 m += 3; 786 750 } 787 - printstructlen(m, len); 751 + cdb = printstructlen(cdb, m, len); 752 + return cdb; 788 753 } 789 754 790 755 /*-------------------------------------------------------*/ 791 756 #define NAME (pnames[cmsg->par[cmsg->p]]) 792 757 793 - static void protocol_message_2_pars(_cmsg * cmsg, int level) 758 + static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) 794 759 { 795 760 for (; TYP != _CEND; cmsg->p++) { 796 761 int slen = 29 + 3 - level; 797 762 int i; 798 763 799 - bufprint(" "); 764 + if (!cdb) 765 + return NULL; 766 + cdb = bufprint(cdb, " "); 800 767 for (i = 0; i < level - 1; i++) 801 - bufprint(" "); 768 + cdb = bufprint(cdb, " "); 802 769 803 770 switch (TYP) { 804 771 case _CBYTE: 805 - bufprint("%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 772 + cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 806 773 cmsg->l++; 807 774 break; 808 775 case _CWORD: 809 - bufprint("%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 776 + cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 810 777 cmsg->l += 2; 811 778 break; 812 779 case _CDWORD: 813 - bufprint("%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 780 + cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 814 781 cmsg->l += 4; 815 782 break; 816 783 case _CSTRUCT: 817 - bufprint("%-*s = ", slen, NAME); 784 + cdb = bufprint(cdb, "%-*s = ", slen, NAME); 818 785 if (cmsg->m[cmsg->l] == '\0') 819 - bufprint("default"); 786 + cdb = bufprint(cdb, "default"); 820 787 else 821 - printstruct(cmsg->m + cmsg->l); 822 - bufprint("\n"); 788 + cdb = printstruct(cdb, cmsg->m + cmsg->l); 789 + cdb = bufprint(cdb, "\n"); 823 790 if (cmsg->m[cmsg->l] != 0xff) 824 791 cmsg->l += 1 + cmsg->m[cmsg->l]; 825 792 else ··· 833 794 case _CMSTRUCT: 834 795 /*----- Metastruktur 0 -----*/ 835 796 if (cmsg->m[cmsg->l] == '\0') { 836 - bufprint("%-*s = default\n", slen, NAME); 797 + cdb = bufprint(cdb, "%-*s = default\n", slen, NAME); 837 798 cmsg->l++; 838 799 jumpcstruct(cmsg); 839 800 } else { 840 801 char *name = NAME; 841 802 unsigned _l = cmsg->l; 842 - bufprint("%-*s\n", slen, name); 803 + cdb = bufprint(cdb, "%-*s\n", slen, name); 843 804 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; 844 805 cmsg->p++; 845 - protocol_message_2_pars(cmsg, level + 1); 806 + cdb = protocol_message_2_pars(cdb, cmsg, level + 1); 846 807 } 847 808 break; 848 809 } 849 810 } 811 + return cdb; 850 812 } 851 813 /*-------------------------------------------------------*/ 852 - char *capi_message2str(u8 * msg) 814 + 815 + static _cdebbuf *g_debbuf; 816 + static u_long g_debbuf_lock; 817 + static _cmsg *g_cmsg; 818 + 819 + _cdebbuf *cdebbuf_alloc(void) 853 820 { 821 + _cdebbuf *cdb; 854 822 855 - _cmsg cmsg; 856 - p = buf; 857 - p[0] = 0; 823 + if (likely(!test_and_set_bit(1, &g_debbuf_lock))) { 824 + cdb = g_debbuf; 825 + goto init; 826 + } else 827 + cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC); 828 + if (!cdb) 829 + return NULL; 830 + cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC); 831 + if (!cdb->buf) { 832 + kfree(cdb); 833 + return NULL; 834 + } 835 + cdb->size = CDEBUG_SIZE; 836 + init: 837 + cdb->buf[0] = 0; 838 + cdb->p = cdb->buf; 839 + cdb->pos = 0; 840 + return cdb; 841 + } 858 842 859 - cmsg.m = msg; 860 - cmsg.l = 8; 861 - cmsg.p = 0; 862 - byteTRcpy(cmsg.m + 4, &cmsg.Command); 863 - byteTRcpy(cmsg.m + 5, &cmsg.Subcommand); 864 - cmsg.par = cpars[command_2_index(cmsg.Command, cmsg.Subcommand)]; 843 + void cdebbuf_free(_cdebbuf *cdb) 844 + { 845 + if (likely(cdb == g_debbuf)) { 846 + test_and_clear_bit(1, &g_debbuf_lock); 847 + return; 848 + } 849 + if (likely(cdb)) 850 + kfree(cdb->buf); 851 + kfree(cdb); 852 + } 865 853 866 - bufprint("%-26s ID=%03d #0x%04x LEN=%04d\n", 867 - mnames[command_2_index(cmsg.Command, cmsg.Subcommand)], 854 + 855 + _cdebbuf *capi_message2str(u8 * msg) 856 + { 857 + _cdebbuf *cdb; 858 + _cmsg *cmsg; 859 + 860 + cdb = cdebbuf_alloc(); 861 + if (unlikely(!cdb)) 862 + return NULL; 863 + if (likely(cdb == g_debbuf)) 864 + cmsg = g_cmsg; 865 + else 866 + cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC); 867 + if (unlikely(!cmsg)) { 868 + cdebbuf_free(cdb); 869 + return NULL; 870 + } 871 + cmsg->m = msg; 872 + cmsg->l = 8; 873 + cmsg->p = 0; 874 + byteTRcpy(cmsg->m + 4, &cmsg->Command); 875 + byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); 876 + cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)]; 877 + 878 + cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n", 879 + mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], 868 880 ((unsigned short *) msg)[1], 869 881 ((unsigned short *) msg)[3], 870 882 ((unsigned short *) msg)[0]); 871 883 872 - protocol_message_2_pars(&cmsg, 1); 873 - return buf; 884 + cdb = protocol_message_2_pars(cdb, cmsg, 1); 885 + if (unlikely(cmsg != g_cmsg)) 886 + kfree(cmsg); 887 + return cdb; 874 888 } 875 889 876 - char *capi_cmsg2str(_cmsg * cmsg) 890 + _cdebbuf *capi_cmsg2str(_cmsg * cmsg) 877 891 { 878 - p = buf; 879 - p[0] = 0; 892 + _cdebbuf *cdb; 893 + 894 + cdb = cdebbuf_alloc(); 895 + if (!cdb) 896 + return NULL; 880 897 cmsg->l = 8; 881 898 cmsg->p = 0; 882 - bufprint("%s ID=%03d #0x%04x LEN=%04d\n", 899 + cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n", 883 900 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], 884 901 ((u16 *) cmsg->m)[1], 885 902 ((u16 *) cmsg->m)[3], 886 903 ((u16 *) cmsg->m)[0]); 887 - protocol_message_2_pars(cmsg, 1); 888 - return buf; 904 + cdb = protocol_message_2_pars(cdb, cmsg, 1); 905 + return cdb; 889 906 } 890 907 908 + int __init cdebug_init(void) 909 + { 910 + g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL); 911 + if (!g_cmsg) 912 + return ENOMEM; 913 + g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); 914 + if (!g_debbuf) { 915 + kfree(g_cmsg); 916 + return ENOMEM; 917 + } 918 + g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); 919 + if (!g_debbuf->buf) { 920 + kfree(g_cmsg); 921 + kfree(g_debbuf); 922 + return ENOMEM;; 923 + } 924 + g_debbuf->size = CDEBUG_GSIZE; 925 + g_debbuf->buf[0] = 0; 926 + g_debbuf->p = g_debbuf->buf; 927 + g_debbuf->pos = 0; 928 + return 0; 929 + } 930 + 931 + void __exit cdebug_exit(void) 932 + { 933 + if (g_debbuf) 934 + kfree(g_debbuf->buf); 935 + kfree(g_debbuf); 936 + kfree(g_cmsg); 937 + } 938 + 939 + #else /* !CONFIG_CAPI_TRACE */ 940 + 941 + static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0}; 942 + 943 + _cdebbuf *capi_message2str(u8 * msg) 944 + { 945 + return &g_debbuf; 946 + } 947 + 948 + _cdebbuf *capi_cmsg2str(_cmsg * cmsg) 949 + { 950 + return &g_debbuf; 951 + } 952 + 953 + _cdebbuf *cdebbuf_alloc(void) 954 + { 955 + return &g_debbuf; 956 + } 957 + 958 + void cdebbuf_free(_cdebbuf *cdb) 959 + { 960 + } 961 + 962 + int __init cdebug_init(void) 963 + { 964 + return 0; 965 + } 966 + 967 + void __exit cdebug_exit(void) 968 + { 969 + } 970 + 971 + #endif 972 + 973 + EXPORT_SYMBOL(cdebbuf_alloc); 974 + EXPORT_SYMBOL(cdebbuf_free); 891 975 EXPORT_SYMBOL(capi_cmsg2message); 892 976 EXPORT_SYMBOL(capi_message2cmsg); 893 977 EXPORT_SYMBOL(capi_cmsg_header);
+55 -22
drivers/isdn/capi/kcapi.c
··· 276 276 int showctl = 0; 277 277 u8 cmd, subcmd; 278 278 unsigned long flags; 279 + _cdebbuf *cdb; 279 280 280 281 if (card->cardstate != CARD_RUNNING) { 281 - printk(KERN_INFO "kcapi: controller %d not active, got: %s", 282 - card->cnr, capi_message2str(skb->data)); 282 + cdb = 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 290 goto error; 284 291 } 285 292 ··· 302 295 showctl |= (card->traceflag & 1); 303 296 if (showctl & 2) { 304 297 if (showctl & 1) { 305 - printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", 306 - (unsigned long) card->cnr, 307 - CAPIMSG_APPID(skb->data), 298 + printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", 299 + card->cnr, CAPIMSG_APPID(skb->data), 308 300 capi_cmd2str(cmd, subcmd), 309 301 CAPIMSG_LEN(skb->data)); 310 302 } else { 311 - printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", 312 - (unsigned long) card->cnr, 313 - capi_message2str(skb->data)); 303 + cdb = capi_message2str(skb->data); 304 + if (cdb) { 305 + printk(KERN_DEBUG "kcapi: got [%03d] %s\n", 306 + card->cnr, cdb->buf); 307 + cdebbuf_free(cdb); 308 + } else 309 + printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n", 310 + card->cnr, CAPIMSG_APPID(skb->data), 311 + capi_cmd2str(cmd, subcmd), 312 + CAPIMSG_LEN(skb->data)); 314 313 } 315 314 316 315 } ··· 325 312 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 326 313 if ((!ap) || (ap->release_in_progress)) { 327 314 read_unlock_irqrestore(&application_lock, flags); 328 - printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 329 - CAPIMSG_APPID(skb->data), capi_message2str(skb->data)); 315 + cdb = capi_message2str(skb->data); 316 + if (cdb) { 317 + printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 318 + CAPIMSG_APPID(skb->data), cdb->buf); 319 + cdebbuf_free(cdb); 320 + } else 321 + printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n", 322 + CAPIMSG_APPID(skb->data), 323 + capi_cmd2str(cmd, subcmd)); 330 324 goto error; 331 325 } 332 326 skb_queue_tail(&ap->recv_queue, skb); ··· 352 332 { 353 333 card->cardstate = CARD_RUNNING; 354 334 355 - printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", 335 + printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n", 356 336 card->cnr, card->name); 357 337 358 338 notify_push(KCI_CONTRUP, card->cnr, 0, 0); ··· 384 364 capi_ctr_put(card); 385 365 } 386 366 387 - printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr); 367 + printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr); 388 368 389 369 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 390 370 } ··· 394 374 void capi_ctr_suspend_output(struct capi_ctr *card) 395 375 { 396 376 if (!card->blocked) { 397 - printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr); 377 + printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); 398 378 card->blocked = 1; 399 379 } 400 380 } ··· 404 384 void capi_ctr_resume_output(struct capi_ctr *card) 405 385 { 406 386 if (card->blocked) { 407 - printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr); 387 + printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); 408 388 card->blocked = 0; 409 389 } 410 390 } ··· 452 432 } 453 433 454 434 ncards++; 455 - printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", 435 + printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 456 436 card->cnr, card->name); 457 437 return 0; 458 438 } ··· 471 451 card->procent = NULL; 472 452 } 473 453 capi_cards[card->cnr - 1] = NULL; 474 - printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", 454 + printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", 475 455 card->cnr, card->name); 476 456 477 457 return 0; ··· 643 623 showctl |= (card->traceflag & 1); 644 624 if (showctl & 2) { 645 625 if (showctl & 1) { 646 - printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", 626 + printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", 647 627 CAPIMSG_CONTROLLER(skb->data), 648 628 CAPIMSG_APPID(skb->data), 649 629 capi_cmd2str(cmd, subcmd), 650 630 CAPIMSG_LEN(skb->data)); 651 631 } else { 652 - printk(KERN_DEBUG "kcapi: put [%#x] %s\n", 653 - CAPIMSG_CONTROLLER(skb->data), 654 - capi_message2str(skb->data)); 632 + _cdebbuf *cdb = capi_message2str(skb->data); 633 + if (cdb) { 634 + printk(KERN_DEBUG "kcapi: put [%03d] %s\n", 635 + CAPIMSG_CONTROLLER(skb->data), 636 + cdb->buf); 637 + cdebbuf_free(cdb); 638 + } else 639 + printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n", 640 + CAPIMSG_CONTROLLER(skb->data), 641 + CAPIMSG_APPID(skb->data), 642 + capi_cmd2str(cmd, subcmd), 643 + CAPIMSG_LEN(skb->data)); 655 644 } 656 - 657 645 } 658 646 return card->send_message(card, skb); 659 647 } ··· 922 894 return -ESRCH; 923 895 924 896 card->traceflag = fdef.flag; 925 - printk(KERN_INFO "kcapi: contr %d set trace=%d\n", 897 + printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", 926 898 card->cnr, card->traceflag); 927 899 return 0; 928 900 } ··· 995 967 { 996 968 char *p; 997 969 char rev[32]; 970 + int ret; 998 971 972 + ret = cdebug_init(); 973 + if (ret) 974 + return ret; 999 975 kcapi_proc_init(); 1000 976 1001 977 if ((p = strchr(revision, ':')) != 0 && p[1]) { ··· 1020 988 1021 989 /* make sure all notifiers are finished */ 1022 990 flush_scheduled_work(); 991 + cdebug_exit(); 1023 992 } 1024 993 1025 994 module_init(kcapi_init);
+19 -2
include/linux/isdn/capiutil.h
··· 174 174 /* 175 175 * Debugging / Tracing functions 176 176 */ 177 + 177 178 char *capi_cmd2str(__u8 cmd, __u8 subcmd); 178 - char *capi_cmsg2str(_cmsg * cmsg); 179 - char *capi_message2str(__u8 * msg); 179 + 180 + typedef struct { 181 + u_char *buf; 182 + u_char *p; 183 + size_t size; 184 + size_t pos; 185 + } _cdebbuf; 186 + 187 + #define CDEBUG_SIZE 1024 188 + #define CDEBUG_GSIZE 4096 189 + 190 + _cdebbuf *cdebbuf_alloc(void); 191 + void cdebbuf_free(_cdebbuf *cdb); 192 + int cdebug_init(void); 193 + void cdebug_exit(void); 194 + 195 + _cdebbuf *capi_cmsg2str(_cmsg *cmsg); 196 + _cdebbuf *capi_message2str(__u8 *msg); 180 197 181 198 /*-----------------------------------------------------------------------*/ 182 199