Index: linux-2.6.21-mm/arch/um/drivers/pcap_kern.c =================================================================== --- linux-2.6.21-mm.orig/arch/um/drivers/pcap_kern.c 2007-04-27 13:16:49.000000000 -0400 +++ linux-2.6.21-mm/arch/um/drivers/pcap_kern.c 2007-04-27 16:20:57.000000000 -0400 @@ -31,19 +31,21 @@ void pcap_init(struct net_device *dev, v ppri->filter = init->filter; } -static int pcap_read(int fd, struct sk_buff **skb, +static int pcap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) return(-ENOMEM); - return(pcap_user_read(fd, skb_mac_header(*skb), + if(*skb == NULL) + return -ENOMEM; + + return pcap_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER, - (struct pcap_data *) &lp->user)); + (struct pcap_data *) &lp->user); } static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) { - return(-EPERM); + return -EPERM; } static const struct net_kern_info pcap_kern_info = { @@ -65,12 +67,12 @@ int pcap_setup(char *str, char **mac_out .optimize = 0, .filter = NULL }); - remain = split_if_spec(str, &host_if, &init->filter, + remain = split_if_spec(str, &host_if, &init->filter, &options[0], &options[1], NULL); if(remain != NULL){ printk(KERN_ERR "pcap_setup - Extra garbage on " "specification : '%s'\n", remain); - return(0); + return 0; } if(host_if != NULL) @@ -87,10 +89,13 @@ int pcap_setup(char *str, char **mac_out init->optimize = 1; else if(!strcmp(options[i], "nooptimize")) init->optimize = 0; - else printk("pcap_setup : bad option - '%s'\n", options[i]); + else { + printk("pcap_setup : bad option - '%s'\n", options[i]); + return 0; + } } - return(1); + return 1; } static struct transport pcap_transport = { Index: linux-2.6.21-mm/arch/um/include/user.h =================================================================== --- linux-2.6.21-mm.orig/arch/um/include/user.h 2007-04-26 17:33:01.000000000 -0400 +++ linux-2.6.21-mm/arch/um/include/user.h 2007-04-27 14:21:35.000000000 -0400 @@ -27,5 +27,6 @@ extern int in_aton(char *str); extern int open_gdb_chan(void); extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); +extern int reserved_address(void *addr); #endif Index: linux-2.6.21-mm/arch/um/kernel/um_arch.c =================================================================== --- linux-2.6.21-mm.orig/arch/um/kernel/um_arch.c 2007-04-26 17:41:21.000000000 -0400 +++ linux-2.6.21-mm/arch/um/kernel/um_arch.c 2007-04-27 14:30:36.000000000 -0400 @@ -500,6 +500,13 @@ void __init check_bugs(void) os_check_bugs(); } +int reserved_address(void *addr) +{ + struct page *page = virt_to_page(addr); + + return(PageReserved(page)); +} + void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { } Index: linux-2.6.21-mm/arch/um/os-Linux/main.c =================================================================== --- linux-2.6.21-mm.orig/arch/um/os-Linux/main.c 2007-04-26 17:41:10.000000000 -0400 +++ linux-2.6.21-mm/arch/um/os-Linux/main.c 2007-04-27 14:30:31.000000000 -0400 @@ -266,6 +266,8 @@ void __wrap_free(void *ptr) /* We need to know how the allocation happened, so it can be correctly * freed. This is done by seeing what region of memory the pointer is * in - + * in a reserved page - free, assume the pointer was + * acquired with malloc, since it couldn't have been kmalloced. * physical memory - kmalloc/kfree * kernel virtual memory - vmalloc/vfree * anywhere else - malloc/free @@ -281,7 +283,9 @@ void __wrap_free(void *ptr) * there is a possibility for memory leaks. */ - if((addr >= uml_physmem) && (addr < high_physmem)){ + if(kmalloc_ok && reserved_address(ptr)) + __real_free(ptr); + else if((addr >= uml_physmem) && (addr < high_physmem)){ if(CAN_KMALLOC()) kfree(ptr); }