[11705] in bugtraq

home help back first fref pref prev next nref lref last post

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 )
===========================================================			

home help back first fref pref prev next nref lref last post