Bugtraq mailing list archives
limit maximum nr. of processes.
From: petter () proact no (Petter Wahlman)
Date: Wed, 1 Sep 1999 10:53:48 +0200
'lo! i have made a loadable kernel module that lets you limit the maximum number of processes members of the group USER_GID can execute. this can e.g be used to prevent DoS attacks like: int main() { while(1) fork(); return 1; } Setting the limit is easily done through the proc interface: arjuna(root):fork~>cat /proc/maxprocs gid: 500 restricted to: 40 processes arjuna(root):fork~>echo 64 > /proc/maxprocs arjuna(root):fork~>cat /proc/maxprocs gid: 500 restricted to: 64 processes [The module does currently only support v.2.2.X of the Linux kernel.] ________________________________________________________________________________ Petter Wahlman bactus () sol no #define QUESTION ((bb) || !(bb)) - Shakespeare. echo '16i[q]sa[ln0=aln100%Pln100/snlbx]sbA6E616D6C68615720726574746550snlbxq'|dc ________________________________________________________________________________ /*************************************************************** * secfork v1.0a - petter wahlman <bactus () sol no> * * Limit the maximum number of processes members * of the group USER_GID can execute. * * compile: * gcc foo.c -DMODULE -D__KERNEL__ -O2 -fomit-frame-pointer \ * -Wstrict-prototypes -Wall -Wunused -c -o secfork * * install: * insmod secfork * * remove: * rmmod secfork * * usage: * echo 64 > /proc/maxprocs # set limit to 64 processes * ***************************************************************/ #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include <linux/config.h> #define __NO_VERSION__ #include <linux/module.h> #include <linux/version.h> char kernel_version [] = UTS_RELEASE; /* #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif */ #include <linux/kernel.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/proc_fs.h> #include <asm/uaccess.h> #include <asm/io.h> #include <sys/syscall.h> #include <errno.h> MODULE_AUTHOR("petter wahlman <bactus () sol no>"); EXPORT_NO_SYMBOLS; #define MAXPROCS 40 #define USER_GID (int)500 #define MAXDATA (int)8 static unsigned long maxprocs = MAXPROCS; extern void *sys_call_table[]; asmlinkage int (*old_fork) (struct pt_regs); static struct user_struct { long count; struct user_struct *next, **pprev; unsigned int uid; }user_t; /***( module_output )***/ static ssize_t module_output(struct file *file, char *buf, size_t len, loff_t *offset) { static int i, finished = 0; char msg[MAXDATA+50]; if (finished) { finished = 0; return 0; } sprintf(msg, "gid: %d restricted to: %ld processes\n", USER_GID, maxprocs); for(i = 0; i < len && msg[i]; i++) put_user(msg[i], buf+i); finished = 1; return i; } /***( module_input )***/ static ssize_t module_input(struct file *file, const char *buf, size_t length, loff_t *offset) { static char data[MAXDATA]; int i; for (i = 0; i < sizeof(data)-1 && i < length; i++) get_user(data[i], buf+i); data[i] = '\0'; maxprocs = simple_strtoul(data, NULL, 10); return i; } static int module_permission(struct inode *inode, int op) { if (op == 4 || (op == 2 && current->euid == 0)) return 0; return -EACCES; } int module_open(struct inode *inode, struct file *file) { MOD_INC_USE_COUNT; return 0; } int module_close(struct inode *inode, struct file *file) { MOD_DEC_USE_COUNT; return 0; } static struct file_operations fops = { NULL, /* lseek */ module_output, module_input, NULL, /* readdir */ NULL, /* select */ NULL, /* ioctl */ NULL, /* mmap */ module_open, NULL, /* flush */ module_close }; static struct inode_operations iops = { &fops, NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ module_permission }; static struct proc_dir_entry proc_entry = { 0, 8, "maxprocs", /* The file name */ S_IFREG | S_IRUGO | S_IWUSR, 1, /* links */ 0, 0, /* uid, gid */ 0, /* size */ &iops, NULL /* read function - in ino structure */ }; /***( new_fork )***/ int new_fork(struct pt_regs regs) { static int n; if (current->uid == 0) return old_fork(regs); for (n = 0; n < NGROUPS; n++) if (current->groups[n] == USER_GID) { if (current->user->count >= maxprocs) return -EPERM; else return old_fork(regs); } return old_fork(regs); } /***( init_module ***/ int init_module(void) { printk("secfork v1.0a - petter wahlman <bactus () sol no>..\n"); old_fork = sys_call_table[__NR_fork]; sys_call_table[__NR_fork] = new_fork; return proc_register(&proc_root, &proc_entry); } void cleanup_module(void) { sys_call_table[__NR_fork] = old_fork; proc_unregister(&proc_root, proc_entry.low_ino); printk("secfork unloaded..\n"); }
Current thread:
- limit maximum nr. of processes. Petter Wahlman (Sep 01)
- Updated Fix Information for Buffer Overflow in Netscape Enterprise and FastTrack Web Servers X-Force (Sep 02)
- Re: limit maximum nr. of processes. Alfonso Lazaro (Sep 03)
- Re: limit maximum nr. of processes. Andrea Costantino (Sep 07)
- ProFTP-1.2.0pre4 buffer overflow -- once more Renaud Deraison (Sep 07)
- Exploiting DCOM to gain Administrative rights on Windows NT 4 Mnemonix (Sep 07)