Setting and displaying user limits

Ulimit command examples

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". The ulimit command 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"


$ 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


$ ulimit -c
0
$ ulimit -u
19868

/etc/security/limits.conf

As 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 a "Linux Mint" system:


# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain>        <type>  <item>  <value>
#
#Where:
#<domain> can be:
#        - a 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 file descriptors
#        - 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 the command "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:


$ :(){ :|:& };:

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


-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable
-bash: fork: 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.

Below is an example of the current "Max user process" value defined for the user "john".


$ whoami
john
$ ulimit -u
5754

From the above, we can see that a "Max user process" value has been set to "5754". To reduce the number of processes that can be run, we can amend the "/etc/security/limits.conf" file as follows.

The following entry has been added for the user "john" limiting the Max Number of Processes (nproc).


john             soft    nproc           100
john             hard    nproc           200

NOTE: For the above change to be picked up by the user, the user must exit their current shell and login again.

Now if I issue the "ulimit -u" command, you will see that the new reduced value has been assigned.


$ ulimit -u
100

Now if we try and execute the "Fork Bomb" again, our session should recover quite quickly as it will be limited now to a max of 100 processes.


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

[1]+  Done                    : | :

This time, the system has recovered. Again, DO NOT RUN THIS on a live system as you may cause impact to other users and services.