0

I have script to create a minimal chroot (below), but I can't figure out how to get ulimit to work on the chroot'ed process:

#!/bin/bash

user=$1
apps="$2"
cmd_to_run="$3"
shift 3

directory="minimal_chroot"

if [ ! -d "$directory" ]; then
    mkdir -pv $directory/etc >/dev/null 2>&1

    grep /etc/passwd -e "^$user" | sed "s/\/home\/$user/\//" >> $directory/etc/passwd
    grep /etc/group -e "^$user" >> $directory/etc/group

    mkdir -p "$directory/etc/security/" >/dev/null
    limits="$directory/etc/security/limits.conf"
    echo "$user hard nofile 100" >> $limits

    # cmds can be a space-separated list of commands
    for app in $apps; do
        file_path=`which $app`
        if [ -n "$file_path" ] ; then
            non_root_path=`echo "$file_path" | sed -E 's/^\/(.*$)/\1/'`
            mkdir -pv $directory/`dirname $non_root_path` >/dev/null 2>&1
            cp -v {,$directory}$file_path >/dev/null 2>&1

            for file in `ldd $file_path | grep "/lib" | sed -E 's/^.*[ \t]\/(lib[^ ]+\.[0-9]) .*$/\1/'` ; do
                mkdir -p $directory/`dirname $file | sed -E 's/^\/(.*$)/\1/'` >/dev/null 2>&1
                cp -v {,$directory}/$file >/dev/null 2>&1
            done
        fi
    done
fi

find $directory -maxdepth 1 -type f -exec rm {} + >/dev/null 2>&1

chmod -R o+rwx $directory >/dev/null 2>&1
find $directory -exec chmod o+rx-w {} + >/dev/null 2>&1
chmod o+rw $directory >/dev/null 2>&1

uid=`id -u $user`

ulimit -Su 10
sudo chroot --userspec=$uid:$uid $directory $cmd_to_run $* <&0 &
chroot_pid=$!

trap "kill -INT $chroot_pid" SIGINT SIGTERM SIGXCPU

wait $python_chroot_pid

find $directory -maxdepth 1 -type f -exec rm {} + >/dev/null 2>&1

Output:

blah@dev:~$ sudo ./minimal_chroot.sh chrootuser "ls cd pwd cat bash" bash
bash-4.2$ pwd
/
bash-4.2$ 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) 7806
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) 7806
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
bash-4.2$

notice that max user processes is still at 7806 instead of the 10 that I was trying to specify with the ulimit -Su 10 command. Oh, I was also messing with /etc/security/limits.conf as can be seen with the echo "$user hard nofile 100" >> $limits line. This also is not taking effect.

How can I get ulimits to take effect while still keeping the chroot to a minimum?

Attempt #2

I attempted to swap out this line:

sudo chroot --userspec=$uid:$uid $directory $cmd_to_run $* <&0 &

for this:

sudo chroot $directory bash -c "ulimit -Su 20; su $user; $cmd_to_run $*" <&0 &

This actually worked well, and ulimit -a showed the max user processes to be 20, but then I realized that it didn't su to $user and was still running as root, since I took out the --userspec.

d0c_s4vage
  • 111
  • 5

1 Answers1

1

Notice that limits are enforced via a PAM module, namely pam_limits, and its configuration file is /etc/security/limits.conf by default, but simply putting that configuration file inside the chroot does not provide any real infrastructure.

The output of ulimit -a you are seeing is that of the blah user, which is logged in.

The chroot invocation does not trigger the PAM configuration at any point, and therefore it can't set any limits inside the chroot.

dawud
  • 15,096
  • 3
  • 42
  • 61
  • hmm, I've thought about adding bash to the chroot regardless of the apps passed in, and then running `bash -c "ulimit -Su 10 ; $cmd` in the chroot, but I was hoping to not have to include bash or sh at all. Is there a way to force the PAM configuration to trigger? – d0c_s4vage Mar 21 '14 at 18:44
  • also, wouldn't the `ulimit -a` be the ulimit of root since I ran the script with sudo? Maybe my understanding is off on this point. – d0c_s4vage Mar 21 '14 at 19:04