[11705] in bugtraq
Re: limit maximum nr. of processes.
daemon@ATHENA.MIT.EDU (Alfonso Lazaro)
Tue Sep 7 07:16:12 1999
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Message-Id: <19990903131802.A16071@ip6seguridad.com>
Date: Fri, 3 Sep 1999 13:18:02 +0200
Reply-To: altellez@IP6SEGURIDAD.COM
From: Alfonso Lazaro <altellez@IP6SEGURIDAD.COM>
X-To: bugtraq <BUGTRAQ@SECURITYFOCUS.COM>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To: <Pine.LNX.4.10.9909010935350.26470-200000@arjuna.proact.no>; from
Petter Wahlman <petter@proact.no> on Wed, Sep 01,
1999 at 10:53:48AM +0200
El dia Wed, Sep 01, 1999 at 10:53:48AM +0200, Petter Wahlman <petter@proact.no> escribis:
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:
#
#<domain> <type> <item> <value>
#
#Where:
#<domain> can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
#<item> 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
#
#<domain> <type> <item> <value>
#
#* 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 <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");
> }
--
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 )
===========================================================