Ulimit Command

Setting and displaying user limits

Ulimit Command

The shell contains a built in command called "Ulimit" which allows you to display and set resource limits for users. The systems resources are defined in a file called "/etc/security/limits.conf". Ulimit can then be used to view these settings.

The defining of system resource limitations is critical to a smooth running system. By defining restrictions to users, you are safe guarding your system from running out of memory, space or from a rouge process that spawns multiple processes. Limits can be placed globally, individually or by group.

The basic syntax of the ulimit command is: ulimit Options limit

Display settings for current user

To display all of your current settings you can issue the command: "ulimit -a"

john@john-desktop:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 19868
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 19868
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

To display individual parameters you must specify the appropriate flag. "-c" would be for "core file size": ulimit -c

To display the "Max user Processes", you could issue the command: ulimit -u

john@john-desktop:~$ ulimit -c
john@john-desktop:~$ ulimit -u


As we mentioned earlier, "/etc/security/limits.conf" is the location for the file that contains user limit settings. Below is an example of a "/etc/security/limits.conf" file taken from an "Ubuntu 12.04 LTS" system:

john@john-desktop:~$ cat /etc/security/limits.conf
# /etc/security/limits.conf
#Each line describes a limit for a user in the form:
#<domain>        <type>  <item>  <value>
#<domain> can be:
#        - an user name
#        - a group name, with @group syntax
#        - the wildcard *, for default entry
#        - the wildcard %, can be also used with %group syntax,
#                 for maxlogin limit
#        - NOTE: group and wildcard limits are not applied to root.
#          To apply a limit to the root user, <domain> must be
#          the literal username root.
#<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 (KB)
#        - maxlogins - max number of logins for this user
#        - maxsyslogins - max number of logins on the system
#        - priority - the priority to run user process with
#        - locks - max number of file locks the user can hold
#        - sigpending - max number of pending signals
#        - msgqueue - max memory used by POSIX message queues (bytes)
#        - nice - max nice priority allowed to raise to values: [-20, 19]
#        - rtprio - max realtime priority
#        - chroot - change root to directory (Debian-specific)
#<domain>      <type>  <item>         <value>

#*               soft    core            0
#root            hard    core            100000
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#ftp             -       chroot          /ftp
#@student        -       maxlogins       4

# End of file

As you can see from the above, limits are either defined as being "soft" or "hard". The hard limit is set by the "root" user or a user with the appropriate escalated privileges. This limit can not be exceeded. The soft limit is also set by the "root" user, however, this limit can be overridden by a user using the "ulimit" command.

As an example, imagine as the system administrator you have defined a hard limit of 100 for the "Max user Processes". This would mean that the user can not go above 100 processes. You might then set a soft limit of 50 for "Max user Processes". This soft value would stop the user from going over 50 processes. However, as this is only a soft limit, the user could use the ulimit command to increase the number of processes up to the hard limit. This new assigned value would then last for the duration of that particular shell. To raise this value you would issue ulimit -u 75. This would raise my max limit now to "75". This limit is only for the current shell!

A common restriction that is applied to many Linux systems is the limiting of the "Max user Processes". By limiting this parameter with a hard value, you stop a badly written script from spawning multiple processes and using all your system resources. An example of a script or function that can spawn multiple processes is a "recursive loop" or a "fork bomb".

Fork Bomb

A "Fork Bomb" is a method of executing a recursive function that continually calls itself and in the process consumes your systems resources. The following code is an example of a simple "fork bomb". WARNING: Do not run this !!

If you do run this, you will get into trouble with your systems administrator as it will consume your systems resources. Often a full reboot is necessary to recover:

[testuser@centos ~]$ :() {
> :|:};:

If you see a screen that display messages similar to the following, it may be too late. This is obviously dependant on the "Max user Process" limit defined:

-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable

To stop this from happening on your system you must define a hard limit for normal users. This limit must be large enough for a user to carry out their daily duties and also small enough so that your system can recover. Many linux distributions have an added security option that will override the "/etc/security/limit.conf" file for the parameter "Max user Processes.

This file is known as: "/etc/security/limits.d/90-nproc.conf"

[testuser@centos limits.d]$ pwd
[testuser@centos limits.d]$ cat 90-nproc.conf 
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

*          soft    nproc     1024

This file acts as a safety net by limiting the number of processes to "1024". It is still best to define a hard limit for the "nproc" value in the normal "/etc/security/limits.conf" file. To stop the "Fork Bomb in the above example, I added the following line to my configuration:

testuser         hard    nproc           30

This meant that I could spawn no more than "30" processes, thus limiting impact to my system.