From: Karsten Keil I found a bug in the PPPIOCSPASS PPPIOCSACTIVE IOCTL implementation in kernel 2.5/2.6. The current pppd code use a empty filter (uprog.len=0) to detach the filter in the kernel, but this code was removed in 2.5.71 while fixing a compiler warning. Here the new patch, also with better limit checking. The second patch check for flen == 0 in the filter check too, since later in this code a filter[flen - 1] access is done, which is not so funny with flen 0. Maybe it's not really needed anymore, since with the first patch it would not longer called with flen=0. --- drivers/net/ppp_generic.c | 31 ++++++++++++++++++------------- net/core/filter.c | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff -puN drivers/net/ppp_generic.c~ppp-active-passive-filter-fix drivers/net/ppp_generic.c --- 25/drivers/net/ppp_generic.c~ppp-active-passive-filter-fix 2004-02-14 13:52:34.000000000 -0800 +++ 25-akpm/drivers/net/ppp_generic.c 2004-02-14 13:52:34.000000000 -0800 @@ -675,20 +675,25 @@ static int ppp_ioctl(struct inode *inode if (copy_from_user(&uprog, (void __user *) arg, sizeof(uprog))) break; - err = -ENOMEM; - len = uprog.len * sizeof(struct sock_filter); - code = kmalloc(len, GFP_KERNEL); - if (code == 0) - break; - err = -EFAULT; - if (copy_from_user(code, (void __user *) uprog.filter, len)) { - kfree(code); - break; - } - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); + err = -EINVAL; + if (uprog.len > BPF_MAXINSNS) break; + err = -ENOMEM; + if (uprog.len > 0) { + len = uprog.len * sizeof(struct sock_filter); + code = kmalloc(len, GFP_KERNEL); + if (code == NULL) + break; + err = -EFAULT; + if (copy_from_user(code, (void __user *) uprog.filter, len)) { + kfree(code); + break; + } + err = sk_chk_filter(code, uprog.len); + if (err) { + kfree(code); + break; + } } filtp = (cmd == PPPIOCSPASS)? &ppp->pass_filter: &ppp->active_filter; ppp_lock(ppp); diff -puN net/core/filter.c~ppp-active-passive-filter-fix net/core/filter.c --- 25/net/core/filter.c~ppp-active-passive-filter-fix 2004-02-14 13:52:34.000000000 -0800 +++ 25-akpm/net/core/filter.c 2004-02-14 13:52:34.000000000 -0800 @@ -332,7 +332,7 @@ int sk_chk_filter(struct sock_filter *fi struct sock_filter *ftest; int pc; - if ((unsigned int)flen >= (~0U / sizeof(struct sock_filter))) + if (((unsigned int)flen >= (~0U / sizeof(struct sock_filter))) || flen == 0) return -EINVAL; /* check the filter code now */ _