[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 # Config.in for the CAPI subsystem 3 # 4 config ISDN_DRV_AVMB1_VERBOSE_REASON 5 - bool "Verbose reason code reporting (kernel size +=7K)" 6 depends on ISDN_CAPI 7 help 8 - If you say Y here, the AVM B1 driver will give verbose reasons for 9 disconnecting. This will increase the size of the kernel by 7 KB. If 10 unsure, say Y. 11 12 config ISDN_CAPI_MIDDLEWARE 13 bool "CAPI2.0 Middleware support (EXPERIMENTAL)"
··· 2 # Config.in for the CAPI subsystem 3 # 4 config ISDN_DRV_AVMB1_VERBOSE_REASON 5 + bool "Verbose reason code reporting" 6 depends on ISDN_CAPI 7 + default y 8 help 9 + If you say Y here, the CAPI drivers will give verbose reasons for 10 disconnecting. This will increase the size of the kernel by 7 KB. If 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. 23 24 config ISDN_CAPI_MIDDLEWARE 25 bool "CAPI2.0 Middleware support (EXPERIMENTAL)"
+22 -6
drivers/isdn/capi/capidrv.c
··· 990 capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); 991 capidrv_plci *plcip; 992 isdn_ctrl cmd; 993 994 if (!card) { 995 printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", ··· 1123 break; 1124 } 1125 } 1126 - printk(KERN_ERR "capidrv-%d: %s\n", 1127 - card->contrnr, capi_cmsg2str(cmsg)); 1128 break; 1129 1130 case CAPI_CONNECT_ACTIVE_CONF: /* plci */ ··· 1379 static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) 1380 { 1381 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 - 1386 if (s_cmsg.Command == CAPI_DATA_B3 1387 && s_cmsg.Subcommand == CAPI_IND) { 1388 handle_data(&s_cmsg, skb);
··· 990 capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); 991 capidrv_plci *plcip; 992 isdn_ctrl cmd; 993 + _cdebbuf *cdb; 994 995 if (!card) { 996 printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", ··· 1122 break; 1123 } 1124 } 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 + 1134 break; 1135 1136 case CAPI_CONNECT_ACTIVE_CONF: /* plci */ ··· 1371 static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) 1372 { 1373 capi_message2cmsg(&s_cmsg, skb->data); 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 if (s_cmsg.Command == CAPI_DATA_B3 1387 && s_cmsg.Subcommand == CAPI_IND) { 1388 handle_data(&s_cmsg, skb);
+208 -46
drivers/isdn/capi/capiutil.c
··· 648 649 650 /*-------------------------------------------------------*/ 651 /*-------------------------------------------------------*/ 652 653 static char *pnames[] = ··· 706 }; 707 708 709 - static char buf[8192]; 710 - static char *p = NULL; 711 712 #include <stdarg.h> 713 714 /*-------------------------------------------------------*/ 715 - static void bufprint(char *fmt,...) 716 { 717 va_list f; 718 va_start(f, fmt); 719 - vsprintf(p, fmt, f); 720 va_end(f); 721 - p += strlen(p); 722 } 723 724 - static void printstructlen(u8 * m, unsigned len) 725 { 726 unsigned hex = 0; 727 for (; len; len--, m++) 728 if (isalnum(*m) || *m == ' ') { 729 if (hex) 730 - bufprint(">"); 731 - bufprint("%c", *m); 732 hex = 0; 733 } else { 734 if (!hex) 735 - bufprint("<%02x", *m); 736 else 737 - bufprint(" %02x", *m); 738 hex = 1; 739 } 740 if (hex) 741 - bufprint(">"); 742 } 743 744 - static void printstruct(u8 * m) 745 { 746 unsigned len; 747 if (m[0] != 0xff) { 748 len = m[0]; 749 m += 1; ··· 784 len = ((u16 *) (m + 1))[0]; 785 m += 3; 786 } 787 - printstructlen(m, len); 788 } 789 790 /*-------------------------------------------------------*/ 791 #define NAME (pnames[cmsg->par[cmsg->p]]) 792 793 - static void protocol_message_2_pars(_cmsg * cmsg, int level) 794 { 795 for (; TYP != _CEND; cmsg->p++) { 796 int slen = 29 + 3 - level; 797 int i; 798 799 - bufprint(" "); 800 for (i = 0; i < level - 1; i++) 801 - bufprint(" "); 802 803 switch (TYP) { 804 case _CBYTE: 805 - bufprint("%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 806 cmsg->l++; 807 break; 808 case _CWORD: 809 - bufprint("%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 810 cmsg->l += 2; 811 break; 812 case _CDWORD: 813 - bufprint("%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 814 cmsg->l += 4; 815 break; 816 case _CSTRUCT: 817 - bufprint("%-*s = ", slen, NAME); 818 if (cmsg->m[cmsg->l] == '\0') 819 - bufprint("default"); 820 else 821 - printstruct(cmsg->m + cmsg->l); 822 - bufprint("\n"); 823 if (cmsg->m[cmsg->l] != 0xff) 824 cmsg->l += 1 + cmsg->m[cmsg->l]; 825 else ··· 833 case _CMSTRUCT: 834 /*----- Metastruktur 0 -----*/ 835 if (cmsg->m[cmsg->l] == '\0') { 836 - bufprint("%-*s = default\n", slen, NAME); 837 cmsg->l++; 838 jumpcstruct(cmsg); 839 } else { 840 char *name = NAME; 841 unsigned _l = cmsg->l; 842 - bufprint("%-*s\n", slen, name); 843 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; 844 cmsg->p++; 845 - protocol_message_2_pars(cmsg, level + 1); 846 } 847 break; 848 } 849 } 850 } 851 /*-------------------------------------------------------*/ 852 - char *capi_message2str(u8 * msg) 853 { 854 855 - _cmsg cmsg; 856 - p = buf; 857 - p[0] = 0; 858 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)]; 865 866 - bufprint("%-26s ID=%03d #0x%04x LEN=%04d\n", 867 - mnames[command_2_index(cmsg.Command, cmsg.Subcommand)], 868 ((unsigned short *) msg)[1], 869 ((unsigned short *) msg)[3], 870 ((unsigned short *) msg)[0]); 871 872 - protocol_message_2_pars(&cmsg, 1); 873 - return buf; 874 } 875 876 - char *capi_cmsg2str(_cmsg * cmsg) 877 { 878 - p = buf; 879 - p[0] = 0; 880 cmsg->l = 8; 881 cmsg->p = 0; 882 - bufprint("%s ID=%03d #0x%04x LEN=%04d\n", 883 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], 884 ((u16 *) cmsg->m)[1], 885 ((u16 *) cmsg->m)[3], 886 ((u16 *) cmsg->m)[0]); 887 - protocol_message_2_pars(cmsg, 1); 888 - return buf; 889 } 890 891 EXPORT_SYMBOL(capi_cmsg2message); 892 EXPORT_SYMBOL(capi_message2cmsg); 893 EXPORT_SYMBOL(capi_cmsg_header);
··· 648 649 650 /*-------------------------------------------------------*/ 651 + 652 + #ifdef CONFIG_CAPI_TRACE 653 + 654 /*-------------------------------------------------------*/ 655 656 static char *pnames[] = ··· 703 }; 704 705 706 707 #include <stdarg.h> 708 709 /*-------------------------------------------------------*/ 710 + static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...) 711 { 712 va_list f; 713 + size_t n,r; 714 + 715 + if (!cdb) 716 + return NULL; 717 va_start(f, fmt); 718 + r = cdb->size - cdb->pos; 719 + n = vsnprintf(cdb->p, r, fmt, f); 720 va_end(f); 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; 747 } 748 749 + static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len) 750 { 751 unsigned hex = 0; 752 + 753 + if (!cdb) 754 + return NULL; 755 for (; len; len--, m++) 756 if (isalnum(*m) || *m == ' ') { 757 if (hex) 758 + cdb = bufprint(cdb, ">"); 759 + cdb = bufprint(cdb, "%c", *m); 760 hex = 0; 761 } else { 762 if (!hex) 763 + cdb = bufprint(cdb, "<%02x", *m); 764 else 765 + cdb = bufprint(cdb, " %02x", *m); 766 hex = 1; 767 } 768 if (hex) 769 + cdb = bufprint(cdb, ">"); 770 + return cdb; 771 } 772 773 + static _cdebbuf *printstruct(_cdebbuf *cdb, u8 * m) 774 { 775 unsigned len; 776 + 777 if (m[0] != 0xff) { 778 len = m[0]; 779 m += 1; ··· 748 len = ((u16 *) (m + 1))[0]; 749 m += 3; 750 } 751 + cdb = printstructlen(cdb, m, len); 752 + return cdb; 753 } 754 755 /*-------------------------------------------------------*/ 756 #define NAME (pnames[cmsg->par[cmsg->p]]) 757 758 + static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) 759 { 760 for (; TYP != _CEND; cmsg->p++) { 761 int slen = 29 + 3 - level; 762 int i; 763 764 + if (!cdb) 765 + return NULL; 766 + cdb = bufprint(cdb, " "); 767 for (i = 0; i < level - 1; i++) 768 + cdb = bufprint(cdb, " "); 769 770 switch (TYP) { 771 case _CBYTE: 772 + cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 773 cmsg->l++; 774 break; 775 case _CWORD: 776 + cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 777 cmsg->l += 2; 778 break; 779 case _CDWORD: 780 + cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 781 cmsg->l += 4; 782 break; 783 case _CSTRUCT: 784 + cdb = bufprint(cdb, "%-*s = ", slen, NAME); 785 if (cmsg->m[cmsg->l] == '\0') 786 + cdb = bufprint(cdb, "default"); 787 else 788 + cdb = printstruct(cdb, cmsg->m + cmsg->l); 789 + cdb = bufprint(cdb, "\n"); 790 if (cmsg->m[cmsg->l] != 0xff) 791 cmsg->l += 1 + cmsg->m[cmsg->l]; 792 else ··· 794 case _CMSTRUCT: 795 /*----- Metastruktur 0 -----*/ 796 if (cmsg->m[cmsg->l] == '\0') { 797 + cdb = bufprint(cdb, "%-*s = default\n", slen, NAME); 798 cmsg->l++; 799 jumpcstruct(cmsg); 800 } else { 801 char *name = NAME; 802 unsigned _l = cmsg->l; 803 + cdb = bufprint(cdb, "%-*s\n", slen, name); 804 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; 805 cmsg->p++; 806 + cdb = protocol_message_2_pars(cdb, cmsg, level + 1); 807 } 808 break; 809 } 810 } 811 + return cdb; 812 } 813 /*-------------------------------------------------------*/ 814 + 815 + static _cdebbuf *g_debbuf; 816 + static u_long g_debbuf_lock; 817 + static _cmsg *g_cmsg; 818 + 819 + _cdebbuf *cdebbuf_alloc(void) 820 { 821 + _cdebbuf *cdb; 822 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 + } 842 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 + } 853 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)], 880 ((unsigned short *) msg)[1], 881 ((unsigned short *) msg)[3], 882 ((unsigned short *) msg)[0]); 883 884 + cdb = protocol_message_2_pars(cdb, cmsg, 1); 885 + if (unlikely(cmsg != g_cmsg)) 886 + kfree(cmsg); 887 + return cdb; 888 } 889 890 + _cdebbuf *capi_cmsg2str(_cmsg * cmsg) 891 { 892 + _cdebbuf *cdb; 893 + 894 + cdb = cdebbuf_alloc(); 895 + if (!cdb) 896 + return NULL; 897 cmsg->l = 8; 898 cmsg->p = 0; 899 + cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n", 900 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], 901 ((u16 *) cmsg->m)[1], 902 ((u16 *) cmsg->m)[3], 903 ((u16 *) cmsg->m)[0]); 904 + cdb = protocol_message_2_pars(cdb, cmsg, 1); 905 + return cdb; 906 } 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); 975 EXPORT_SYMBOL(capi_cmsg2message); 976 EXPORT_SYMBOL(capi_message2cmsg); 977 EXPORT_SYMBOL(capi_cmsg_header);
+55 -22
drivers/isdn/capi/kcapi.c
··· 276 int showctl = 0; 277 u8 cmd, subcmd; 278 unsigned long flags; 279 280 if (card->cardstate != CARD_RUNNING) { 281 - printk(KERN_INFO "kcapi: controller %d not active, got: %s", 282 - card->cnr, capi_message2str(skb->data)); 283 goto error; 284 } 285 ··· 302 showctl |= (card->traceflag & 1); 303 if (showctl & 2) { 304 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), 308 capi_cmd2str(cmd, subcmd), 309 CAPIMSG_LEN(skb->data)); 310 } else { 311 - printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", 312 - (unsigned long) card->cnr, 313 - capi_message2str(skb->data)); 314 } 315 316 } ··· 325 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 326 if ((!ap) || (ap->release_in_progress)) { 327 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)); 330 goto error; 331 } 332 skb_queue_tail(&ap->recv_queue, skb); ··· 352 { 353 card->cardstate = CARD_RUNNING; 354 355 - printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", 356 card->cnr, card->name); 357 358 notify_push(KCI_CONTRUP, card->cnr, 0, 0); ··· 384 capi_ctr_put(card); 385 } 386 387 - printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr); 388 389 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 390 } ··· 394 void capi_ctr_suspend_output(struct capi_ctr *card) 395 { 396 if (!card->blocked) { 397 - printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr); 398 card->blocked = 1; 399 } 400 } ··· 404 void capi_ctr_resume_output(struct capi_ctr *card) 405 { 406 if (card->blocked) { 407 - printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr); 408 card->blocked = 0; 409 } 410 } ··· 452 } 453 454 ncards++; 455 - printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", 456 card->cnr, card->name); 457 return 0; 458 } ··· 471 card->procent = NULL; 472 } 473 capi_cards[card->cnr - 1] = NULL; 474 - printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", 475 card->cnr, card->name); 476 477 return 0; ··· 643 showctl |= (card->traceflag & 1); 644 if (showctl & 2) { 645 if (showctl & 1) { 646 - printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", 647 CAPIMSG_CONTROLLER(skb->data), 648 CAPIMSG_APPID(skb->data), 649 capi_cmd2str(cmd, subcmd), 650 CAPIMSG_LEN(skb->data)); 651 } else { 652 - printk(KERN_DEBUG "kcapi: put [%#x] %s\n", 653 - CAPIMSG_CONTROLLER(skb->data), 654 - capi_message2str(skb->data)); 655 } 656 - 657 } 658 return card->send_message(card, skb); 659 } ··· 922 return -ESRCH; 923 924 card->traceflag = fdef.flag; 925 - printk(KERN_INFO "kcapi: contr %d set trace=%d\n", 926 card->cnr, card->traceflag); 927 return 0; 928 } ··· 995 { 996 char *p; 997 char rev[32]; 998 999 kcapi_proc_init(); 1000 1001 if ((p = strchr(revision, ':')) != 0 && p[1]) { ··· 1020 1021 /* make sure all notifiers are finished */ 1022 flush_scheduled_work(); 1023 } 1024 1025 module_init(kcapi_init);
··· 276 int showctl = 0; 277 u8 cmd, subcmd; 278 unsigned long flags; 279 + _cdebbuf *cdb; 280 281 if (card->cardstate != CARD_RUNNING) { 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); 290 goto error; 291 } 292 ··· 295 showctl |= (card->traceflag & 1); 296 if (showctl & 2) { 297 if (showctl & 1) { 298 + printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", 299 + card->cnr, CAPIMSG_APPID(skb->data), 300 capi_cmd2str(cmd, subcmd), 301 CAPIMSG_LEN(skb->data)); 302 } else { 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)); 313 } 314 315 } ··· 312 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 313 if ((!ap) || (ap->release_in_progress)) { 314 read_unlock_irqrestore(&application_lock, flags); 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)); 324 goto error; 325 } 326 skb_queue_tail(&ap->recv_queue, skb); ··· 332 { 333 card->cardstate = CARD_RUNNING; 334 335 + printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n", 336 card->cnr, card->name); 337 338 notify_push(KCI_CONTRUP, card->cnr, 0, 0); ··· 364 capi_ctr_put(card); 365 } 366 367 + printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr); 368 369 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 370 } ··· 374 void capi_ctr_suspend_output(struct capi_ctr *card) 375 { 376 if (!card->blocked) { 377 + printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); 378 card->blocked = 1; 379 } 380 } ··· 384 void capi_ctr_resume_output(struct capi_ctr *card) 385 { 386 if (card->blocked) { 387 + printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); 388 card->blocked = 0; 389 } 390 } ··· 432 } 433 434 ncards++; 435 + printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 436 card->cnr, card->name); 437 return 0; 438 } ··· 451 card->procent = NULL; 452 } 453 capi_cards[card->cnr - 1] = NULL; 454 + printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", 455 card->cnr, card->name); 456 457 return 0; ··· 623 showctl |= (card->traceflag & 1); 624 if (showctl & 2) { 625 if (showctl & 1) { 626 + printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", 627 CAPIMSG_CONTROLLER(skb->data), 628 CAPIMSG_APPID(skb->data), 629 capi_cmd2str(cmd, subcmd), 630 CAPIMSG_LEN(skb->data)); 631 } else { 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)); 644 } 645 } 646 return card->send_message(card, skb); 647 } ··· 894 return -ESRCH; 895 896 card->traceflag = fdef.flag; 897 + printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", 898 card->cnr, card->traceflag); 899 return 0; 900 } ··· 967 { 968 char *p; 969 char rev[32]; 970 + int ret; 971 972 + ret = cdebug_init(); 973 + if (ret) 974 + return ret; 975 kcapi_proc_init(); 976 977 if ((p = strchr(revision, ':')) != 0 && p[1]) { ··· 988 989 /* make sure all notifiers are finished */ 990 flush_scheduled_work(); 991 + cdebug_exit(); 992 } 993 994 module_init(kcapi_init);
+19 -2
include/linux/isdn/capiutil.h
··· 174 /* 175 * Debugging / Tracing functions 176 */ 177 char *capi_cmd2str(__u8 cmd, __u8 subcmd); 178 - char *capi_cmsg2str(_cmsg * cmsg); 179 - char *capi_message2str(__u8 * msg); 180 181 /*-----------------------------------------------------------------------*/ 182
··· 174 /* 175 * Debugging / Tracing functions 176 */ 177 + 178 char *capi_cmd2str(__u8 cmd, __u8 subcmd); 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); 197 198 /*-----------------------------------------------------------------------*/ 199