/* Stephen White 10/2/2001 swhite@ox.compsoc.net sysctl_fix.c, compile: gcc -Wall -DMODULE -D__KERNEL__ -c sysctl_fix.c (on Redhat/UltraSparc with sparc64-linux-gcc -m64 -mno-fpu -mcmodel=medlow -mcpu=ultrasparc -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wall -DMODULE -D__KERNEL__ -c sysctl_fix.c ) Prevent sysctl exploit discovered by Chris Evans by properly validating input against negative numbers, */ #include #include #include #include #include #include #include #include #include #include #include extern void *sys_call_table[]; int (*old_sysctl)(struct __sysctl_args *args); asmlinkage int validate_sysctl(struct __sysctl_args *args) { struct __sysctl_args tmp; if(copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; if (tmp.nlen < 0) goto bad; if (tmp.oldval) { int old_len; if (copy_from_user(&old_len, tmp.oldlenp, sizeof(old_len))) return -EFAULT; if (old_len < 0) goto bad; } if (tmp.newval) if (tmp.newlen < 0) goto bad; return (*old_sysctl)(args); bad: printk("sysctl: arguments failed sanity check for user %i\n",current->uid); return -EINVAL; } int init_module() { old_sysctl = sys_call_table[__NR__sysctl]; sys_call_table[__NR__sysctl] = validate_sysctl; return 0; } void cleanup_module() { sys_call_table[__NR__sysctl] = old_sysctl; } /* < http://www.securityfocus.com/archive/1/162260 > */