Subject: Re: limit maximum nr. of processes. To: BUGTRAQ@SECURITYFOCUS.COM El dia Wed, Sep 01, 1999 at 10:53:48AM +0200, Petter Wahlman escribió: to limit the maximum number of processes you can use the Linux-PAM edit /etc/pam.d/login #%PAM-1.0 auth required /lib/security/pam_securetty.so auth required /lib/security/pam_pwdb.so shadow nullok auth required /lib/security/pam_nologin.so account required /lib/security/pam_pwdb.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_pwdb.so shadow nullok use_authtok session required /lib/security/pam_pwdb.so session required /lib/security/pam_limits.so you have to add the last two lines then edit /etc/security/limits.conf # /etc/security/limits.conf # #Each line describes a limit for a user in the form: # # # #Where: # can be: # - an user name # - a group name, with @group syntax # - the wildcard *, for default entry # # can have the two values: # - "soft" for enforcing the soft limits # - "hard" for enforcing hard limits # # can be one of the following: # - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open files # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit # - maxlogins - max number of logins for this user # # # #* soft core 0 #* hard rss 10000 #@student hard nproc 20 #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 #@student - maxlogins 4 as you can see you can limit the number of process and much more like cpu, stack ... > > 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 > * > * 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 > > #define __NO_VERSION__ > #include > #include > char kernel_version [] = UTS_RELEASE; > > /* > #if CONFIG_MODVERSIONS==1 > #define MODVERSIONS > #include > #endif > */ > > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > > MODULE_AUTHOR("petter wahlman "); > 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 ..\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"); > } -- Saludos. =========================================================== Alfonso Lazaro Tellez altellez@ip6seguridad.com Analista de seguridad IP6Seguridad http://www.ip6seguridad.com Tfno: +34 91-3430245 C\Alberto Alcocer 5, 1 D Fax: +34 91-3430294 Madrid ( SPAIN ) ===========================================================