6

I have written a bash script to test student written C programs against a test-suite. For some reason the script is getting Killed after a while. I'm a novice in bash scripting and till now has not found the reason. Here's the script.

#!/bin/bash
ulimit -t 1
tests_dir=tests
run_dir=tests
find . -name "*.c" | while read cfile; do rm a.out &> /dev/null; gcc "$cfile" -lm -w &> /dev/null;
if [ ! -f a.out ]; 
then 
    echo "$cfile did-not-compile" >> "$run_dir/results.out";
else
    find "$tests_dir" -name "in*.txt" | while read testin; do echo "running $testin on $cfile"; 
    rm test.out &> /dev/null; 
    rm space_less_testout &> /dev/null;
    LD_PRELOAD=../../EasySandbox/EasySandbox.so ./a.out < $testin | grep -v "entering SECCOMP mode" &> test.out;
    if [ -e test.out ]; then
            testout=${testin/in/out}
            tr -d '\n' < $testout | tr -d ' ' > space_less_testout
            echo -e '\n' >> space_less_testout

            if diff -qwB "$testout" test.out &> /dev/null
            then
                    # if no difference then takes true brance (based on return value)
                    echo "$cfile ;passed-on-test; $testin" >> "$run_dir/results.out"; echo "passed-on-test $testin";
            elif diff -qB space_less_testout test.out &> /dev/null 
            then
                    # or no difference with new-line removed should-be-output (just a formatting error)
                    echo "$cfile ;passed-on-test; $testin" >> "$run_dir/results.out"; echo "passed-on-test $testin";
            else
                    echo "$cfile ;failed-on-test; $testin" >> "$run_dir/results.out"; echo "failed-on-test $testin";
            fi
    fi
done;
fi
done;
5
  • You could run strace or bash -x on it to see where it timeouts. It might also be getting killed by OOM Killer if you run out of memory Jun 9, 2017 at 15:24
  • I don't think LD_PRELOAD is a secure way to implement a sandbox.
    – kasperd
    Jun 10, 2017 at 10:46
  • @kasperd I'm not an expert but I'm following github.com/daveho/EasySandbox
    – rahuL
    Jun 11, 2017 at 14:27
  • @rahuL From your link there is already one exploit documented. The proposed workaround for that exploit is to avoid linking the dl library required for loading dynamic libraries. But if the executable can get to run code before SECCOMP mode is activated it does not need any libraries to do harm. One can use inline assembly to make system calls directly from C code without needing any libraries. Example: __asm__ __volatile__("syscall": "=a"(fd): "a"(2), "D"("/tmp/gotcha"), "S"(O_CREAT|O_WRONLY), "d"(0644));
    – kasperd
    Jun 11, 2017 at 15:48
  • @kasperd Okay. I'll see what other options are there. Thanks.
    – rahuL
    Jun 11, 2017 at 17:53

1 Answer 1

15

ulimit -t 1 limits the script's CPU time to 1 second. When the script has consumed all its CPU time it gets killed.

To limit the CPU time of just one command in your script you can use parentheses to start it in a subshell with its own limit, e.g.

(ulimit -t 1; LD_PRELOAD=../../EasySandbox/EasySandbox.so ./a.out < $testin) 
2
  • But then how do I limit the execution time of student code? I had tried setting limit to 1 second before test-case execution and the increasing it again. But increasing ulimit -t is not allowed it seems.
    – rahuL
    Jun 9, 2017 at 16:06
  • Added that to my answer. Jun 9, 2017 at 16:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .