--- linux-2.6.12/net/ipv4/netfilter/ipt_layer7.c 2005-06-22 19:38:08.000000000 +0200 +++ linux-2.6.13-rc3/net/ipv4/netfilter/ipt_layer7.c 2005-07-20 23:25:37.000000000 +0200 @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "regexp/regexp.c" @@ -68,8 +68,8 @@ static struct pattern_cache { time. In this case, we have to protect the conntracks and the list of compiled patterns. */ -DECLARE_RWLOCK(ct_lock); -DECLARE_LOCK(list_lock); +DEFINE_RWLOCK(ct_lock); +DEFINE_SPINLOCK(list_lock); #if CONFIG_IP_NF_MATCH_LAYER7_DEBUG /* Converts an unfriendly string into a friendly one by @@ -238,7 +238,7 @@ static int match_no_append(struct ip_con struct ipt_layer7_info * info) { /* If we're in here, throw the app data away */ - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); if(master_conntrack->layer7.app_data != NULL) { #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG @@ -257,38 +257,38 @@ static int match_no_append(struct ip_con kfree(master_conntrack->layer7.app_data); master_conntrack->layer7.app_data = NULL; /* don't free again */ } - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); if(master_conntrack->layer7.app_proto){ /* Here child connections set their .app_proto (for /proc/net/ip_conntrack) */ - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); if(!conntrack->layer7.app_proto) { conntrack->layer7.app_proto = kmalloc(strlen(master_conntrack->layer7.app_proto)+1, GFP_ATOMIC); if(!conntrack->layer7.app_proto){ if (net_ratelimit()) printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return 1; } strcpy(conntrack->layer7.app_proto, master_conntrack->layer7.app_proto); } - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return (!strcmp(master_conntrack->layer7.app_proto, info->protocol)); } else { /* If not classified, set to "unknown" to distinguish from connections that are still being tested. */ - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); master_conntrack->layer7.app_proto = kmalloc(strlen("unknown")+1, GFP_ATOMIC); if(!master_conntrack->layer7.app_proto){ if (net_ratelimit()) printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return 1; } strcpy(master_conntrack->layer7.app_proto, "unknown"); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return 0; } } @@ -377,25 +377,25 @@ static int match(/* const */struct sk_bu app_data = skb->data + app_data_offset(skb); appdatalen = skb->tail - app_data; - LOCK_BH(&list_lock); + spin_lock_bh(&list_lock); /* the return value gets checked later, when we're ready to use it */ comppattern = compile_and_cache(info->pattern, info->protocol); - UNLOCK_BH(&list_lock); + spin_unlock_bh(&list_lock); /* On the first packet of a connection, allocate space for app data */ - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { master_conntrack->layer7.app_data = kmalloc(CONFIG_IP_NF_MATCH_LAYER7_MAXDATALEN, GFP_ATOMIC); if(!master_conntrack->layer7.app_data){ if (net_ratelimit()) printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return info->invert; } master_conntrack->layer7.app_data[0] = '\0'; } - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); /* Can be here, but unallocated, if numpackets is increased near the beginning of a connection */ @@ -404,9 +404,9 @@ static int match(/* const */struct sk_bu if(!skb->cb[0]){ int newbytes; - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); newbytes = add_data(master_conntrack, app_data, appdatalen); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); if(newbytes == 0) { /* didn't add any data */ skb->cb[0] = 1; @@ -426,16 +426,16 @@ static int match(/* const */struct sk_bu } else pattern_result = 0; if(pattern_result) { - WRITE_LOCK(&ct_lock); + write_lock(&ct_lock); master_conntrack->layer7.app_proto = kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); if(!master_conntrack->layer7.app_proto){ if (net_ratelimit()) printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); return (pattern_result ^ info->invert); } strcpy(master_conntrack->layer7.app_proto, info->protocol); - WRITE_UNLOCK(&ct_lock); + write_unlock(&ct_lock); } /* mark the packet seen */ @@ -504,7 +504,10 @@ static int layer7_write_proc(struct file return count; } - copy_from_user(foo, buffer, count); + if(copy_from_user(foo, buffer, count)) { + return -EFAULT; + } + num_packets = my_atoi(foo); kfree (foo);