Description:
merge
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r228:3d0f479a7258 - - 5 files changed: 207 inserted, 13 deleted

@@ -0,0 +1,179
1 + #!/bin/sh
2 +
3 + echo "This script will install and configure Cafe grader."
4 +
5 + RUBY_VERSION=2.1.2
6 + echo "This will install Ruby $RUBY_VERSION under RVM"
7 +
8 + echo "Installing required apts"
9 +
10 + sudo zypper install \
11 + g++ gcc libmysqlclient18 build-essential \
12 + git-core openssl libreadline6 libreadline6-devel \
13 + zlib1g zlib1g-devel libssl37 libyaml-devel sqlite3-devel \
14 + sqlite3 libxml2-devel libxslt-devel autoconf libc6-devel \
15 + ncurses-devel automake libtool bison subversion \
16 + pkg-config curl nodejs unzip pyflakes java-1_8_0-openjdk \
17 + libmysqld-devel mercurial python-setuptools python-devel
18 +
19 +
20 + echo "Installing Ruby $RUBY_VERSION in RVM"
21 +
22 + rvm install $RUBY_VERSION
23 + rvm use $RUBY_VERSION
24 +
25 + echo "Fetching Cafe Grader from Git repositories"
26 +
27 + echo "Fetching web interface"
28 +
29 + mkdir cafe_grader
30 + cd cafe_grader
31 + #git clone -q git://github.com/jittat/cafe-grader-web.git web
32 + hg clone git+ssh://git@github.com/nattee/cafe-grader-web.git web
33 +
34 + echo "Configuring rails app"
35 +
36 + cp web/config/application.rb.SAMPLE web/config/application.rb
37 + cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
38 +
39 + #replace UTC in application.rb with the system timezone
40 + timezone='UTC'
41 + if [ -f '/etc/timezone' ]; then
42 + timezone=\"`cat /etc/timezone`\"
43 + else
44 + if [ -f '/etc/sysconfig/clock' ]; then
45 + timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
46 + fi
47 + fi
48 + replace="s!'UTC'!$timezone!g"
49 + sed -i $replace web/config/application.rb
50 +
51 + echo "At this point we will need MySQL user and database."
52 + echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
53 + read ch
54 +
55 + if [ "$ch" = "n" -o "$ch" = "N" ]
56 + then
57 + echo "Please open another terminal and create the user and database for Cafe grader."
58 + echo "Don't forget to grant access to that database for the user."
59 + echo "Please have username, password, and database name ready before continue."
60 + echo
61 + echo "The following are instructions:"
62 + echo "1. Run mysql:"
63 + echo
64 + echo " mysql -u root -p"
65 + echo
66 + echo " if you have just installed mysql, the root password is the one that you have just entered"
67 + echo "2. Create a new database, a new user, and grant access to grader database:"
68 + echo
69 + echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
70 + echo " create database \`DATABASENEME\`;"
71 + echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
72 + echo
73 + echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
74 + echo
75 + echo "Hit enter when ready..."
76 + read dummy
77 + fi
78 +
79 + CAFE_PATH=`pwd`
80 +
81 + cd web
82 +
83 + echo "Please provide grader database:"
84 + read database
85 +
86 + echo "Please provide grader username:"
87 + read username
88 +
89 + echo "Please provide $username password:"
90 + read password
91 +
92 + echo "development:" > config/database.yml
93 + echo " adapter: mysql2" >> config/database.yml
94 + echo " encoding: utf8" >> config/database.yml
95 + echo " reconnect: false" >> config/database.yml
96 + echo " database: $database" >> config/database.yml
97 + echo " pool: 5" >> config/database.yml
98 + echo " username: $username" >> config/database.yml
99 + echo " password: $password" >> config/database.yml
100 + echo " host: localhost" >> config/database.yml
101 + echo " socket: /run/mysql/mysql.sock" >> config/database.yml
102 + echo "" >> config/database.yml
103 + echo "production:" >> config/database.yml
104 + echo " adapter: mysql2" >> config/database.yml
105 + echo " encoding: utf8" >> config/database.yml
106 + echo " reconnect: false" >> config/database.yml
107 + echo " database: $database" >> config/database.yml
108 + echo " pool: 5" >> config/database.yml
109 + echo " username: $username" >> config/database.yml
110 + echo " password: $password" >> config/database.yml
111 + echo " host: localhost" >> config/database.yml
112 + echo " socket: /run/mysql/mysql.sock" >> config/database.yml
113 +
114 + echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
115 + echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
116 + echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
117 + echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
118 +
119 + echo "Installing required gems"
120 + gem install bundler
121 + bundle install
122 +
123 + echo "Running rake tasks to initialize database"
124 +
125 + rake db:migrate
126 + rake db:seed
127 +
128 + echo "Running rake tasks to precompile the assets"
129 +
130 + rake assets:precompile
131 +
132 + echo "Intalling web interface complete..."
133 + echo
134 + echo "Fetching grader"
135 +
136 + cd ..
137 +
138 + mkdir judge
139 + cd judge
140 + #git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
141 + hg clone git+ssh://git@github.com/nattee/cafe-grader-judge-scripts.git scripts
142 + mkdir raw
143 + mkdir ev-exam
144 + mkdir ev
145 + mkdir result
146 + mkdir log
147 +
148 + echo "Configuring grader"
149 +
150 + cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
151 + cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
152 +
153 + # create new environment.rb file
154 + echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
155 + echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
156 + echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
157 + echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
158 +
159 + # compiling box
160 + MACHINE_TYPE=`uname -m`
161 + if [ ${MACHINE_TYPE} == 'x86_64' ]; then
162 + gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
163 + else
164 + g++ -o scripts/std-script/box scripts/std-script/box.cc
165 + fi
166 +
167 +
168 + cd ..
169 +
170 + echo "Now you are ready to run cafe grader...."
171 + echo
172 + echo "Try:"
173 + echo
174 + echo " cd web"
175 + echo " rails s"
176 + echo
177 + echo "and access web at http://localhost:3000/"
178 + echo "The root username is 'root', its password is 'ioionrails'."
179 +
@@ -1,180 +1,181
1 #!/bin/sh
1 #!/bin/sh
2
2
3 echo "This script will install and configure Cafe grader."
3 echo "This script will install and configure Cafe grader."
4
4
5 RUBY_VERSION=2.1.2
5 RUBY_VERSION=2.1.2
6 echo "This will install Ruby $RUBY_VERSION under RVM"
6 echo "This will install Ruby $RUBY_VERSION under RVM"
7
7
8 echo "Installing required apts"
8 echo "Installing required apts"
9
9
10 sudo apt-get update
10 sudo apt-get update
11 sudo apt-get install mysql-server mysql-client \
11 sudo apt-get install mysql-server mysql-client \
12 - g++ gcc apache2 libmysqlclient15-dev build-essential \
12 + g++ gcc apache2 libmysqlclient20 build-essential \
13 git-core openssl libreadline6 libreadline6-dev \
13 git-core openssl libreadline6 libreadline6-dev \
14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
16 ncurses-dev automake libtool bison subversion \
16 ncurses-dev automake libtool bison subversion \
17 - pkg-config curl nodejs unzip pyflakes ruby default-jdk
17 + pkg-config curl nodejs unzip pyflakes ruby default-jdk \
18 + libmysqld-dev mercurial python-setuptools python-dev python3-numpy
18
19
19 echo "Installing RVM"
20 echo "Installing RVM"
20 curl -k -L https://get.rvm.io | bash -s stable
21 curl -k -L https://get.rvm.io | bash -s stable
21 source ~/.rvm/scripts/rvm
22 source ~/.rvm/scripts/rvm
22
23
23 echo "Installing Ruby $RUBY_VERSION in RVM"
24 echo "Installing Ruby $RUBY_VERSION in RVM"
24
25
25 rvm install $RUBY_VERSION
26 rvm install $RUBY_VERSION
26 rvm use $RUBY_VERSION
27 rvm use $RUBY_VERSION
27
28
28 echo "Fetching Cafe Grader from Git repositories"
29 echo "Fetching Cafe Grader from Git repositories"
29
30
30 echo "Fetching web interface"
31 echo "Fetching web interface"
31
32
32 mkdir cafe_grader
33 mkdir cafe_grader
33 cd cafe_grader
34 cd cafe_grader
34 git clone -q git://github.com/jittat/cafe-grader-web.git web
35 git clone -q git://github.com/jittat/cafe-grader-web.git web
35
36
36 echo "Configuring rails app"
37 echo "Configuring rails app"
37
38
38 cp web/config/application.rb.SAMPLE web/config/application.rb
39 cp web/config/application.rb.SAMPLE web/config/application.rb
39 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
40 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
40
41
41 #replace UTC in application.rb with the system timezone
42 #replace UTC in application.rb with the system timezone
42 timezone='UTC'
43 timezone='UTC'
43 if [ -f '/etc/timezone' ]; then
44 if [ -f '/etc/timezone' ]; then
44 timezone=\"`cat /etc/timezone`\"
45 timezone=\"`cat /etc/timezone`\"
45 else
46 else
46 if [ -f '/etc/sysconfig/clock' ]; then
47 if [ -f '/etc/sysconfig/clock' ]; then
47 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
48 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
48 fi
49 fi
49 fi
50 fi
50 replace="s!'UTC'!$timezone!g"
51 replace="s!'UTC'!$timezone!g"
51 sed -i $replace web/config/application.rb
52 sed -i $replace web/config/application.rb
52
53
53 echo "At this point we will need MySQL user and database."
54 echo "At this point we will need MySQL user and database."
54 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
55 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
55 read ch
56 read ch
56
57
57 if [ "$ch" = "n" -o "$ch" = "N" ]
58 if [ "$ch" = "n" -o "$ch" = "N" ]
58 then
59 then
59 echo "Please open another terminal and create the user and database for Cafe grader."
60 echo "Please open another terminal and create the user and database for Cafe grader."
60 echo "Don't forget to grant access to that database for the user."
61 echo "Don't forget to grant access to that database for the user."
61 echo "Please have username, password, and database name ready before continue."
62 echo "Please have username, password, and database name ready before continue."
62 echo
63 echo
63 echo "The following are instructions:"
64 echo "The following are instructions:"
64 echo "1. Run mysql:"
65 echo "1. Run mysql:"
65 echo
66 echo
66 echo " mysql -u root -p"
67 echo " mysql -u root -p"
67 echo
68 echo
68 echo " if you have just installed mysql, the root password is the one that you have just entered"
69 echo " if you have just installed mysql, the root password is the one that you have just entered"
69 echo "2. Create a new database, a new user, and grant access to grader database:"
70 echo "2. Create a new database, a new user, and grant access to grader database:"
70 echo
71 echo
71 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
72 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
72 echo " create database \`DATABASENEME\`;"
73 echo " create database \`DATABASENEME\`;"
73 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
74 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
74 echo
75 echo
75 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
76 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
76 echo
77 echo
77 echo "Hit enter when ready..."
78 echo "Hit enter when ready..."
78 read dummy
79 read dummy
79 fi
80 fi
80
81
81 CAFE_PATH=`pwd`
82 CAFE_PATH=`pwd`
82
83
83 cd web
84 cd web
84
85
85 echo "Please provide grader database:"
86 echo "Please provide grader database:"
86 read database
87 read database
87
88
88 echo "Please provide grader username:"
89 echo "Please provide grader username:"
89 read username
90 read username
90
91
91 echo "Please provide $username password:"
92 echo "Please provide $username password:"
92 read password
93 read password
93
94
94 echo "development:" > config/database.yml
95 echo "development:" > config/database.yml
95 echo " adapter: mysql2" >> config/database.yml
96 echo " adapter: mysql2" >> config/database.yml
96 echo " encoding: utf8" >> config/database.yml
97 echo " encoding: utf8" >> config/database.yml
97 echo " reconnect: false" >> config/database.yml
98 echo " reconnect: false" >> config/database.yml
98 echo " database: $database" >> config/database.yml
99 echo " database: $database" >> config/database.yml
99 echo " pool: 5" >> config/database.yml
100 echo " pool: 5" >> config/database.yml
100 echo " username: $username" >> config/database.yml
101 echo " username: $username" >> config/database.yml
101 echo " password: $password" >> config/database.yml
102 echo " password: $password" >> config/database.yml
102 echo " host: localhost" >> config/database.yml
103 echo " host: localhost" >> config/database.yml
103 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
104 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
104 echo "" >> config/database.yml
105 echo "" >> config/database.yml
105 echo "production:" >> config/database.yml
106 echo "production:" >> config/database.yml
106 echo " adapter: mysql2" >> config/database.yml
107 echo " adapter: mysql2" >> config/database.yml
107 echo " encoding: utf8" >> config/database.yml
108 echo " encoding: utf8" >> config/database.yml
108 echo " reconnect: false" >> config/database.yml
109 echo " reconnect: false" >> config/database.yml
109 echo " database: $database" >> config/database.yml
110 echo " database: $database" >> config/database.yml
110 echo " pool: 5" >> config/database.yml
111 echo " pool: 5" >> config/database.yml
111 echo " username: $username" >> config/database.yml
112 echo " username: $username" >> config/database.yml
112 echo " password: $password" >> config/database.yml
113 echo " password: $password" >> config/database.yml
113 echo " host: localhost" >> config/database.yml
114 echo " host: localhost" >> config/database.yml
114 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
115 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
115
116
116 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
117 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
117 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
118 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
118 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
119 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
119 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
120 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
120
121
121 echo "Installing required gems"
122 echo "Installing required gems"
122 gem install bundler
123 gem install bundler
123 bundle install
124 bundle install
124
125
125 echo "Running rake tasks to initialize database"
126 echo "Running rake tasks to initialize database"
126
127
127 rake db:migrate
128 rake db:migrate
128 rake db:seed
129 rake db:seed
129
130
130 echo "Running rake tasks to precompile the assets"
131 echo "Running rake tasks to precompile the assets"
131
132
132 rake assets:precompile
133 rake assets:precompile
133
134
134 echo "Intalling web interface complete..."
135 echo "Intalling web interface complete..."
135 echo
136 echo
136 echo "Fetching grader"
137 echo "Fetching grader"
137
138
138 cd ..
139 cd ..
139
140
140 mkdir judge
141 mkdir judge
141 cd judge
142 cd judge
142 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
143 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
143 mkdir raw
144 mkdir raw
144 mkdir ev-exam
145 mkdir ev-exam
145 mkdir ev
146 mkdir ev
146 mkdir result
147 mkdir result
147 mkdir log
148 mkdir log
148
149
149 echo "Configuring grader"
150 echo "Configuring grader"
150
151
151 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
152 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
152 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
153 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
153
154
154 # create new environment.rb file
155 # create new environment.rb file
155 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
156 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
156 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
157 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
157 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
158 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
158 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
159 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
159
160
160 # compiling box
161 # compiling box
161 MACHINE_TYPE=`uname -m`
162 MACHINE_TYPE=`uname -m`
162 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
163 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
163 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
164 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
164 else
165 else
165 g++ -o scripts/std-script/box scripts/std-script/box.cc
166 g++ -o scripts/std-script/box scripts/std-script/box.cc
166 fi
167 fi
167
168
168
169
169 cd ..
170 cd ..
170
171
171 echo "Now you are ready to run cafe grader...."
172 echo "Now you are ready to run cafe grader...."
172 echo
173 echo
173 echo "Try:"
174 echo "Try:"
174 echo
175 echo
175 echo " cd web"
176 echo " cd web"
176 echo " rails s"
177 echo " rails s"
177 echo
178 echo
178 echo "and access web at http://localhost:3000/"
179 echo "and access web at http://localhost:3000/"
179 echo "The root username is 'root', its password is 'ioionrails'."
180 echo "The root username is 'root', its password is 'ioionrails'."
180
181
@@ -1,1373 +1,1385
1 /*
1 /*
2 * A Simple Sandbox for Moe
2 * A Simple Sandbox for Moe
3 *
3 *
4 * (c) 2001--2010 Martin Mares <mj@ucw.cz>
4 * (c) 2001--2010 Martin Mares <mj@ucw.cz>
5 */
5 */
6
6
7 #define _LARGEFILE64_SOURCE
7 #define _LARGEFILE64_SOURCE
8 #define _GNU_SOURCE
8 #define _GNU_SOURCE
9
9
10 /* Generated automatically by ./configure, please don't touch manually. */
10 /* Generated automatically by ./configure, please don't touch manually. */
11 #define CONFIG_BOX_KERNEL_AMD64 1
11 #define CONFIG_BOX_KERNEL_AMD64 1
12 #define CONFIG_BOX_USER_AMD64 1
12 #define CONFIG_BOX_USER_AMD64 1
13 #define CONFIG_DIR "cf"
13 #define CONFIG_DIR "cf"
14 #define CONFIG_DIRECT_IO 1
14 #define CONFIG_DIRECT_IO 1
15 #define CONFIG_ISOLATE_BOX_DIR "/tmp/box"
15 #define CONFIG_ISOLATE_BOX_DIR "/tmp/box"
16 #define CONFIG_ISOLATE_CGROUP_ROOT "/sys/fs/cgroup"
16 #define CONFIG_ISOLATE_CGROUP_ROOT "/sys/fs/cgroup"
17 #define CONFIG_ISOLATE_FIRST_GID 60000
17 #define CONFIG_ISOLATE_FIRST_GID 60000
18 #define CONFIG_ISOLATE_FIRST_UID 60000
18 #define CONFIG_ISOLATE_FIRST_UID 60000
19 #define CONFIG_ISOLATE_NUM_BOXES 100
19 #define CONFIG_ISOLATE_NUM_BOXES 100
20 #define CONFIG_LARGE_FILES 1
20 #define CONFIG_LARGE_FILES 1
21 #define CONFIG_LFS 1
21 #define CONFIG_LFS 1
22 #define CONFIG_LINUX 1
22 #define CONFIG_LINUX 1
23 #define CONFIG_LOCAL 1
23 #define CONFIG_LOCAL 1
24 #define CONFIG_UCW_PARTMAP_IS_MMAP 1
24 #define CONFIG_UCW_PARTMAP_IS_MMAP 1
25 #define CONFIG_UCW_PERL 1
25 #define CONFIG_UCW_PERL 1
26 #define CONFIG_UCW_POOL_IS_MMAP 1
26 #define CONFIG_UCW_POOL_IS_MMAP 1
27 #define CONFIG_UCW_RADIX_SORTER_BITS 10
27 #define CONFIG_UCW_RADIX_SORTER_BITS 10
28 #define CONFIG_UCW_SHELL_UTILS 1
28 #define CONFIG_UCW_SHELL_UTILS 1
29 #define CPU_64BIT_POINTERS 1
29 #define CPU_64BIT_POINTERS 1
30 #define CPU_ALLOW_UNALIGNED 1
30 #define CPU_ALLOW_UNALIGNED 1
31 #define CPU_AMD64 1
31 #define CPU_AMD64 1
32 #define CPU_ARCH "default"
32 #define CPU_ARCH "default"
33 #define CPU_LITTLE_ENDIAN 1
33 #define CPU_LITTLE_ENDIAN 1
34 #define CPU_PAGE_SIZE 4096
34 #define CPU_PAGE_SIZE 4096
35 #define CPU_STRUCT_ALIGN 8
35 #define CPU_STRUCT_ALIGN 8
36 #define CWARNS_OFF " -Wno-pointer-sign"
36 #define CWARNS_OFF " -Wno-pointer-sign"
37 #define HAVE_ASCII_DOC "none"
37 #define HAVE_ASCII_DOC "none"
38 #define INSTALL_BIN_DIR "bin"
38 #define INSTALL_BIN_DIR "bin"
39 #define INSTALL_CONFIG_DIR "cf"
39 #define INSTALL_CONFIG_DIR "cf"
40 #define INSTALL_DOC_DIR "share/doc"
40 #define INSTALL_DOC_DIR "share/doc"
41 #define INSTALL_INCLUDE_DIR "include"
41 #define INSTALL_INCLUDE_DIR "include"
42 #define INSTALL_LIB_DIR "lib"
42 #define INSTALL_LIB_DIR "lib"
43 #define INSTALL_LOG_DIR "log"
43 #define INSTALL_LOG_DIR "log"
44 #define INSTALL_MAN_DIR "share/man"
44 #define INSTALL_MAN_DIR "share/man"
45 #define INSTALL_PERL_DIR "lib/perl5"
45 #define INSTALL_PERL_DIR "lib/perl5"
46 #define INSTALL_PKGCONFIG_DIR "lib/pkgconfig"
46 #define INSTALL_PKGCONFIG_DIR "lib/pkgconfig"
47 #define INSTALL_PREFIX
47 #define INSTALL_PREFIX
48 #define INSTALL_RUN_DIR "run"
48 #define INSTALL_RUN_DIR "run"
49 #define INSTALL_SBIN_DIR "sbin"
49 #define INSTALL_SBIN_DIR "sbin"
50 #define INSTALL_SHARE_DIR "share"
50 #define INSTALL_SHARE_DIR "share"
51 #define INSTALL_STATE_DIR "lib"
51 #define INSTALL_STATE_DIR "lib"
52 #define INSTALL_USR_PREFIX
52 #define INSTALL_USR_PREFIX
53 #define INSTALL_VAR_PREFIX
53 #define INSTALL_VAR_PREFIX
54 #define SHERLOCK_VERSION "3.99.2"
54 #define SHERLOCK_VERSION "3.99.2"
55 #define SHERLOCK_VERSION_CODE 3099002
55 #define SHERLOCK_VERSION_CODE 3099002
56 #define SONAME_PREFIX "lib/"
56 #define SONAME_PREFIX "lib/"
57 #define UCW_VERSION "3.99.2"
57 #define UCW_VERSION "3.99.2"
58 #define UCW_VERSION_CODE 3099002
58 #define UCW_VERSION_CODE 3099002
59
59
60 #include <errno.h>
60 #include <errno.h>
61 #include <stdio.h>
61 #include <stdio.h>
62 #include <fcntl.h>
62 #include <fcntl.h>
63 #include <stdlib.h>
63 #include <stdlib.h>
64 #include <string.h>
64 #include <string.h>
65 #include <stdarg.h>
65 #include <stdarg.h>
66 #include <stdint.h>
66 #include <stdint.h>
67 #include <unistd.h>
67 #include <unistd.h>
68 #include <getopt.h>
68 #include <getopt.h>
69 #include <time.h>
69 #include <time.h>
70 #include <sys/wait.h>
70 #include <sys/wait.h>
71 #include <sys/user.h>
71 #include <sys/user.h>
72 #include <sys/time.h>
72 #include <sys/time.h>
73 #include <sys/ptrace.h>
73 #include <sys/ptrace.h>
74 #include <sys/signal.h>
74 #include <sys/signal.h>
75 #include <sys/sysinfo.h>
75 #include <sys/sysinfo.h>
76 #include <sys/resource.h>
76 #include <sys/resource.h>
77 #include <sys/utsname.h>
77 #include <sys/utsname.h>
78 //#include <linux/ptrace.h>
78 //#include <linux/ptrace.h>
79
79
80 #if defined(CONFIG_BOX_KERNEL_AMD64) && !defined(CONFIG_BOX_USER_AMD64)
80 #if defined(CONFIG_BOX_KERNEL_AMD64) && !defined(CONFIG_BOX_USER_AMD64)
81 #include <asm/unistd_32.h>
81 #include <asm/unistd_32.h>
82 #define NATIVE_NR_execve 59 /* 64-bit execve */
82 #define NATIVE_NR_execve 59 /* 64-bit execve */
83 #else
83 #else
84 #include <asm/unistd.h>
84 #include <asm/unistd.h>
85 #define NATIVE_NR_execve __NR_execve
85 #define NATIVE_NR_execve __NR_execve
86 #endif
86 #endif
87
87
88 #define NONRET __attribute__((noreturn))
88 #define NONRET __attribute__((noreturn))
89 #define UNUSED __attribute__((unused))
89 #define UNUSED __attribute__((unused))
90 #define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof(a[0]))
90 #define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof(a[0]))
91
91
92 static int filter_syscalls; /* 0=off, 1=liberal, 2=totalitarian */
92 static int filter_syscalls; /* 0=off, 1=liberal, 2=totalitarian */
93 static int timeout; /* milliseconds */
93 static int timeout; /* milliseconds */
94 static int wall_timeout;
94 static int wall_timeout;
95 static int extra_timeout;
95 static int extra_timeout;
96 static int pass_environ;
96 static int pass_environ;
97 static int file_access;
97 static int file_access;
98 static int verbose;
98 static int verbose;
99 static int memory_limit;
99 static int memory_limit;
100 static int stack_limit;
100 static int stack_limit;
101 static char *redir_stdin, *redir_stdout, *redir_stderr;
101 static char *redir_stdin, *redir_stdout, *redir_stderr;
102 static char *set_cwd;
102 static char *set_cwd;
103
103
104 static pid_t box_pid;
104 static pid_t box_pid;
105 static int is_ptraced;
105 static int is_ptraced;
106 static volatile int timer_tick;
106 static volatile int timer_tick;
107 static struct timeval start_time;
107 static struct timeval start_time;
108 static int ticks_per_sec;
108 static int ticks_per_sec;
109 static int exec_seen;
109 static int exec_seen;
110 static int partial_line;
110 static int partial_line;
111
111
112 static int mem_peak_kb;
112 static int mem_peak_kb;
113 static int total_ms, wall_ms, sys_ms;
113 static int total_ms, wall_ms, sys_ms;
114
114
115 static void die(char *msg, ...) NONRET;
115 static void die(char *msg, ...) NONRET;
116 static void sample_mem_peak(void);
116 static void sample_mem_peak(void);
117
117
118 /*** Meta-files ***/
118 /*** Meta-files ***/
119
119
120 static FILE *metafile;
120 static FILE *metafile;
121
121
122 static void
122 static void
123 meta_open(const char *name)
123 meta_open(const char *name)
124 {
124 {
125 if (!strcmp(name, "-"))
125 if (!strcmp(name, "-"))
126 {
126 {
127 metafile = stdout;
127 metafile = stdout;
128 return;
128 return;
129 }
129 }
130 metafile = fopen(name, "w");
130 metafile = fopen(name, "w");
131 if (!metafile)
131 if (!metafile)
132 die("Failed to open metafile '%s'",name);
132 die("Failed to open metafile '%s'",name);
133 }
133 }
134
134
135 static void
135 static void
136 meta_close(void)
136 meta_close(void)
137 {
137 {
138 if (metafile && metafile != stdout)
138 if (metafile && metafile != stdout)
139 fclose(metafile);
139 fclose(metafile);
140 }
140 }
141
141
142 static void __attribute__((format(printf,1,2)))
142 static void __attribute__((format(printf,1,2)))
143 meta_printf(const char *fmt, ...)
143 meta_printf(const char *fmt, ...)
144 {
144 {
145 if (!metafile)
145 if (!metafile)
146 return;
146 return;
147
147
148 va_list args;
148 va_list args;
149 va_start(args, fmt);
149 va_start(args, fmt);
150 vfprintf(metafile, fmt, args);
150 vfprintf(metafile, fmt, args);
151 va_end(args);
151 va_end(args);
152 }
152 }
153
153
154
154
155 static void print_running_stat(double wall_time,
155 static void print_running_stat(double wall_time,
156 double user_time,
156 double user_time,
157 double system_time,
157 double system_time,
158 int mem_usage)
158 int mem_usage)
159 {
159 {
160 //total is user
160 //total is user
161 //wall is wall
161 //wall is wall
162 //
162 //
163 fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dkbytes\n",
163 fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dkbytes\n",
164 wall_time, user_time, system_time, mem_usage);
164 wall_time, user_time, system_time, mem_usage);
165 }
165 }
166
166
167 static void
167 static void
168 final_stats(struct rusage *rus)
168 final_stats(struct rusage *rus)
169 {
169 {
170 struct timeval total, now, wall;
170 struct timeval total, now, wall;
171 timeradd(&rus->ru_utime, &rus->ru_stime, &total);
171 timeradd(&rus->ru_utime, &rus->ru_stime, &total);
172 total_ms = total.tv_sec*1000 + total.tv_usec/1000;
172 total_ms = total.tv_sec*1000 + total.tv_usec/1000;
173 gettimeofday(&now, NULL);
173 gettimeofday(&now, NULL);
174 timersub(&now, &start_time, &wall);
174 timersub(&now, &start_time, &wall);
175 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
175 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
176 sys_ms = rus->ru_stime.tv_sec * 1000 + rus->ru_stime.tv_usec / 1000;
176 sys_ms = rus->ru_stime.tv_sec * 1000 + rus->ru_stime.tv_usec / 1000;
177
177
178 meta_printf("time:%d.%03d\n", total_ms/1000, total_ms%1000);
178 meta_printf("time:%d.%03d\n", total_ms/1000, total_ms%1000);
179 meta_printf("time-wall:%d.%03d\n", wall_ms/1000, wall_ms%1000);
179 meta_printf("time-wall:%d.%03d\n", wall_ms/1000, wall_ms%1000);
180 meta_printf("mem:%llu\n", (unsigned long long) mem_peak_kb * 1024);
180 meta_printf("mem:%llu\n", (unsigned long long) mem_peak_kb * 1024);
181 }
181 }
182
182
183 /*** Messages and exits ***/
183 /*** Messages and exits ***/
184
184
185 static void NONRET
185 static void NONRET
186 box_exit(int rc)
186 box_exit(int rc)
187 {
187 {
188 if (box_pid > 0)
188 if (box_pid > 0)
189 {
189 {
190 sample_mem_peak();
190 sample_mem_peak();
191 if (is_ptraced)
191 if (is_ptraced)
192 ptrace(PTRACE_KILL, box_pid);
192 ptrace(PTRACE_KILL, box_pid);
193 kill(-box_pid, SIGKILL);
193 kill(-box_pid, SIGKILL);
194 kill(box_pid, SIGKILL);
194 kill(box_pid, SIGKILL);
195 meta_printf("killed:1\n");
195 meta_printf("killed:1\n");
196
196
197 struct rusage rus;
197 struct rusage rus;
198 int p, stat;
198 int p, stat;
199 do
199 do
200 p = wait4(box_pid, &stat, 0, &rus);
200 p = wait4(box_pid, &stat, 0, &rus);
201 while (p < 0 && errno == EINTR);
201 while (p < 0 && errno == EINTR);
202 if (p < 0)
202 if (p < 0)
203 fprintf(stderr, "UGH: Lost track of the process (%m)\n");
203 fprintf(stderr, "UGH: Lost track of the process (%m)\n");
204 else {
204 else {
205 final_stats(&rus);
205 final_stats(&rus);
206 }
206 }
207 }
207 }
208 print_running_stat(
208 print_running_stat(
209 (double)wall_ms/1000,
209 (double)wall_ms/1000,
210 (double)total_ms/1000,
210 (double)total_ms/1000,
211 (double)sys_ms/1000,
211 (double)sys_ms/1000,
212 mem_peak_kb);
212 mem_peak_kb);
213 meta_close();
213 meta_close();
214 exit(rc);
214 exit(rc);
215 }
215 }
216
216
217 static void
217 static void
218 flush_line(void)
218 flush_line(void)
219 {
219 {
220 if (partial_line)
220 if (partial_line)
221 fputc('\n', stderr);
221 fputc('\n', stderr);
222 partial_line = 0;
222 partial_line = 0;
223 }
223 }
224
224
225 /* Report an error of the sandbox itself */
225 /* Report an error of the sandbox itself */
226 static void NONRET __attribute__((format(printf,1,2)))
226 static void NONRET __attribute__((format(printf,1,2)))
227 die(char *msg, ...)
227 die(char *msg, ...)
228 {
228 {
229 va_list args;
229 va_list args;
230 va_start(args, msg);
230 va_start(args, msg);
231 flush_line();
231 flush_line();
232 char buf[1024];
232 char buf[1024];
233 vsnprintf(buf, sizeof(buf), msg, args);
233 vsnprintf(buf, sizeof(buf), msg, args);
234 meta_printf("status:XX\nmessage:%s\n", buf);
234 meta_printf("status:XX\nmessage:%s\n", buf);
235 fputs(buf, stderr);
235 fputs(buf, stderr);
236 fputc('\n', stderr);
236 fputc('\n', stderr);
237 box_exit(2);
237 box_exit(2);
238 }
238 }
239
239
240 /* Report an error of the program inside the sandbox */
240 /* Report an error of the program inside the sandbox */
241 static void NONRET __attribute__((format(printf,1,2)))
241 static void NONRET __attribute__((format(printf,1,2)))
242 err(char *msg, ...)
242 err(char *msg, ...)
243 {
243 {
244 va_list args;
244 va_list args;
245 va_start(args, msg);
245 va_start(args, msg);
246 flush_line();
246 flush_line();
247 if (msg[0] && msg[1] && msg[2] == ':' && msg[3] == ' ')
247 if (msg[0] && msg[1] && msg[2] == ':' && msg[3] == ' ')
248 {
248 {
249 meta_printf("status:%c%c\n", msg[0], msg[1]);
249 meta_printf("status:%c%c\n", msg[0], msg[1]);
250 msg += 4;
250 msg += 4;
251 }
251 }
252 char buf[1024];
252 char buf[1024];
253 vsnprintf(buf, sizeof(buf), msg, args);
253 vsnprintf(buf, sizeof(buf), msg, args);
254 meta_printf("message:%s\n", buf);
254 meta_printf("message:%s\n", buf);
255 fputs(buf, stderr);
255 fputs(buf, stderr);
256 fputc('\n', stderr);
256 fputc('\n', stderr);
257 box_exit(1);
257 box_exit(1);
258 }
258 }
259
259
260 /* Write a message, but only if in verbose mode */
260 /* Write a message, but only if in verbose mode */
261 static void __attribute__((format(printf,1,2)))
261 static void __attribute__((format(printf,1,2)))
262 msg(char *msg, ...)
262 msg(char *msg, ...)
263 {
263 {
264 va_list args;
264 va_list args;
265 va_start(args, msg);
265 va_start(args, msg);
266 if (verbose)
266 if (verbose)
267 {
267 {
268 int len = strlen(msg);
268 int len = strlen(msg);
269 if (len > 0)
269 if (len > 0)
270 partial_line = (msg[len-1] != '\n');
270 partial_line = (msg[len-1] != '\n');
271 vfprintf(stderr, msg, args);
271 vfprintf(stderr, msg, args);
272 fflush(stderr);
272 fflush(stderr);
273 }
273 }
274 va_end(args);
274 va_end(args);
275 }
275 }
276
276
277 static void *
277 static void *
278 xmalloc(size_t size)
278 xmalloc(size_t size)
279 {
279 {
280 void *p = malloc(size);
280 void *p = malloc(size);
281 if (!p)
281 if (!p)
282 die("Out of memory");
282 die("Out of memory");
283 return p;
283 return p;
284 }
284 }
285
285
286 /*** Syscall rules ***/
286 /*** Syscall rules ***/
287
287
288 static const char * const syscall_names[] = {
288 static const char * const syscall_names[] = {
289
289
290 /* Syscall table automatically generated by mk-syscall-table */
290 /* Syscall table automatically generated by mk-syscall-table */
291
291
292 /* 0 */ [ __NR_read ] = "read",
292 /* 0 */ [ __NR_read ] = "read",
293 /* 1 */ [ __NR_write ] = "write",
293 /* 1 */ [ __NR_write ] = "write",
294 /* 2 */ [ __NR_open ] = "open",
294 /* 2 */ [ __NR_open ] = "open",
295 /* 3 */ [ __NR_close ] = "close",
295 /* 3 */ [ __NR_close ] = "close",
296 /* 4 */ [ __NR_stat ] = "stat",
296 /* 4 */ [ __NR_stat ] = "stat",
297 /* 5 */ [ __NR_fstat ] = "fstat",
297 /* 5 */ [ __NR_fstat ] = "fstat",
298 /* 6 */ [ __NR_lstat ] = "lstat",
298 /* 6 */ [ __NR_lstat ] = "lstat",
299 /* 7 */ [ __NR_poll ] = "poll",
299 /* 7 */ [ __NR_poll ] = "poll",
300 /* 8 */ [ __NR_lseek ] = "lseek",
300 /* 8 */ [ __NR_lseek ] = "lseek",
301 /* 9 */ [ __NR_mmap ] = "mmap",
301 /* 9 */ [ __NR_mmap ] = "mmap",
302 /* 10 */ [ __NR_mprotect ] = "mprotect",
302 /* 10 */ [ __NR_mprotect ] = "mprotect",
303 /* 11 */ [ __NR_munmap ] = "munmap",
303 /* 11 */ [ __NR_munmap ] = "munmap",
304 /* 12 */ [ __NR_brk ] = "brk",
304 /* 12 */ [ __NR_brk ] = "brk",
305 /* 13 */ [ __NR_rt_sigaction ] = "rt_sigaction",
305 /* 13 */ [ __NR_rt_sigaction ] = "rt_sigaction",
306 /* 14 */ [ __NR_rt_sigprocmask ] = "rt_sigprocmask",
306 /* 14 */ [ __NR_rt_sigprocmask ] = "rt_sigprocmask",
307 /* 15 */ [ __NR_rt_sigreturn ] = "rt_sigreturn",
307 /* 15 */ [ __NR_rt_sigreturn ] = "rt_sigreturn",
308 /* 16 */ [ __NR_ioctl ] = "ioctl",
308 /* 16 */ [ __NR_ioctl ] = "ioctl",
309 /* 17 */ [ __NR_pread64 ] = "pread64",
309 /* 17 */ [ __NR_pread64 ] = "pread64",
310 /* 18 */ [ __NR_pwrite64 ] = "pwrite64",
310 /* 18 */ [ __NR_pwrite64 ] = "pwrite64",
311 /* 19 */ [ __NR_readv ] = "readv",
311 /* 19 */ [ __NR_readv ] = "readv",
312 /* 20 */ [ __NR_writev ] = "writev",
312 /* 20 */ [ __NR_writev ] = "writev",
313 /* 21 */ [ __NR_access ] = "access",
313 /* 21 */ [ __NR_access ] = "access",
314 /* 22 */ [ __NR_pipe ] = "pipe",
314 /* 22 */ [ __NR_pipe ] = "pipe",
315 /* 23 */ [ __NR_select ] = "select",
315 /* 23 */ [ __NR_select ] = "select",
316 /* 24 */ [ __NR_sched_yield ] = "sched_yield",
316 /* 24 */ [ __NR_sched_yield ] = "sched_yield",
317 /* 25 */ [ __NR_mremap ] = "mremap",
317 /* 25 */ [ __NR_mremap ] = "mremap",
318 /* 26 */ [ __NR_msync ] = "msync",
318 /* 26 */ [ __NR_msync ] = "msync",
319 /* 27 */ [ __NR_mincore ] = "mincore",
319 /* 27 */ [ __NR_mincore ] = "mincore",
320 /* 28 */ [ __NR_madvise ] = "madvise",
320 /* 28 */ [ __NR_madvise ] = "madvise",
321 /* 29 */ [ __NR_shmget ] = "shmget",
321 /* 29 */ [ __NR_shmget ] = "shmget",
322 /* 30 */ [ __NR_shmat ] = "shmat",
322 /* 30 */ [ __NR_shmat ] = "shmat",
323 /* 31 */ [ __NR_shmctl ] = "shmctl",
323 /* 31 */ [ __NR_shmctl ] = "shmctl",
324 /* 32 */ [ __NR_dup ] = "dup",
324 /* 32 */ [ __NR_dup ] = "dup",
325 /* 33 */ [ __NR_dup2 ] = "dup2",
325 /* 33 */ [ __NR_dup2 ] = "dup2",
326 /* 34 */ [ __NR_pause ] = "pause",
326 /* 34 */ [ __NR_pause ] = "pause",
327 /* 35 */ [ __NR_nanosleep ] = "nanosleep",
327 /* 35 */ [ __NR_nanosleep ] = "nanosleep",
328 /* 36 */ [ __NR_getitimer ] = "getitimer",
328 /* 36 */ [ __NR_getitimer ] = "getitimer",
329 /* 37 */ [ __NR_alarm ] = "alarm",
329 /* 37 */ [ __NR_alarm ] = "alarm",
330 /* 38 */ [ __NR_setitimer ] = "setitimer",
330 /* 38 */ [ __NR_setitimer ] = "setitimer",
331 /* 39 */ [ __NR_getpid ] = "getpid",
331 /* 39 */ [ __NR_getpid ] = "getpid",
332 /* 40 */ [ __NR_sendfile ] = "sendfile",
332 /* 40 */ [ __NR_sendfile ] = "sendfile",
333 /* 41 */ [ __NR_socket ] = "socket",
333 /* 41 */ [ __NR_socket ] = "socket",
334 /* 42 */ [ __NR_connect ] = "connect",
334 /* 42 */ [ __NR_connect ] = "connect",
335 /* 43 */ [ __NR_accept ] = "accept",
335 /* 43 */ [ __NR_accept ] = "accept",
336 /* 44 */ [ __NR_sendto ] = "sendto",
336 /* 44 */ [ __NR_sendto ] = "sendto",
337 /* 45 */ [ __NR_recvfrom ] = "recvfrom",
337 /* 45 */ [ __NR_recvfrom ] = "recvfrom",
338 /* 46 */ [ __NR_sendmsg ] = "sendmsg",
338 /* 46 */ [ __NR_sendmsg ] = "sendmsg",
339 /* 47 */ [ __NR_recvmsg ] = "recvmsg",
339 /* 47 */ [ __NR_recvmsg ] = "recvmsg",
340 /* 48 */ [ __NR_shutdown ] = "shutdown",
340 /* 48 */ [ __NR_shutdown ] = "shutdown",
341 /* 49 */ [ __NR_bind ] = "bind",
341 /* 49 */ [ __NR_bind ] = "bind",
342 /* 50 */ [ __NR_listen ] = "listen",
342 /* 50 */ [ __NR_listen ] = "listen",
343 /* 51 */ [ __NR_getsockname ] = "getsockname",
343 /* 51 */ [ __NR_getsockname ] = "getsockname",
344 /* 52 */ [ __NR_getpeername ] = "getpeername",
344 /* 52 */ [ __NR_getpeername ] = "getpeername",
345 /* 53 */ [ __NR_socketpair ] = "socketpair",
345 /* 53 */ [ __NR_socketpair ] = "socketpair",
346 /* 54 */ [ __NR_setsockopt ] = "setsockopt",
346 /* 54 */ [ __NR_setsockopt ] = "setsockopt",
347 /* 55 */ [ __NR_getsockopt ] = "getsockopt",
347 /* 55 */ [ __NR_getsockopt ] = "getsockopt",
348 /* 56 */ [ __NR_clone ] = "clone",
348 /* 56 */ [ __NR_clone ] = "clone",
349 /* 57 */ [ __NR_fork ] = "fork",
349 /* 57 */ [ __NR_fork ] = "fork",
350 /* 58 */ [ __NR_vfork ] = "vfork",
350 /* 58 */ [ __NR_vfork ] = "vfork",
351 /* 59 */ [ __NR_execve ] = "execve",
351 /* 59 */ [ __NR_execve ] = "execve",
352 /* 60 */ [ __NR_exit ] = "exit",
352 /* 60 */ [ __NR_exit ] = "exit",
353 /* 61 */ [ __NR_wait4 ] = "wait4",
353 /* 61 */ [ __NR_wait4 ] = "wait4",
354 /* 62 */ [ __NR_kill ] = "kill",
354 /* 62 */ [ __NR_kill ] = "kill",
355 /* 63 */ [ __NR_uname ] = "uname",
355 /* 63 */ [ __NR_uname ] = "uname",
356 /* 64 */ [ __NR_semget ] = "semget",
356 /* 64 */ [ __NR_semget ] = "semget",
357 /* 65 */ [ __NR_semop ] = "semop",
357 /* 65 */ [ __NR_semop ] = "semop",
358 /* 66 */ [ __NR_semctl ] = "semctl",
358 /* 66 */ [ __NR_semctl ] = "semctl",
359 /* 67 */ [ __NR_shmdt ] = "shmdt",
359 /* 67 */ [ __NR_shmdt ] = "shmdt",
360 /* 68 */ [ __NR_msgget ] = "msgget",
360 /* 68 */ [ __NR_msgget ] = "msgget",
361 /* 69 */ [ __NR_msgsnd ] = "msgsnd",
361 /* 69 */ [ __NR_msgsnd ] = "msgsnd",
362 /* 70 */ [ __NR_msgrcv ] = "msgrcv",
362 /* 70 */ [ __NR_msgrcv ] = "msgrcv",
363 /* 71 */ [ __NR_msgctl ] = "msgctl",
363 /* 71 */ [ __NR_msgctl ] = "msgctl",
364 /* 72 */ [ __NR_fcntl ] = "fcntl",
364 /* 72 */ [ __NR_fcntl ] = "fcntl",
365 /* 73 */ [ __NR_flock ] = "flock",
365 /* 73 */ [ __NR_flock ] = "flock",
366 /* 74 */ [ __NR_fsync ] = "fsync",
366 /* 74 */ [ __NR_fsync ] = "fsync",
367 /* 75 */ [ __NR_fdatasync ] = "fdatasync",
367 /* 75 */ [ __NR_fdatasync ] = "fdatasync",
368 /* 76 */ [ __NR_truncate ] = "truncate",
368 /* 76 */ [ __NR_truncate ] = "truncate",
369 /* 77 */ [ __NR_ftruncate ] = "ftruncate",
369 /* 77 */ [ __NR_ftruncate ] = "ftruncate",
370 /* 78 */ [ __NR_getdents ] = "getdents",
370 /* 78 */ [ __NR_getdents ] = "getdents",
371 /* 79 */ [ __NR_getcwd ] = "getcwd",
371 /* 79 */ [ __NR_getcwd ] = "getcwd",
372 /* 80 */ [ __NR_chdir ] = "chdir",
372 /* 80 */ [ __NR_chdir ] = "chdir",
373 /* 81 */ [ __NR_fchdir ] = "fchdir",
373 /* 81 */ [ __NR_fchdir ] = "fchdir",
374 /* 82 */ [ __NR_rename ] = "rename",
374 /* 82 */ [ __NR_rename ] = "rename",
375 /* 83 */ [ __NR_mkdir ] = "mkdir",
375 /* 83 */ [ __NR_mkdir ] = "mkdir",
376 /* 84 */ [ __NR_rmdir ] = "rmdir",
376 /* 84 */ [ __NR_rmdir ] = "rmdir",
377 /* 85 */ [ __NR_creat ] = "creat",
377 /* 85 */ [ __NR_creat ] = "creat",
378 /* 86 */ [ __NR_link ] = "link",
378 /* 86 */ [ __NR_link ] = "link",
379 /* 87 */ [ __NR_unlink ] = "unlink",
379 /* 87 */ [ __NR_unlink ] = "unlink",
380 /* 88 */ [ __NR_symlink ] = "symlink",
380 /* 88 */ [ __NR_symlink ] = "symlink",
381 /* 89 */ [ __NR_readlink ] = "readlink",
381 /* 89 */ [ __NR_readlink ] = "readlink",
382 /* 90 */ [ __NR_chmod ] = "chmod",
382 /* 90 */ [ __NR_chmod ] = "chmod",
383 /* 91 */ [ __NR_fchmod ] = "fchmod",
383 /* 91 */ [ __NR_fchmod ] = "fchmod",
384 /* 92 */ [ __NR_chown ] = "chown",
384 /* 92 */ [ __NR_chown ] = "chown",
385 /* 93 */ [ __NR_fchown ] = "fchown",
385 /* 93 */ [ __NR_fchown ] = "fchown",
386 /* 94 */ [ __NR_lchown ] = "lchown",
386 /* 94 */ [ __NR_lchown ] = "lchown",
387 /* 95 */ [ __NR_umask ] = "umask",
387 /* 95 */ [ __NR_umask ] = "umask",
388 /* 96 */ [ __NR_gettimeofday ] = "gettimeofday",
388 /* 96 */ [ __NR_gettimeofday ] = "gettimeofday",
389 /* 97 */ [ __NR_getrlimit ] = "getrlimit",
389 /* 97 */ [ __NR_getrlimit ] = "getrlimit",
390 /* 98 */ [ __NR_getrusage ] = "getrusage",
390 /* 98 */ [ __NR_getrusage ] = "getrusage",
391 /* 99 */ [ __NR_sysinfo ] = "sysinfo",
391 /* 99 */ [ __NR_sysinfo ] = "sysinfo",
392 /* 100 */ [ __NR_times ] = "times",
392 /* 100 */ [ __NR_times ] = "times",
393 /* 101 */ [ __NR_ptrace ] = "ptrace",
393 /* 101 */ [ __NR_ptrace ] = "ptrace",
394 /* 102 */ [ __NR_getuid ] = "getuid",
394 /* 102 */ [ __NR_getuid ] = "getuid",
395 /* 103 */ [ __NR_syslog ] = "syslog",
395 /* 103 */ [ __NR_syslog ] = "syslog",
396 /* 104 */ [ __NR_getgid ] = "getgid",
396 /* 104 */ [ __NR_getgid ] = "getgid",
397 /* 105 */ [ __NR_setuid ] = "setuid",
397 /* 105 */ [ __NR_setuid ] = "setuid",
398 /* 106 */ [ __NR_setgid ] = "setgid",
398 /* 106 */ [ __NR_setgid ] = "setgid",
399 /* 107 */ [ __NR_geteuid ] = "geteuid",
399 /* 107 */ [ __NR_geteuid ] = "geteuid",
400 /* 108 */ [ __NR_getegid ] = "getegid",
400 /* 108 */ [ __NR_getegid ] = "getegid",
401 /* 109 */ [ __NR_setpgid ] = "setpgid",
401 /* 109 */ [ __NR_setpgid ] = "setpgid",
402 /* 110 */ [ __NR_getppid ] = "getppid",
402 /* 110 */ [ __NR_getppid ] = "getppid",
403 /* 111 */ [ __NR_getpgrp ] = "getpgrp",
403 /* 111 */ [ __NR_getpgrp ] = "getpgrp",
404 /* 112 */ [ __NR_setsid ] = "setsid",
404 /* 112 */ [ __NR_setsid ] = "setsid",
405 /* 113 */ [ __NR_setreuid ] = "setreuid",
405 /* 113 */ [ __NR_setreuid ] = "setreuid",
406 /* 114 */ [ __NR_setregid ] = "setregid",
406 /* 114 */ [ __NR_setregid ] = "setregid",
407 /* 115 */ [ __NR_getgroups ] = "getgroups",
407 /* 115 */ [ __NR_getgroups ] = "getgroups",
408 /* 116 */ [ __NR_setgroups ] = "setgroups",
408 /* 116 */ [ __NR_setgroups ] = "setgroups",
409 /* 117 */ [ __NR_setresuid ] = "setresuid",
409 /* 117 */ [ __NR_setresuid ] = "setresuid",
410 /* 118 */ [ __NR_getresuid ] = "getresuid",
410 /* 118 */ [ __NR_getresuid ] = "getresuid",
411 /* 119 */ [ __NR_setresgid ] = "setresgid",
411 /* 119 */ [ __NR_setresgid ] = "setresgid",
412 /* 120 */ [ __NR_getresgid ] = "getresgid",
412 /* 120 */ [ __NR_getresgid ] = "getresgid",
413 /* 121 */ [ __NR_getpgid ] = "getpgid",
413 /* 121 */ [ __NR_getpgid ] = "getpgid",
414 /* 122 */ [ __NR_setfsuid ] = "setfsuid",
414 /* 122 */ [ __NR_setfsuid ] = "setfsuid",
415 /* 123 */ [ __NR_setfsgid ] = "setfsgid",
415 /* 123 */ [ __NR_setfsgid ] = "setfsgid",
416 /* 124 */ [ __NR_getsid ] = "getsid",
416 /* 124 */ [ __NR_getsid ] = "getsid",
417 /* 125 */ [ __NR_capget ] = "capget",
417 /* 125 */ [ __NR_capget ] = "capget",
418 /* 126 */ [ __NR_capset ] = "capset",
418 /* 126 */ [ __NR_capset ] = "capset",
419 /* 127 */ [ __NR_rt_sigpending ] = "rt_sigpending",
419 /* 127 */ [ __NR_rt_sigpending ] = "rt_sigpending",
420 /* 128 */ [ __NR_rt_sigtimedwait ] = "rt_sigtimedwait",
420 /* 128 */ [ __NR_rt_sigtimedwait ] = "rt_sigtimedwait",
421 /* 129 */ [ __NR_rt_sigqueueinfo ] = "rt_sigqueueinfo",
421 /* 129 */ [ __NR_rt_sigqueueinfo ] = "rt_sigqueueinfo",
422 /* 130 */ [ __NR_rt_sigsuspend ] = "rt_sigsuspend",
422 /* 130 */ [ __NR_rt_sigsuspend ] = "rt_sigsuspend",
423 /* 131 */ [ __NR_sigaltstack ] = "sigaltstack",
423 /* 131 */ [ __NR_sigaltstack ] = "sigaltstack",
424 /* 132 */ [ __NR_utime ] = "utime",
424 /* 132 */ [ __NR_utime ] = "utime",
425 /* 133 */ [ __NR_mknod ] = "mknod",
425 /* 133 */ [ __NR_mknod ] = "mknod",
426 /* 134 */ [ __NR_uselib ] = "uselib",
426 /* 134 */ [ __NR_uselib ] = "uselib",
427 /* 135 */ [ __NR_personality ] = "personality",
427 /* 135 */ [ __NR_personality ] = "personality",
428 /* 136 */ [ __NR_ustat ] = "ustat",
428 /* 136 */ [ __NR_ustat ] = "ustat",
429 /* 137 */ [ __NR_statfs ] = "statfs",
429 /* 137 */ [ __NR_statfs ] = "statfs",
430 /* 138 */ [ __NR_fstatfs ] = "fstatfs",
430 /* 138 */ [ __NR_fstatfs ] = "fstatfs",
431 /* 139 */ [ __NR_sysfs ] = "sysfs",
431 /* 139 */ [ __NR_sysfs ] = "sysfs",
432 /* 140 */ [ __NR_getpriority ] = "getpriority",
432 /* 140 */ [ __NR_getpriority ] = "getpriority",
433 /* 141 */ [ __NR_setpriority ] = "setpriority",
433 /* 141 */ [ __NR_setpriority ] = "setpriority",
434 /* 142 */ [ __NR_sched_setparam ] = "sched_setparam",
434 /* 142 */ [ __NR_sched_setparam ] = "sched_setparam",
435 /* 143 */ [ __NR_sched_getparam ] = "sched_getparam",
435 /* 143 */ [ __NR_sched_getparam ] = "sched_getparam",
436 /* 144 */ [ __NR_sched_setscheduler ] = "sched_setscheduler",
436 /* 144 */ [ __NR_sched_setscheduler ] = "sched_setscheduler",
437 /* 145 */ [ __NR_sched_getscheduler ] = "sched_getscheduler",
437 /* 145 */ [ __NR_sched_getscheduler ] = "sched_getscheduler",
438 /* 146 */ [ __NR_sched_get_priority_max ] = "sched_get_priority_max",
438 /* 146 */ [ __NR_sched_get_priority_max ] = "sched_get_priority_max",
439 /* 147 */ [ __NR_sched_get_priority_min ] = "sched_get_priority_min",
439 /* 147 */ [ __NR_sched_get_priority_min ] = "sched_get_priority_min",
440 /* 148 */ [ __NR_sched_rr_get_interval ] = "sched_rr_get_interval",
440 /* 148 */ [ __NR_sched_rr_get_interval ] = "sched_rr_get_interval",
441 /* 149 */ [ __NR_mlock ] = "mlock",
441 /* 149 */ [ __NR_mlock ] = "mlock",
442 /* 150 */ [ __NR_munlock ] = "munlock",
442 /* 150 */ [ __NR_munlock ] = "munlock",
443 /* 151 */ [ __NR_mlockall ] = "mlockall",
443 /* 151 */ [ __NR_mlockall ] = "mlockall",
444 /* 152 */ [ __NR_munlockall ] = "munlockall",
444 /* 152 */ [ __NR_munlockall ] = "munlockall",
445 /* 153 */ [ __NR_vhangup ] = "vhangup",
445 /* 153 */ [ __NR_vhangup ] = "vhangup",
446 /* 154 */ [ __NR_modify_ldt ] = "modify_ldt",
446 /* 154 */ [ __NR_modify_ldt ] = "modify_ldt",
447 /* 155 */ [ __NR_pivot_root ] = "pivot_root",
447 /* 155 */ [ __NR_pivot_root ] = "pivot_root",
448 /* 156 */ [ __NR__sysctl ] = "_sysctl",
448 /* 156 */ [ __NR__sysctl ] = "_sysctl",
449 /* 157 */ [ __NR_prctl ] = "prctl",
449 /* 157 */ [ __NR_prctl ] = "prctl",
450 /* 158 */ [ __NR_arch_prctl ] = "arch_prctl",
450 /* 158 */ [ __NR_arch_prctl ] = "arch_prctl",
451 /* 159 */ [ __NR_adjtimex ] = "adjtimex",
451 /* 159 */ [ __NR_adjtimex ] = "adjtimex",
452 /* 160 */ [ __NR_setrlimit ] = "setrlimit",
452 /* 160 */ [ __NR_setrlimit ] = "setrlimit",
453 /* 161 */ [ __NR_chroot ] = "chroot",
453 /* 161 */ [ __NR_chroot ] = "chroot",
454 /* 162 */ [ __NR_sync ] = "sync",
454 /* 162 */ [ __NR_sync ] = "sync",
455 /* 163 */ [ __NR_acct ] = "acct",
455 /* 163 */ [ __NR_acct ] = "acct",
456 /* 164 */ [ __NR_settimeofday ] = "settimeofday",
456 /* 164 */ [ __NR_settimeofday ] = "settimeofday",
457 /* 165 */ [ __NR_mount ] = "mount",
457 /* 165 */ [ __NR_mount ] = "mount",
458 /* 166 */ [ __NR_umount2 ] = "umount2",
458 /* 166 */ [ __NR_umount2 ] = "umount2",
459 /* 167 */ [ __NR_swapon ] = "swapon",
459 /* 167 */ [ __NR_swapon ] = "swapon",
460 /* 168 */ [ __NR_swapoff ] = "swapoff",
460 /* 168 */ [ __NR_swapoff ] = "swapoff",
461 /* 169 */ [ __NR_reboot ] = "reboot",
461 /* 169 */ [ __NR_reboot ] = "reboot",
462 /* 170 */ [ __NR_sethostname ] = "sethostname",
462 /* 170 */ [ __NR_sethostname ] = "sethostname",
463 /* 171 */ [ __NR_setdomainname ] = "setdomainname",
463 /* 171 */ [ __NR_setdomainname ] = "setdomainname",
464 /* 172 */ [ __NR_iopl ] = "iopl",
464 /* 172 */ [ __NR_iopl ] = "iopl",
465 /* 173 */ [ __NR_ioperm ] = "ioperm",
465 /* 173 */ [ __NR_ioperm ] = "ioperm",
466 /* 174 */ [ __NR_create_module ] = "create_module",
466 /* 174 */ [ __NR_create_module ] = "create_module",
467 /* 175 */ [ __NR_init_module ] = "init_module",
467 /* 175 */ [ __NR_init_module ] = "init_module",
468 /* 176 */ [ __NR_delete_module ] = "delete_module",
468 /* 176 */ [ __NR_delete_module ] = "delete_module",
469 /* 177 */ [ __NR_get_kernel_syms ] = "get_kernel_syms",
469 /* 177 */ [ __NR_get_kernel_syms ] = "get_kernel_syms",
470 /* 178 */ [ __NR_query_module ] = "query_module",
470 /* 178 */ [ __NR_query_module ] = "query_module",
471 /* 179 */ [ __NR_quotactl ] = "quotactl",
471 /* 179 */ [ __NR_quotactl ] = "quotactl",
472 /* 180 */ [ __NR_nfsservctl ] = "nfsservctl",
472 /* 180 */ [ __NR_nfsservctl ] = "nfsservctl",
473 /* 181 */ [ __NR_getpmsg ] = "getpmsg",
473 /* 181 */ [ __NR_getpmsg ] = "getpmsg",
474 /* 182 */ [ __NR_putpmsg ] = "putpmsg",
474 /* 182 */ [ __NR_putpmsg ] = "putpmsg",
475 /* 183 */ [ __NR_afs_syscall ] = "afs_syscall",
475 /* 183 */ [ __NR_afs_syscall ] = "afs_syscall",
476 /* 184 */ [ __NR_tuxcall ] = "tuxcall",
476 /* 184 */ [ __NR_tuxcall ] = "tuxcall",
477 /* 185 */ [ __NR_security ] = "security",
477 /* 185 */ [ __NR_security ] = "security",
478 /* 186 */ [ __NR_gettid ] = "gettid",
478 /* 186 */ [ __NR_gettid ] = "gettid",
479 /* 187 */ [ __NR_readahead ] = "readahead",
479 /* 187 */ [ __NR_readahead ] = "readahead",
480 /* 188 */ [ __NR_setxattr ] = "setxattr",
480 /* 188 */ [ __NR_setxattr ] = "setxattr",
481 /* 189 */ [ __NR_lsetxattr ] = "lsetxattr",
481 /* 189 */ [ __NR_lsetxattr ] = "lsetxattr",
482 /* 190 */ [ __NR_fsetxattr ] = "fsetxattr",
482 /* 190 */ [ __NR_fsetxattr ] = "fsetxattr",
483 /* 191 */ [ __NR_getxattr ] = "getxattr",
483 /* 191 */ [ __NR_getxattr ] = "getxattr",
484 /* 192 */ [ __NR_lgetxattr ] = "lgetxattr",
484 /* 192 */ [ __NR_lgetxattr ] = "lgetxattr",
485 /* 193 */ [ __NR_fgetxattr ] = "fgetxattr",
485 /* 193 */ [ __NR_fgetxattr ] = "fgetxattr",
486 /* 194 */ [ __NR_listxattr ] = "listxattr",
486 /* 194 */ [ __NR_listxattr ] = "listxattr",
487 /* 195 */ [ __NR_llistxattr ] = "llistxattr",
487 /* 195 */ [ __NR_llistxattr ] = "llistxattr",
488 /* 196 */ [ __NR_flistxattr ] = "flistxattr",
488 /* 196 */ [ __NR_flistxattr ] = "flistxattr",
489 /* 197 */ [ __NR_removexattr ] = "removexattr",
489 /* 197 */ [ __NR_removexattr ] = "removexattr",
490 /* 198 */ [ __NR_lremovexattr ] = "lremovexattr",
490 /* 198 */ [ __NR_lremovexattr ] = "lremovexattr",
491 /* 199 */ [ __NR_fremovexattr ] = "fremovexattr",
491 /* 199 */ [ __NR_fremovexattr ] = "fremovexattr",
492 /* 200 */ [ __NR_tkill ] = "tkill",
492 /* 200 */ [ __NR_tkill ] = "tkill",
493 /* 201 */ [ __NR_time ] = "time",
493 /* 201 */ [ __NR_time ] = "time",
494 /* 202 */ [ __NR_futex ] = "futex",
494 /* 202 */ [ __NR_futex ] = "futex",
495 /* 203 */ [ __NR_sched_setaffinity ] = "sched_setaffinity",
495 /* 203 */ [ __NR_sched_setaffinity ] = "sched_setaffinity",
496 /* 204 */ [ __NR_sched_getaffinity ] = "sched_getaffinity",
496 /* 204 */ [ __NR_sched_getaffinity ] = "sched_getaffinity",
497 /* 205 */ [ __NR_set_thread_area ] = "set_thread_area",
497 /* 205 */ [ __NR_set_thread_area ] = "set_thread_area",
498 /* 206 */ [ __NR_io_setup ] = "io_setup",
498 /* 206 */ [ __NR_io_setup ] = "io_setup",
499 /* 207 */ [ __NR_io_destroy ] = "io_destroy",
499 /* 207 */ [ __NR_io_destroy ] = "io_destroy",
500 /* 208 */ [ __NR_io_getevents ] = "io_getevents",
500 /* 208 */ [ __NR_io_getevents ] = "io_getevents",
501 /* 209 */ [ __NR_io_submit ] = "io_submit",
501 /* 209 */ [ __NR_io_submit ] = "io_submit",
502 /* 210 */ [ __NR_io_cancel ] = "io_cancel",
502 /* 210 */ [ __NR_io_cancel ] = "io_cancel",
503 /* 211 */ [ __NR_get_thread_area ] = "get_thread_area",
503 /* 211 */ [ __NR_get_thread_area ] = "get_thread_area",
504 /* 212 */ [ __NR_lookup_dcookie ] = "lookup_dcookie",
504 /* 212 */ [ __NR_lookup_dcookie ] = "lookup_dcookie",
505 /* 213 */ [ __NR_epoll_create ] = "epoll_create",
505 /* 213 */ [ __NR_epoll_create ] = "epoll_create",
506 /* 214 */ [ __NR_epoll_ctl_old ] = "epoll_ctl_old",
506 /* 214 */ [ __NR_epoll_ctl_old ] = "epoll_ctl_old",
507 /* 215 */ [ __NR_epoll_wait_old ] = "epoll_wait_old",
507 /* 215 */ [ __NR_epoll_wait_old ] = "epoll_wait_old",
508 /* 216 */ [ __NR_remap_file_pages ] = "remap_file_pages",
508 /* 216 */ [ __NR_remap_file_pages ] = "remap_file_pages",
509 /* 217 */ [ __NR_getdents64 ] = "getdents64",
509 /* 217 */ [ __NR_getdents64 ] = "getdents64",
510 /* 218 */ [ __NR_set_tid_address ] = "set_tid_address",
510 /* 218 */ [ __NR_set_tid_address ] = "set_tid_address",
511 /* 219 */ [ __NR_restart_syscall ] = "restart_syscall",
511 /* 219 */ [ __NR_restart_syscall ] = "restart_syscall",
512 /* 220 */ [ __NR_semtimedop ] = "semtimedop",
512 /* 220 */ [ __NR_semtimedop ] = "semtimedop",
513 /* 221 */ [ __NR_fadvise64 ] = "fadvise64",
513 /* 221 */ [ __NR_fadvise64 ] = "fadvise64",
514 /* 222 */ [ __NR_timer_create ] = "timer_create",
514 /* 222 */ [ __NR_timer_create ] = "timer_create",
515 /* 223 */ [ __NR_timer_settime ] = "timer_settime",
515 /* 223 */ [ __NR_timer_settime ] = "timer_settime",
516 /* 224 */ [ __NR_timer_gettime ] = "timer_gettime",
516 /* 224 */ [ __NR_timer_gettime ] = "timer_gettime",
517 /* 225 */ [ __NR_timer_getoverrun ] = "timer_getoverrun",
517 /* 225 */ [ __NR_timer_getoverrun ] = "timer_getoverrun",
518 /* 226 */ [ __NR_timer_delete ] = "timer_delete",
518 /* 226 */ [ __NR_timer_delete ] = "timer_delete",
519 /* 227 */ [ __NR_clock_settime ] = "clock_settime",
519 /* 227 */ [ __NR_clock_settime ] = "clock_settime",
520 /* 228 */ [ __NR_clock_gettime ] = "clock_gettime",
520 /* 228 */ [ __NR_clock_gettime ] = "clock_gettime",
521 /* 229 */ [ __NR_clock_getres ] = "clock_getres",
521 /* 229 */ [ __NR_clock_getres ] = "clock_getres",
522 /* 230 */ [ __NR_clock_nanosleep ] = "clock_nanosleep",
522 /* 230 */ [ __NR_clock_nanosleep ] = "clock_nanosleep",
523 /* 231 */ [ __NR_exit_group ] = "exit_group",
523 /* 231 */ [ __NR_exit_group ] = "exit_group",
524 /* 232 */ [ __NR_epoll_wait ] = "epoll_wait",
524 /* 232 */ [ __NR_epoll_wait ] = "epoll_wait",
525 /* 233 */ [ __NR_epoll_ctl ] = "epoll_ctl",
525 /* 233 */ [ __NR_epoll_ctl ] = "epoll_ctl",
526 /* 234 */ [ __NR_tgkill ] = "tgkill",
526 /* 234 */ [ __NR_tgkill ] = "tgkill",
527 /* 235 */ [ __NR_utimes ] = "utimes",
527 /* 235 */ [ __NR_utimes ] = "utimes",
528 /* 236 */ [ __NR_vserver ] = "vserver",
528 /* 236 */ [ __NR_vserver ] = "vserver",
529 /* 237 */ [ __NR_mbind ] = "mbind",
529 /* 237 */ [ __NR_mbind ] = "mbind",
530 /* 238 */ [ __NR_set_mempolicy ] = "set_mempolicy",
530 /* 238 */ [ __NR_set_mempolicy ] = "set_mempolicy",
531 /* 239 */ [ __NR_get_mempolicy ] = "get_mempolicy",
531 /* 239 */ [ __NR_get_mempolicy ] = "get_mempolicy",
532 /* 240 */ [ __NR_mq_open ] = "mq_open",
532 /* 240 */ [ __NR_mq_open ] = "mq_open",
533 /* 241 */ [ __NR_mq_unlink ] = "mq_unlink",
533 /* 241 */ [ __NR_mq_unlink ] = "mq_unlink",
534 /* 242 */ [ __NR_mq_timedsend ] = "mq_timedsend",
534 /* 242 */ [ __NR_mq_timedsend ] = "mq_timedsend",
535 /* 243 */ [ __NR_mq_timedreceive ] = "mq_timedreceive",
535 /* 243 */ [ __NR_mq_timedreceive ] = "mq_timedreceive",
536 /* 244 */ [ __NR_mq_notify ] = "mq_notify",
536 /* 244 */ [ __NR_mq_notify ] = "mq_notify",
537 /* 245 */ [ __NR_mq_getsetattr ] = "mq_getsetattr",
537 /* 245 */ [ __NR_mq_getsetattr ] = "mq_getsetattr",
538 /* 246 */ [ __NR_kexec_load ] = "kexec_load",
538 /* 246 */ [ __NR_kexec_load ] = "kexec_load",
539 /* 247 */ [ __NR_waitid ] = "waitid",
539 /* 247 */ [ __NR_waitid ] = "waitid",
540 /* 248 */ [ __NR_add_key ] = "add_key",
540 /* 248 */ [ __NR_add_key ] = "add_key",
541 /* 249 */ [ __NR_request_key ] = "request_key",
541 /* 249 */ [ __NR_request_key ] = "request_key",
542 /* 250 */ [ __NR_keyctl ] = "keyctl",
542 /* 250 */ [ __NR_keyctl ] = "keyctl",
543 /* 251 */ [ __NR_ioprio_set ] = "ioprio_set",
543 /* 251 */ [ __NR_ioprio_set ] = "ioprio_set",
544 /* 252 */ [ __NR_ioprio_get ] = "ioprio_get",
544 /* 252 */ [ __NR_ioprio_get ] = "ioprio_get",
545 /* 253 */ [ __NR_inotify_init ] = "inotify_init",
545 /* 253 */ [ __NR_inotify_init ] = "inotify_init",
546 /* 254 */ [ __NR_inotify_add_watch ] = "inotify_add_watch",
546 /* 254 */ [ __NR_inotify_add_watch ] = "inotify_add_watch",
547 /* 255 */ [ __NR_inotify_rm_watch ] = "inotify_rm_watch",
547 /* 255 */ [ __NR_inotify_rm_watch ] = "inotify_rm_watch",
548 /* 256 */ [ __NR_migrate_pages ] = "migrate_pages",
548 /* 256 */ [ __NR_migrate_pages ] = "migrate_pages",
549 /* 257 */ [ __NR_openat ] = "openat",
549 /* 257 */ [ __NR_openat ] = "openat",
550 /* 258 */ [ __NR_mkdirat ] = "mkdirat",
550 /* 258 */ [ __NR_mkdirat ] = "mkdirat",
551 /* 259 */ [ __NR_mknodat ] = "mknodat",
551 /* 259 */ [ __NR_mknodat ] = "mknodat",
552 /* 260 */ [ __NR_fchownat ] = "fchownat",
552 /* 260 */ [ __NR_fchownat ] = "fchownat",
553 /* 261 */ [ __NR_futimesat ] = "futimesat",
553 /* 261 */ [ __NR_futimesat ] = "futimesat",
554 /* 262 */ [ __NR_newfstatat ] = "newfstatat",
554 /* 262 */ [ __NR_newfstatat ] = "newfstatat",
555 /* 263 */ [ __NR_unlinkat ] = "unlinkat",
555 /* 263 */ [ __NR_unlinkat ] = "unlinkat",
556 /* 264 */ [ __NR_renameat ] = "renameat",
556 /* 264 */ [ __NR_renameat ] = "renameat",
557 /* 265 */ [ __NR_linkat ] = "linkat",
557 /* 265 */ [ __NR_linkat ] = "linkat",
558 /* 266 */ [ __NR_symlinkat ] = "symlinkat",
558 /* 266 */ [ __NR_symlinkat ] = "symlinkat",
559 /* 267 */ [ __NR_readlinkat ] = "readlinkat",
559 /* 267 */ [ __NR_readlinkat ] = "readlinkat",
560 /* 268 */ [ __NR_fchmodat ] = "fchmodat",
560 /* 268 */ [ __NR_fchmodat ] = "fchmodat",
561 /* 269 */ [ __NR_faccessat ] = "faccessat",
561 /* 269 */ [ __NR_faccessat ] = "faccessat",
562 /* 270 */ [ __NR_pselect6 ] = "pselect6",
562 /* 270 */ [ __NR_pselect6 ] = "pselect6",
563 /* 271 */ [ __NR_ppoll ] = "ppoll",
563 /* 271 */ [ __NR_ppoll ] = "ppoll",
564 /* 272 */ [ __NR_unshare ] = "unshare",
564 /* 272 */ [ __NR_unshare ] = "unshare",
565 /* 273 */ [ __NR_set_robust_list ] = "set_robust_list",
565 /* 273 */ [ __NR_set_robust_list ] = "set_robust_list",
566 /* 274 */ [ __NR_get_robust_list ] = "get_robust_list",
566 /* 274 */ [ __NR_get_robust_list ] = "get_robust_list",
567 /* 275 */ [ __NR_splice ] = "splice",
567 /* 275 */ [ __NR_splice ] = "splice",
568 /* 276 */ [ __NR_tee ] = "tee",
568 /* 276 */ [ __NR_tee ] = "tee",
569 /* 277 */ [ __NR_sync_file_range ] = "sync_file_range",
569 /* 277 */ [ __NR_sync_file_range ] = "sync_file_range",
570 /* 278 */ [ __NR_vmsplice ] = "vmsplice",
570 /* 278 */ [ __NR_vmsplice ] = "vmsplice",
571 /* 279 */ [ __NR_move_pages ] = "move_pages",
571 /* 279 */ [ __NR_move_pages ] = "move_pages",
572 /* 280 */ [ __NR_utimensat ] = "utimensat",
572 /* 280 */ [ __NR_utimensat ] = "utimensat",
573 /* 281 */ [ __NR_epoll_pwait ] = "epoll_pwait",
573 /* 281 */ [ __NR_epoll_pwait ] = "epoll_pwait",
574 /* 282 */ [ __NR_signalfd ] = "signalfd",
574 /* 282 */ [ __NR_signalfd ] = "signalfd",
575 /* 283 */ [ __NR_timerfd_create ] = "timerfd_create",
575 /* 283 */ [ __NR_timerfd_create ] = "timerfd_create",
576 /* 284 */ [ __NR_eventfd ] = "eventfd",
576 /* 284 */ [ __NR_eventfd ] = "eventfd",
577 /* 285 */ [ __NR_fallocate ] = "fallocate",
577 /* 285 */ [ __NR_fallocate ] = "fallocate",
578 /* 286 */ [ __NR_timerfd_settime ] = "timerfd_settime",
578 /* 286 */ [ __NR_timerfd_settime ] = "timerfd_settime",
579 /* 287 */ [ __NR_timerfd_gettime ] = "timerfd_gettime",
579 /* 287 */ [ __NR_timerfd_gettime ] = "timerfd_gettime",
580 /* 288 */ [ __NR_accept4 ] = "accept4",
580 /* 288 */ [ __NR_accept4 ] = "accept4",
581 /* 289 */ [ __NR_signalfd4 ] = "signalfd4",
581 /* 289 */ [ __NR_signalfd4 ] = "signalfd4",
582 /* 290 */ [ __NR_eventfd2 ] = "eventfd2",
582 /* 290 */ [ __NR_eventfd2 ] = "eventfd2",
583 /* 291 */ [ __NR_epoll_create1 ] = "epoll_create1",
583 /* 291 */ [ __NR_epoll_create1 ] = "epoll_create1",
584 /* 292 */ [ __NR_dup3 ] = "dup3",
584 /* 292 */ [ __NR_dup3 ] = "dup3",
585 /* 293 */ [ __NR_pipe2 ] = "pipe2",
585 /* 293 */ [ __NR_pipe2 ] = "pipe2",
586 /* 294 */ [ __NR_inotify_init1 ] = "inotify_init1",
586 /* 294 */ [ __NR_inotify_init1 ] = "inotify_init1",
587 /* 295 */ [ __NR_preadv ] = "preadv",
587 /* 295 */ [ __NR_preadv ] = "preadv",
588 /* 296 */ [ __NR_pwritev ] = "pwritev",
588 /* 296 */ [ __NR_pwritev ] = "pwritev",
589 /* 297 */ [ __NR_rt_tgsigqueueinfo ] = "rt_tgsigqueueinfo",
589 /* 297 */ [ __NR_rt_tgsigqueueinfo ] = "rt_tgsigqueueinfo",
590 /* 298 */ [ __NR_perf_event_open ] = "perf_event_open",
590 /* 298 */ [ __NR_perf_event_open ] = "perf_event_open",
591 /* 299 */ [ __NR_recvmmsg ] = "recvmmsg",
591 /* 299 */ [ __NR_recvmmsg ] = "recvmmsg",
592 /* 300 */ [ __NR_fanotify_init ] = "fanotify_init",
592 /* 300 */ [ __NR_fanotify_init ] = "fanotify_init",
593 /* 301 */ [ __NR_fanotify_mark ] = "fanotify_mark",
593 /* 301 */ [ __NR_fanotify_mark ] = "fanotify_mark",
594 /* 302 */ [ __NR_prlimit64 ] = "prlimit64",
594 /* 302 */ [ __NR_prlimit64 ] = "prlimit64",
595 /* 303 */ [ __NR_name_to_handle_at ] = "name_to_handle_at",
595 /* 303 */ [ __NR_name_to_handle_at ] = "name_to_handle_at",
596 /* 304 */ [ __NR_open_by_handle_at ] = "open_by_handle_at",
596 /* 304 */ [ __NR_open_by_handle_at ] = "open_by_handle_at",
597 /* 305 */ [ __NR_clock_adjtime ] = "clock_adjtime",
597 /* 305 */ [ __NR_clock_adjtime ] = "clock_adjtime",
598 /* 306 */ [ __NR_syncfs ] = "syncfs",
598 /* 306 */ [ __NR_syncfs ] = "syncfs",
599 /* 307 */ [ __NR_sendmmsg ] = "sendmmsg",
599 /* 307 */ [ __NR_sendmmsg ] = "sendmmsg",
600 /* 308 */ [ __NR_setns ] = "setns",
600 /* 308 */ [ __NR_setns ] = "setns",
601 /* 309 */ [ __NR_getcpu ] = "getcpu",
601 /* 309 */ [ __NR_getcpu ] = "getcpu",
602 /* 310 */ [ __NR_process_vm_readv ] = "process_vm_readv",
602 /* 310 */ [ __NR_process_vm_readv ] = "process_vm_readv",
603 /* 311 */ [ __NR_process_vm_writev ] = "process_vm_writev",
603 /* 311 */ [ __NR_process_vm_writev ] = "process_vm_writev",
604 /* 312 */ [ __NR_kcmp ] = "kcmp",
604 /* 312 */ [ __NR_kcmp ] = "kcmp",
605 /* 313 */ [ __NR_finit_module ] = "finit_module",
605 /* 313 */ [ __NR_finit_module ] = "finit_module",
606 + /* 314 */ [ __NR_sched_setattr ] = "sched_setattr",
607 + /* 315 */ [ __NR_sched_getattr ] = "sched_getattr",
608 + /* 316 */ [ __NR_renameat2 ] = "renameat2",
609 + /* 317 */ [ __NR_seccomp ] = "seccomp",
610 + /* 318 */ [ __NR_getrandom ] = "getrandom",
611 + /* 319 */ [ __NR_memfd_create ] = "memfd_create",
612 + /* 320 */ [ __NR_kexec_file_load ] = "kexec_file_load",
613 + /* 321 */ [ __NR_bpf ] = "bpf",
614 + /* 322 */ [ __NR_execveat ] = "execveat",
615 + /* 323 */ [ __NR_userfaultfd ] = "userfaultfd",
616 + /* 324 */ [ __NR_membarrier ] = "membarrier",
617 + /* 325 */ [ __NR_mlock2 ] = "mlock2",
606 };
618 };
607 #define NUM_SYSCALLS ARRAY_SIZE(syscall_names)
619 #define NUM_SYSCALLS ARRAY_SIZE(syscall_names)
608 #define NUM_ACTIONS (NUM_SYSCALLS+64)
620 #define NUM_ACTIONS (NUM_SYSCALLS+64)
609
621
610 enum action {
622 enum action {
611 A_DEFAULT, // Use the default action
623 A_DEFAULT, // Use the default action
612 A_NO, // Always forbid
624 A_NO, // Always forbid
613 A_YES, // Always permit
625 A_YES, // Always permit
614 A_FILENAME, // Permit if arg1 is a known filename
626 A_FILENAME, // Permit if arg1 is a known filename
615 A_ACTION_MASK = 15,
627 A_ACTION_MASK = 15,
616 A_NO_RETVAL = 32, // Does not return a value
628 A_NO_RETVAL = 32, // Does not return a value
617 A_SAMPLE_MEM = 64, // Sample memory usage before the syscall
629 A_SAMPLE_MEM = 64, // Sample memory usage before the syscall
618 A_LIBERAL = 128, // Valid only in liberal mode
630 A_LIBERAL = 128, // Valid only in liberal mode
619 // Must fit in a unsigned char
631 // Must fit in a unsigned char
620 };
632 };
621
633
622 static unsigned char syscall_action[NUM_ACTIONS] = {
634 static unsigned char syscall_action[NUM_ACTIONS] = {
623 #define S(x) [__NR_##x]
635 #define S(x) [__NR_##x]
624
636
625 // Syscalls permitted for specific file names
637 // Syscalls permitted for specific file names
626 S(open) = A_FILENAME,
638 S(open) = A_FILENAME,
627 S(creat) = A_FILENAME,
639 S(creat) = A_FILENAME,
628 S(unlink) = A_FILENAME,
640 S(unlink) = A_FILENAME,
629 S(access) = A_FILENAME,
641 S(access) = A_FILENAME,
630 S(truncate) = A_FILENAME,
642 S(truncate) = A_FILENAME,
631 S(stat) = A_FILENAME,
643 S(stat) = A_FILENAME,
632 S(lstat) = A_FILENAME,
644 S(lstat) = A_FILENAME,
633 S(readlink) = A_FILENAME,
645 S(readlink) = A_FILENAME,
634 #ifndef CONFIG_BOX_USER_AMD64
646 #ifndef CONFIG_BOX_USER_AMD64
635 S(oldstat) = A_FILENAME,
647 S(oldstat) = A_FILENAME,
636 S(oldlstat) = A_FILENAME,
648 S(oldlstat) = A_FILENAME,
637 S(truncate64) = A_FILENAME,
649 S(truncate64) = A_FILENAME,
638 S(stat64) = A_FILENAME,
650 S(stat64) = A_FILENAME,
639 S(lstat64) = A_FILENAME,
651 S(lstat64) = A_FILENAME,
640 #endif
652 #endif
641
653
642 // Syscalls permitted always
654 // Syscalls permitted always
643 S(exit) = A_YES | A_SAMPLE_MEM,
655 S(exit) = A_YES | A_SAMPLE_MEM,
644 S(read) = A_YES,
656 S(read) = A_YES,
645 S(write) = A_YES,
657 S(write) = A_YES,
646 S(close) = A_YES,
658 S(close) = A_YES,
647 S(lseek) = A_YES,
659 S(lseek) = A_YES,
648 S(getpid) = A_YES,
660 S(getpid) = A_YES,
649 S(getuid) = A_YES,
661 S(getuid) = A_YES,
650 S(dup) = A_YES,
662 S(dup) = A_YES,
651 S(brk) = A_YES,
663 S(brk) = A_YES,
652 S(getgid) = A_YES,
664 S(getgid) = A_YES,
653 S(geteuid) = A_YES,
665 S(geteuid) = A_YES,
654 S(getegid) = A_YES,
666 S(getegid) = A_YES,
655 S(dup2) = A_YES,
667 S(dup2) = A_YES,
656 S(ftruncate) = A_YES,
668 S(ftruncate) = A_YES,
657 S(fstat) = A_YES,
669 S(fstat) = A_YES,
658 S(personality) = A_YES,
670 S(personality) = A_YES,
659 S(readv) = A_YES,
671 S(readv) = A_YES,
660 S(writev) = A_YES,
672 S(writev) = A_YES,
661 S(getresuid) = A_YES,
673 S(getresuid) = A_YES,
662 #ifdef __NR_pread64
674 #ifdef __NR_pread64
663 S(pread64) = A_YES,
675 S(pread64) = A_YES,
664 S(pwrite64) = A_YES,
676 S(pwrite64) = A_YES,
665 #else
677 #else
666 S(pread) = A_YES,
678 S(pread) = A_YES,
667 S(pwrite) = A_YES,
679 S(pwrite) = A_YES,
668 #endif
680 #endif
669 S(fcntl) = A_YES,
681 S(fcntl) = A_YES,
670 S(mmap) = A_YES,
682 S(mmap) = A_YES,
671 S(munmap) = A_YES,
683 S(munmap) = A_YES,
672 S(ioctl) = A_YES,
684 S(ioctl) = A_YES,
673 S(uname) = A_YES,
685 S(uname) = A_YES,
674 S(gettid) = A_YES,
686 S(gettid) = A_YES,
675 S(set_thread_area) = A_YES,
687 S(set_thread_area) = A_YES,
676 S(get_thread_area) = A_YES,
688 S(get_thread_area) = A_YES,
677 S(set_tid_address) = A_YES,
689 S(set_tid_address) = A_YES,
678 S(exit_group) = A_YES | A_SAMPLE_MEM,
690 S(exit_group) = A_YES | A_SAMPLE_MEM,
679 #ifdef CONFIG_BOX_USER_AMD64
691 #ifdef CONFIG_BOX_USER_AMD64
680 S(arch_prctl) = A_YES,
692 S(arch_prctl) = A_YES,
681 #else
693 #else
682 S(oldfstat) = A_YES,
694 S(oldfstat) = A_YES,
683 S(ftruncate64) = A_YES,
695 S(ftruncate64) = A_YES,
684 S(_llseek) = A_YES,
696 S(_llseek) = A_YES,
685 S(fstat64) = A_YES,
697 S(fstat64) = A_YES,
686 S(fcntl64) = A_YES,
698 S(fcntl64) = A_YES,
687 S(mmap2) = A_YES,
699 S(mmap2) = A_YES,
688 #endif
700 #endif
689
701
690 // Syscalls permitted only in liberal mode
702 // Syscalls permitted only in liberal mode
691 S(time) = A_YES | A_LIBERAL,
703 S(time) = A_YES | A_LIBERAL,
692 S(alarm) = A_YES | A_LIBERAL,
704 S(alarm) = A_YES | A_LIBERAL,
693 S(pause) = A_YES | A_LIBERAL,
705 S(pause) = A_YES | A_LIBERAL,
694 S(fchmod) = A_YES | A_LIBERAL,
706 S(fchmod) = A_YES | A_LIBERAL,
695 S(getrlimit) = A_YES | A_LIBERAL,
707 S(getrlimit) = A_YES | A_LIBERAL,
696 S(getrusage) = A_YES | A_LIBERAL,
708 S(getrusage) = A_YES | A_LIBERAL,
697 S(gettimeofday) = A_YES | A_LIBERAL,
709 S(gettimeofday) = A_YES | A_LIBERAL,
698 S(select) = A_YES | A_LIBERAL,
710 S(select) = A_YES | A_LIBERAL,
699 S(setitimer) = A_YES | A_LIBERAL,
711 S(setitimer) = A_YES | A_LIBERAL,
700 S(getitimer) = A_YES | A_LIBERAL,
712 S(getitimer) = A_YES | A_LIBERAL,
701 S(mprotect) = A_YES | A_LIBERAL,
713 S(mprotect) = A_YES | A_LIBERAL,
702 S(getdents) = A_YES | A_LIBERAL,
714 S(getdents) = A_YES | A_LIBERAL,
703 S(getdents64) = A_YES | A_LIBERAL,
715 S(getdents64) = A_YES | A_LIBERAL,
704 S(fdatasync) = A_YES | A_LIBERAL,
716 S(fdatasync) = A_YES | A_LIBERAL,
705 S(mremap) = A_YES | A_LIBERAL,
717 S(mremap) = A_YES | A_LIBERAL,
706 S(poll) = A_YES | A_LIBERAL,
718 S(poll) = A_YES | A_LIBERAL,
707 S(getcwd) = A_YES | A_LIBERAL,
719 S(getcwd) = A_YES | A_LIBERAL,
708 S(nanosleep) = A_YES | A_LIBERAL,
720 S(nanosleep) = A_YES | A_LIBERAL,
709 S(rt_sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
721 S(rt_sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
710 S(rt_sigaction) = A_YES | A_LIBERAL,
722 S(rt_sigaction) = A_YES | A_LIBERAL,
711 S(rt_sigprocmask) = A_YES | A_LIBERAL,
723 S(rt_sigprocmask) = A_YES | A_LIBERAL,
712 S(rt_sigpending) = A_YES | A_LIBERAL,
724 S(rt_sigpending) = A_YES | A_LIBERAL,
713 S(rt_sigtimedwait) = A_YES | A_LIBERAL,
725 S(rt_sigtimedwait) = A_YES | A_LIBERAL,
714 S(rt_sigqueueinfo) = A_YES | A_LIBERAL,
726 S(rt_sigqueueinfo) = A_YES | A_LIBERAL,
715 S(rt_sigsuspend) = A_YES | A_LIBERAL,
727 S(rt_sigsuspend) = A_YES | A_LIBERAL,
716 S(_sysctl) = A_YES | A_LIBERAL,
728 S(_sysctl) = A_YES | A_LIBERAL,
717 #ifndef CONFIG_BOX_USER_AMD64
729 #ifndef CONFIG_BOX_USER_AMD64
718 S(sigaction) = A_YES | A_LIBERAL,
730 S(sigaction) = A_YES | A_LIBERAL,
719 S(sgetmask) = A_YES | A_LIBERAL,
731 S(sgetmask) = A_YES | A_LIBERAL,
720 S(ssetmask) = A_YES | A_LIBERAL,
732 S(ssetmask) = A_YES | A_LIBERAL,
721 S(sigsuspend) = A_YES | A_LIBERAL,
733 S(sigsuspend) = A_YES | A_LIBERAL,
722 S(sigpending) = A_YES | A_LIBERAL,
734 S(sigpending) = A_YES | A_LIBERAL,
723 S(sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
735 S(sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
724 S(sigprocmask) = A_YES | A_LIBERAL,
736 S(sigprocmask) = A_YES | A_LIBERAL,
725 S(ugetrlimit) = A_YES | A_LIBERAL,
737 S(ugetrlimit) = A_YES | A_LIBERAL,
726 S(readdir) = A_YES | A_LIBERAL,
738 S(readdir) = A_YES | A_LIBERAL,
727 S(signal) = A_YES | A_LIBERAL,
739 S(signal) = A_YES | A_LIBERAL,
728 S(_newselect) = A_YES | A_LIBERAL,
740 S(_newselect) = A_YES | A_LIBERAL,
729 #endif
741 #endif
730
742
731 #undef S
743 #undef S
732 };
744 };
733
745
734 static const char *
746 static const char *
735 syscall_name(unsigned int id, char *buf)
747 syscall_name(unsigned int id, char *buf)
736 {
748 {
737 if (id < NUM_SYSCALLS && syscall_names[id])
749 if (id < NUM_SYSCALLS && syscall_names[id])
738 return syscall_names[id];
750 return syscall_names[id];
739 else
751 else
740 {
752 {
741 sprintf(buf, "#%d", id);
753 sprintf(buf, "#%d", id);
742 return buf;
754 return buf;
743 }
755 }
744 }
756 }
745
757
746 static int
758 static int
747 syscall_by_name(char *name)
759 syscall_by_name(char *name)
748 {
760 {
749 for (unsigned int i=0; i<NUM_SYSCALLS; i++)
761 for (unsigned int i=0; i<NUM_SYSCALLS; i++)
750 if (syscall_names[i] && !strcmp(syscall_names[i], name))
762 if (syscall_names[i] && !strcmp(syscall_names[i], name))
751 return i;
763 return i;
752 if (name[0] == '#')
764 if (name[0] == '#')
753 name++;
765 name++;
754 if (!*name)
766 if (!*name)
755 return -1;
767 return -1;
756 char *ep;
768 char *ep;
757 unsigned long l = strtoul(name, &ep, 0);
769 unsigned long l = strtoul(name, &ep, 0);
758 if (*ep)
770 if (*ep)
759 return -1;
771 return -1;
760 if (l >= NUM_ACTIONS)
772 if (l >= NUM_ACTIONS)
761 return NUM_ACTIONS;
773 return NUM_ACTIONS;
762 return l;
774 return l;
763 }
775 }
764
776
765 static int
777 static int
766 set_syscall_action(char *a)
778 set_syscall_action(char *a)
767 {
779 {
768 char *sep = strchr(a, '=');
780 char *sep = strchr(a, '=');
769 enum action act = A_YES;
781 enum action act = A_YES;
770 if (sep)
782 if (sep)
771 {
783 {
772 *sep++ = 0;
784 *sep++ = 0;
773 if (!strcmp(sep, "yes"))
785 if (!strcmp(sep, "yes"))
774 act = A_YES;
786 act = A_YES;
775 else if (!strcmp(sep, "no"))
787 else if (!strcmp(sep, "no"))
776 act = A_NO;
788 act = A_NO;
777 else if (!strcmp(sep, "file"))
789 else if (!strcmp(sep, "file"))
778 act = A_FILENAME;
790 act = A_FILENAME;
779 else
791 else
780 return 0;
792 return 0;
781 }
793 }
782
794
783 int sys = syscall_by_name(a);
795 int sys = syscall_by_name(a);
784 if (sys < 0)
796 if (sys < 0)
785 die("Unknown syscall `%s'", a);
797 die("Unknown syscall `%s'", a);
786 if (sys >= NUM_ACTIONS)
798 if (sys >= NUM_ACTIONS)
787 die("Syscall `%s' out of range", a);
799 die("Syscall `%s' out of range", a);
788 syscall_action[sys] = act;
800 syscall_action[sys] = act;
789 return 1;
801 return 1;
790 }
802 }
791
803
792 /*** Path rules ***/
804 /*** Path rules ***/
793
805
794 struct path_rule {
806 struct path_rule {
795 char *path;
807 char *path;
796 enum action action;
808 enum action action;
797 struct path_rule *next;
809 struct path_rule *next;
798 };
810 };
799
811
800 static struct path_rule default_path_rules[] = {
812 static struct path_rule default_path_rules[] = {
801 { "/etc/", A_YES },
813 { "/etc/", A_YES },
802 { "/lib/", A_YES },
814 { "/lib/", A_YES },
803 { "/usr/lib/", A_YES },
815 { "/usr/lib/", A_YES },
804 { "/opt/lib/", A_YES },
816 { "/opt/lib/", A_YES },
805 { "/usr/share/zoneinfo/", A_YES },
817 { "/usr/share/zoneinfo/", A_YES },
806 { "/usr/share/locale/", A_YES },
818 { "/usr/share/locale/", A_YES },
807 { "/dev/null", A_YES },
819 { "/dev/null", A_YES },
808 { "/dev/zero", A_YES },
820 { "/dev/zero", A_YES },
809 { "/proc/meminfo", A_YES },
821 { "/proc/meminfo", A_YES },
810 { "/proc/self/stat", A_YES },
822 { "/proc/self/stat", A_YES },
811 { "/proc/self/exe", A_YES }, // Needed by FPC 2.0.x runtime
823 { "/proc/self/exe", A_YES }, // Needed by FPC 2.0.x runtime
812 { "/proc/self/maps", A_YES }, // Needed by glibc when it reports arena corruption
824 { "/proc/self/maps", A_YES }, // Needed by glibc when it reports arena corruption
813 };
825 };
814
826
815 static struct path_rule *user_path_rules;
827 static struct path_rule *user_path_rules;
816 static struct path_rule **last_path_rule = &user_path_rules;
828 static struct path_rule **last_path_rule = &user_path_rules;
817
829
818 static int
830 static int
819 set_path_action(char *a)
831 set_path_action(char *a)
820 {
832 {
821 char *sep = strchr(a, '=');
833 char *sep = strchr(a, '=');
822 enum action act = A_YES;
834 enum action act = A_YES;
823 if (sep)
835 if (sep)
824 {
836 {
825 *sep++ = 0;
837 *sep++ = 0;
826 if (!strcmp(sep, "yes"))
838 if (!strcmp(sep, "yes"))
827 act = A_YES;
839 act = A_YES;
828 else if (!strcmp(sep, "no"))
840 else if (!strcmp(sep, "no"))
829 act = A_NO;
841 act = A_NO;
830 else
842 else
831 return 0;
843 return 0;
832 }
844 }
833
845
834 struct path_rule *r = xmalloc(sizeof(*r) + strlen(a) + 1);
846 struct path_rule *r = xmalloc(sizeof(*r) + strlen(a) + 1);
835 r->path = (char *)(r+1);
847 r->path = (char *)(r+1);
836 strcpy(r->path, a);
848 strcpy(r->path, a);
837 r->action = act;
849 r->action = act;
838 r->next = NULL;
850 r->next = NULL;
839 *last_path_rule = r;
851 *last_path_rule = r;
840 last_path_rule = &r->next;
852 last_path_rule = &r->next;
841 return 1;
853 return 1;
842 }
854 }
843
855
844 static enum action
856 static enum action
845 match_path_rule(struct path_rule *r, char *path)
857 match_path_rule(struct path_rule *r, char *path)
846 {
858 {
847 char *rr = r->path;
859 char *rr = r->path;
848 while (*rr)
860 while (*rr)
849 if (*rr++ != *path++)
861 if (*rr++ != *path++)
850 {
862 {
851 if (rr[-1] == '/' && !path[-1])
863 if (rr[-1] == '/' && !path[-1])
852 break;
864 break;
853 return A_DEFAULT;
865 return A_DEFAULT;
854 }
866 }
855 if (rr > r->path && rr[-1] != '/' && *path)
867 if (rr > r->path && rr[-1] != '/' && *path)
856 return A_DEFAULT;
868 return A_DEFAULT;
857 return r->action;
869 return r->action;
858 }
870 }
859
871
860 /*** Environment rules ***/
872 /*** Environment rules ***/
861
873
862 struct env_rule {
874 struct env_rule {
863 char *var; // Variable to match
875 char *var; // Variable to match
864 char *val; // ""=clear, NULL=inherit
876 char *val; // ""=clear, NULL=inherit
865 int var_len;
877 int var_len;
866 struct env_rule *next;
878 struct env_rule *next;
867 };
879 };
868
880
869 static struct env_rule *first_env_rule;
881 static struct env_rule *first_env_rule;
870 static struct env_rule **last_env_rule = &first_env_rule;
882 static struct env_rule **last_env_rule = &first_env_rule;
871
883
872 static struct env_rule default_env_rules[] = {
884 static struct env_rule default_env_rules[] = {
873 { "LIBC_FATAL_STDERR_", "1" }
885 { "LIBC_FATAL_STDERR_", "1" }
874 };
886 };
875
887
876 static int
888 static int
877 set_env_action(char *a0)
889 set_env_action(char *a0)
878 {
890 {
879 struct env_rule *r = xmalloc(sizeof(*r) + strlen(a0) + 1);
891 struct env_rule *r = xmalloc(sizeof(*r) + strlen(a0) + 1);
880 char *a = (char *)(r+1);
892 char *a = (char *)(r+1);
881 strcpy(a, a0);
893 strcpy(a, a0);
882
894
883 char *sep = strchr(a, '=');
895 char *sep = strchr(a, '=');
884 if (sep == a)
896 if (sep == a)
885 return 0;
897 return 0;
886 r->var = a;
898 r->var = a;
887 if (sep)
899 if (sep)
888 {
900 {
889 *sep++ = 0;
901 *sep++ = 0;
890 r->val = sep;
902 r->val = sep;
891 }
903 }
892 else
904 else
893 r->val = NULL;
905 r->val = NULL;
894 *last_env_rule = r;
906 *last_env_rule = r;
895 last_env_rule = &r->next;
907 last_env_rule = &r->next;
896 r->next = NULL;
908 r->next = NULL;
897 return 1;
909 return 1;
898 }
910 }
899
911
900 static int
912 static int
901 match_env_var(char *env_entry, struct env_rule *r)
913 match_env_var(char *env_entry, struct env_rule *r)
902 {
914 {
903 if (strncmp(env_entry, r->var, r->var_len))
915 if (strncmp(env_entry, r->var, r->var_len))
904 return 0;
916 return 0;
905 return (env_entry[r->var_len] == '=');
917 return (env_entry[r->var_len] == '=');
906 }
918 }
907
919
908 static void
920 static void
909 apply_env_rule(char **env, int *env_sizep, struct env_rule *r)
921 apply_env_rule(char **env, int *env_sizep, struct env_rule *r)
910 {
922 {
911 // First remove the variable if already set
923 // First remove the variable if already set
912 int pos = 0;
924 int pos = 0;
913 while (pos < *env_sizep && !match_env_var(env[pos], r))
925 while (pos < *env_sizep && !match_env_var(env[pos], r))
914 pos++;
926 pos++;
915 if (pos < *env_sizep)
927 if (pos < *env_sizep)
916 {
928 {
917 (*env_sizep)--;
929 (*env_sizep)--;
918 env[pos] = env[*env_sizep];
930 env[pos] = env[*env_sizep];
919 env[*env_sizep] = NULL;
931 env[*env_sizep] = NULL;
920 }
932 }
921
933
922 // What is the new value?
934 // What is the new value?
923 char *new;
935 char *new;
924 if (r->val)
936 if (r->val)
925 {
937 {
926 if (!r->val[0])
938 if (!r->val[0])
927 return;
939 return;
928 new = xmalloc(r->var_len + 1 + strlen(r->val) + 1);
940 new = xmalloc(r->var_len + 1 + strlen(r->val) + 1);
929 sprintf(new, "%s=%s", r->var, r->val);
941 sprintf(new, "%s=%s", r->var, r->val);
930 }
942 }
931 else
943 else
932 {
944 {
933 pos = 0;
945 pos = 0;
934 while (environ[pos] && !match_env_var(environ[pos], r))
946 while (environ[pos] && !match_env_var(environ[pos], r))
935 pos++;
947 pos++;
936 if (!(new = environ[pos]))
948 if (!(new = environ[pos]))
937 return;
949 return;
938 }
950 }
939
951
940 // Add it at the end of the array
952 // Add it at the end of the array
941 env[(*env_sizep)++] = new;
953 env[(*env_sizep)++] = new;
942 env[*env_sizep] = NULL;
954 env[*env_sizep] = NULL;
943 }
955 }
944
956
945 static char **
957 static char **
946 setup_environment(void)
958 setup_environment(void)
947 {
959 {
948 // Link built-in rules with user rules
960 // Link built-in rules with user rules
949 for (int i=ARRAY_SIZE(default_env_rules)-1; i >= 0; i--)
961 for (int i=ARRAY_SIZE(default_env_rules)-1; i >= 0; i--)
950 {
962 {
951 default_env_rules[i].next = first_env_rule;
963 default_env_rules[i].next = first_env_rule;
952 first_env_rule = &default_env_rules[i];
964 first_env_rule = &default_env_rules[i];
953 }
965 }
954
966
955 // Scan the original environment
967 // Scan the original environment
956 char **orig_env = environ;
968 char **orig_env = environ;
957 int orig_size = 0;
969 int orig_size = 0;
958 while (orig_env[orig_size])
970 while (orig_env[orig_size])
959 orig_size++;
971 orig_size++;
960
972
961 // For each rule, reserve one more slot and calculate length
973 // For each rule, reserve one more slot and calculate length
962 int num_rules = 0;
974 int num_rules = 0;
963 for (struct env_rule *r = first_env_rule; r; r=r->next)
975 for (struct env_rule *r = first_env_rule; r; r=r->next)
964 {
976 {
965 num_rules++;
977 num_rules++;
966 r->var_len = strlen(r->var);
978 r->var_len = strlen(r->var);
967 }
979 }
968
980
969 // Create a new environment
981 // Create a new environment
970 char **env = xmalloc((orig_size + num_rules + 1) * sizeof(char *));
982 char **env = xmalloc((orig_size + num_rules + 1) * sizeof(char *));
971 int size;
983 int size;
972 if (pass_environ)
984 if (pass_environ)
973 {
985 {
974 memcpy(env, environ, orig_size * sizeof(char *));
986 memcpy(env, environ, orig_size * sizeof(char *));
975 size = orig_size;
987 size = orig_size;
976 }
988 }
977 else
989 else
978 size = 0;
990 size = 0;
979 env[size] = NULL;
991 env[size] = NULL;
980
992
981 // Apply the rules one by one
993 // Apply the rules one by one
982 for (struct env_rule *r = first_env_rule; r; r=r->next)
994 for (struct env_rule *r = first_env_rule; r; r=r->next)
983 apply_env_rule(env, &size, r);
995 apply_env_rule(env, &size, r);
984
996
985 // Return the new env and pass some gossip
997 // Return the new env and pass some gossip
986 if (verbose > 1)
998 if (verbose > 1)
987 {
999 {
988 fprintf(stderr, "Passing environment:\n");
1000 fprintf(stderr, "Passing environment:\n");
989 for (int i=0; env[i]; i++)
1001 for (int i=0; env[i]; i++)
990 fprintf(stderr, "\t%s\n", env[i]);
1002 fprintf(stderr, "\t%s\n", env[i]);
991 }
1003 }
992 return env;
1004 return env;
993 }
1005 }
994
1006
995 /*** Low-level parsing of syscalls ***/
1007 /*** Low-level parsing of syscalls ***/
996
1008
997 #ifdef CONFIG_BOX_KERNEL_AMD64
1009 #ifdef CONFIG_BOX_KERNEL_AMD64
998 typedef uint64_t arg_t;
1010 typedef uint64_t arg_t;
999 #else
1011 #else
1000 typedef uint32_t arg_t;
1012 typedef uint32_t arg_t;
1001 #endif
1013 #endif
1002
1014
1003 struct syscall_args {
1015 struct syscall_args {
1004 arg_t sys;
1016 arg_t sys;
1005 arg_t arg1, arg2, arg3;
1017 arg_t arg1, arg2, arg3;
1006 arg_t result;
1018 arg_t result;
1007 struct user user;
1019 struct user user;
1008 };
1020 };
1009
1021
1010 static int user_mem_fd;
1022 static int user_mem_fd;
1011
1023
1012 static int read_user_mem(arg_t addr, char *buf, int len)
1024 static int read_user_mem(arg_t addr, char *buf, int len)
1013 {
1025 {
1014 if (!user_mem_fd)
1026 if (!user_mem_fd)
1015 {
1027 {
1016 char memname[64];
1028 char memname[64];
1017 sprintf(memname, "/proc/%d/mem", (int) box_pid);
1029 sprintf(memname, "/proc/%d/mem", (int) box_pid);
1018 user_mem_fd = open(memname, O_RDONLY);
1030 user_mem_fd = open(memname, O_RDONLY);
1019 if (user_mem_fd < 0)
1031 if (user_mem_fd < 0)
1020 die("open(%s): %m", memname);
1032 die("open(%s): %m", memname);
1021 }
1033 }
1022 if (lseek64(user_mem_fd, addr, SEEK_SET) < 0)
1034 if (lseek64(user_mem_fd, addr, SEEK_SET) < 0)
1023 die("lseek64(mem): %m");
1035 die("lseek64(mem): %m");
1024 return read(user_mem_fd, buf, len);
1036 return read(user_mem_fd, buf, len);
1025 }
1037 }
1026
1038
1027 static void close_user_mem(void)
1039 static void close_user_mem(void)
1028 {
1040 {
1029 if (user_mem_fd)
1041 if (user_mem_fd)
1030 {
1042 {
1031 close(user_mem_fd);
1043 close(user_mem_fd);
1032 user_mem_fd = 0;
1044 user_mem_fd = 0;
1033 }
1045 }
1034 }
1046 }
1035
1047
1036 #ifdef CONFIG_BOX_KERNEL_AMD64
1048 #ifdef CONFIG_BOX_KERNEL_AMD64
1037
1049
1038 static void
1050 static void
1039 get_syscall_args(struct syscall_args *a, int is_exit)
1051 get_syscall_args(struct syscall_args *a, int is_exit)
1040 {
1052 {
1041 if (ptrace(PTRACE_GETREGS, box_pid, NULL, &a->user) < 0)
1053 if (ptrace(PTRACE_GETREGS, box_pid, NULL, &a->user) < 0)
1042 die("ptrace(PTRACE_GETREGS): %m");
1054 die("ptrace(PTRACE_GETREGS): %m");
1043 a->sys = a->user.regs.orig_rax;
1055 a->sys = a->user.regs.orig_rax;
1044 a->result = a->user.regs.rax;
1056 a->result = a->user.regs.rax;
1045
1057
1046 /*
1058 /*
1047 * CAVEAT: We have to check carefully that this is a real 64-bit syscall.
1059 * CAVEAT: We have to check carefully that this is a real 64-bit syscall.
1048 * We test whether the process runs in 64-bit mode, but surprisingly this
1060 * We test whether the process runs in 64-bit mode, but surprisingly this
1049 * is not enough: a 64-bit process can still issue the INT 0x80 instruction
1061 * is not enough: a 64-bit process can still issue the INT 0x80 instruction
1050 * which performs a 32-bit syscall. Currently, the only known way how to
1062 * which performs a 32-bit syscall. Currently, the only known way how to
1051 * detect this situation is to inspect the instruction code (the kernel
1063 * detect this situation is to inspect the instruction code (the kernel
1052 * keeps a syscall type flag internally, but it is not accessible from
1064 * keeps a syscall type flag internally, but it is not accessible from
1053 * user space). Hopefully, there is no instruction whose suffix is the
1065 * user space). Hopefully, there is no instruction whose suffix is the
1054 * code of the SYSCALL instruction. Sometimes, one would wish the
1066 * code of the SYSCALL instruction. Sometimes, one would wish the
1055 * instruction codes to be unique even when read backwards :)
1067 * instruction codes to be unique even when read backwards :)
1056 */
1068 */
1057
1069
1058 if (is_exit)
1070 if (is_exit)
1059 return;
1071 return;
1060
1072
1061 int sys_type;
1073 int sys_type;
1062 uint16_t instr;
1074 uint16_t instr;
1063
1075
1064 switch (a->user.regs.cs)
1076 switch (a->user.regs.cs)
1065 {
1077 {
1066 case 0x23:
1078 case 0x23:
1067 // 32-bit CPU mode => only 32-bit syscalls can be issued
1079 // 32-bit CPU mode => only 32-bit syscalls can be issued
1068 sys_type = 32;
1080 sys_type = 32;
1069 break;
1081 break;
1070 case 0x33:
1082 case 0x33:
1071 // 64-bit CPU mode
1083 // 64-bit CPU mode
1072 if (read_user_mem(a->user.regs.rip-2, (char *) &instr, 2) != 2)
1084 if (read_user_mem(a->user.regs.rip-2, (char *) &instr, 2) != 2)
1073 err("FO: Cannot read syscall instruction");
1085 err("FO: Cannot read syscall instruction");
1074 switch (instr)
1086 switch (instr)
1075 {
1087 {
1076 case 0x050f:
1088 case 0x050f:
1077 break;
1089 break;
1078 case 0x80cd:
1090 case 0x80cd:
1079 err("FO: Forbidden 32-bit syscall in 64-bit mode");
1091 err("FO: Forbidden 32-bit syscall in 64-bit mode");
1080 default:
1092 default:
1081 err("XX: Unknown syscall instruction %04x", instr);
1093 err("XX: Unknown syscall instruction %04x", instr);
1082 }
1094 }
1083 sys_type = 64;
1095 sys_type = 64;
1084 break;
1096 break;
1085 default:
1097 default:
1086 err("XX: Unknown code segment %04jx", (intmax_t) a->user.regs.cs);
1098 err("XX: Unknown code segment %04jx", (intmax_t) a->user.regs.cs);
1087 }
1099 }
1088
1100
1089 #ifdef CONFIG_BOX_USER_AMD64
1101 #ifdef CONFIG_BOX_USER_AMD64
1090 if (sys_type != 64)
1102 if (sys_type != 64)
1091 err("FO: Forbidden %d-bit mode syscall", sys_type);
1103 err("FO: Forbidden %d-bit mode syscall", sys_type);
1092 #else
1104 #else
1093 if (sys_type != (exec_seen ? 32 : 64))
1105 if (sys_type != (exec_seen ? 32 : 64))
1094 err("FO: Forbidden %d-bit mode syscall", sys_type);
1106 err("FO: Forbidden %d-bit mode syscall", sys_type);
1095 #endif
1107 #endif
1096
1108
1097 if (sys_type == 32)
1109 if (sys_type == 32)
1098 {
1110 {
1099 a->arg1 = a->user.regs.rbx;
1111 a->arg1 = a->user.regs.rbx;
1100 a->arg2 = a->user.regs.rcx;
1112 a->arg2 = a->user.regs.rcx;
1101 a->arg3 = a->user.regs.rdx;
1113 a->arg3 = a->user.regs.rdx;
1102 }
1114 }
1103 else
1115 else
1104 {
1116 {
1105 a->arg1 = a->user.regs.rdi;
1117 a->arg1 = a->user.regs.rdi;
1106 a->arg2 = a->user.regs.rsi;
1118 a->arg2 = a->user.regs.rsi;
1107 a->arg3 = a->user.regs.rdx;
1119 a->arg3 = a->user.regs.rdx;
1108 }
1120 }
1109 }
1121 }
1110
1122
1111 static void
1123 static void
1112 set_syscall_nr(struct syscall_args *a, arg_t sys)
1124 set_syscall_nr(struct syscall_args *a, arg_t sys)
1113 {
1125 {
1114 a->sys = sys;
1126 a->sys = sys;
1115 a->user.regs.orig_rax = sys;
1127 a->user.regs.orig_rax = sys;
1116 if (ptrace(PTRACE_SETREGS, box_pid, NULL, &a->user) < 0)
1128 if (ptrace(PTRACE_SETREGS, box_pid, NULL, &a->user) < 0)
1117 die("ptrace(PTRACE_SETREGS): %m");
1129 die("ptrace(PTRACE_SETREGS): %m");
1118 }
1130 }
1119
1131
1120 static void
1132 static void
1121 sanity_check(void)
1133 sanity_check(void)
1122 {
1134 {
1123 }
1135 }
1124
1136
1125 #else
1137 #else
1126
1138
1127 static void
1139 static void
1128 get_syscall_args(struct syscall_args *a, int is_exit UNUSED)
1140 get_syscall_args(struct syscall_args *a, int is_exit UNUSED)
1129 {
1141 {
1130 if (ptrace(PTRACE_GETREGS, box_pid, NULL, &a->user) < 0)
1142 if (ptrace(PTRACE_GETREGS, box_pid, NULL, &a->user) < 0)
1131 die("ptrace(PTRACE_GETREGS): %m");
1143 die("ptrace(PTRACE_GETREGS): %m");
1132 a->sys = a->user.regs.orig_eax;
1144 a->sys = a->user.regs.orig_eax;
1133 a->arg1 = a->user.regs.ebx;
1145 a->arg1 = a->user.regs.ebx;
1134 a->arg2 = a->user.regs.ecx;
1146 a->arg2 = a->user.regs.ecx;
1135 a->arg3 = a->user.regs.edx;
1147 a->arg3 = a->user.regs.edx;
1136 a->result = a->user.regs.eax;
1148 a->result = a->user.regs.eax;
1137 }
1149 }
1138
1150
1139 static void
1151 static void
1140 set_syscall_nr(struct syscall_args *a, arg_t sys)
1152 set_syscall_nr(struct syscall_args *a, arg_t sys)
1141 {
1153 {
1142 a->sys = sys;
1154 a->sys = sys;
1143 a->user.regs.orig_eax = sys;
1155 a->user.regs.orig_eax = sys;
1144 if (ptrace(PTRACE_SETREGS, box_pid, NULL, &a->user) < 0)
1156 if (ptrace(PTRACE_SETREGS, box_pid, NULL, &a->user) < 0)
1145 die("ptrace(PTRACE_SETREGS): %m");
1157 die("ptrace(PTRACE_SETREGS): %m");
1146 }
1158 }
1147
1159
1148 static void
1160 static void
1149 sanity_check(void)
1161 sanity_check(void)
1150 {
1162 {
1151 #if !defined(CONFIG_BOX_ALLOW_INSECURE)
1163 #if !defined(CONFIG_BOX_ALLOW_INSECURE)
1152 struct utsname uts;
1164 struct utsname uts;
1153 if (uname(&uts) < 0)
1165 if (uname(&uts) < 0)
1154 die("uname() failed: %m");
1166 die("uname() failed: %m");
1155
1167
1156 if (!strcmp(uts.machine, "x86_64"))
1168 if (!strcmp(uts.machine, "x86_64"))
1157 die("Running 32-bit sandbox on 64-bit kernels is inherently unsafe. Please get a 64-bit version.");
1169 die("Running 32-bit sandbox on 64-bit kernels is inherently unsafe. Please get a 64-bit version.");
1158 #endif
1170 #endif
1159 }
1171 }
1160
1172
1161 #endif
1173 #endif
1162
1174
1163 /*** Syscall checks ***/
1175 /*** Syscall checks ***/
1164
1176
1165 static void
1177 static void
1166 valid_filename(arg_t addr)
1178 valid_filename(arg_t addr)
1167 {
1179 {
1168 char namebuf[4096], *p, *end;
1180 char namebuf[4096], *p, *end;
1169
1181
1170 if (!file_access)
1182 if (!file_access)
1171 err("FA: File access forbidden");
1183 err("FA: File access forbidden");
1172 if (file_access >= 9)
1184 if (file_access >= 9)
1173 return;
1185 return;
1174
1186
1175 p = end = namebuf;
1187 p = end = namebuf;
1176 do
1188 do
1177 {
1189 {
1178 if (p >= end)
1190 if (p >= end)
1179 {
1191 {
1180 int remains = PAGE_SIZE - (addr & (PAGE_SIZE-1));
1192 int remains = PAGE_SIZE - (addr & (PAGE_SIZE-1));
1181 int l = namebuf + sizeof(namebuf) - end;
1193 int l = namebuf + sizeof(namebuf) - end;
1182 if (l > remains)
1194 if (l > remains)
1183 l = remains;
1195 l = remains;
1184 if (!l)
1196 if (!l)
1185 err("FA: Access to file with name too long");
1197 err("FA: Access to file with name too long");
1186 remains = read_user_mem(addr, end, l);
1198 remains = read_user_mem(addr, end, l);
1187 if (remains < 0)
1199 if (remains < 0)
1188 die("read(mem): %m");
1200 die("read(mem): %m");
1189 if (!remains)
1201 if (!remains)
1190 err("FA: Access to file with name out of memory");
1202 err("FA: Access to file with name out of memory");
1191 end += remains;
1203 end += remains;
1192 addr += remains;
1204 addr += remains;
1193 }
1205 }
1194 }
1206 }
1195 while (*p++);
1207 while (*p++);
1196
1208
1197 msg("[%s] ", namebuf);
1209 msg("[%s] ", namebuf);
1198 if (file_access >= 3)
1210 if (file_access >= 3)
1199 return;
1211 return;
1200
1212
1201 // Everything in current directory is permitted
1213 // Everything in current directory is permitted
1202 if (!strchr(namebuf, '/') && strcmp(namebuf, ".."))
1214 if (!strchr(namebuf, '/') && strcmp(namebuf, ".."))
1203 return;
1215 return;
1204
1216
1205 // ".." anywhere in the path is forbidden
1217 // ".." anywhere in the path is forbidden
1206 enum action act = A_DEFAULT;
1218 enum action act = A_DEFAULT;
1207 if (strstr(namebuf, ".."))
1219 if (strstr(namebuf, ".."))
1208 act = A_NO;
1220 act = A_NO;
1209
1221
1210 // Scan user rules
1222 // Scan user rules
1211 for (struct path_rule *r = user_path_rules; r && !act; r=r->next)
1223 for (struct path_rule *r = user_path_rules; r && !act; r=r->next)
1212 act = match_path_rule(r, namebuf);
1224 act = match_path_rule(r, namebuf);
1213
1225
1214 // Scan built-in rules
1226 // Scan built-in rules
1215 if (file_access >= 2)
1227 if (file_access >= 2)
1216 for (int i=0; i<ARRAY_SIZE(default_path_rules) && !act; i++)
1228 for (int i=0; i<ARRAY_SIZE(default_path_rules) && !act; i++)
1217 act = match_path_rule(&default_path_rules[i], namebuf);
1229 act = match_path_rule(&default_path_rules[i], namebuf);
1218
1230
1219 if (act != A_YES)
1231 if (act != A_YES)
1220 err("FA: Forbidden access to file `%s'", namebuf);
1232 err("FA: Forbidden access to file `%s'", namebuf);
1221 }
1233 }
1222
1234
1223 // Check syscall. If invalid, return -1, otherwise return the action mask.
1235 // Check syscall. If invalid, return -1, otherwise return the action mask.
1224 static int
1236 static int
1225 valid_syscall(struct syscall_args *a)
1237 valid_syscall(struct syscall_args *a)
1226 {
1238 {
1227 unsigned int sys = a->sys;
1239 unsigned int sys = a->sys;
1228 unsigned int act = (sys < NUM_ACTIONS) ? syscall_action[sys] : A_DEFAULT;
1240 unsigned int act = (sys < NUM_ACTIONS) ? syscall_action[sys] : A_DEFAULT;
1229
1241
1230 if (act & A_LIBERAL)
1242 if (act & A_LIBERAL)
1231 {
1243 {
1232 if (filter_syscalls != 1)
1244 if (filter_syscalls != 1)
1233 act = A_DEFAULT;
1245 act = A_DEFAULT;
1234 }
1246 }
1235
1247
1236 switch (act & A_ACTION_MASK)
1248 switch (act & A_ACTION_MASK)
1237 {
1249 {
1238 case A_YES:
1250 case A_YES:
1239 return act;
1251 return act;
1240 case A_NO:
1252 case A_NO:
1241 return -1;
1253 return -1;
1242 case A_FILENAME:
1254 case A_FILENAME:
1243 valid_filename(a->arg1);
1255 valid_filename(a->arg1);
1244 return act;
1256 return act;
1245 default: ;
1257 default: ;
1246 }
1258 }
1247
1259
1248 switch (sys)
1260 switch (sys)
1249 {
1261 {
1250 case __NR_kill:
1262 case __NR_kill:
1251 if (a->arg1 == (arg_t) box_pid)
1263 if (a->arg1 == (arg_t) box_pid)
1252 {
1264 {
1253 meta_printf("exitsig:%d\n", (int) a->arg2);
1265 meta_printf("exitsig:%d\n", (int) a->arg2);
1254 err("SG: Committed suicide by signal %d", (int) a->arg2);
1266 err("SG: Committed suicide by signal %d", (int) a->arg2);
1255 }
1267 }
1256 return -1;
1268 return -1;
1257 case __NR_tgkill:
1269 case __NR_tgkill:
1258 if (a->arg1 == (arg_t) box_pid && a->arg2 == (arg_t) box_pid)
1270 if (a->arg1 == (arg_t) box_pid && a->arg2 == (arg_t) box_pid)
1259 {
1271 {
1260 meta_printf("exitsig:%d\n", (int) a->arg3);
1272 meta_printf("exitsig:%d\n", (int) a->arg3);
1261 err("SG: Committed suicide by signal %d", (int) a->arg3);
1273 err("SG: Committed suicide by signal %d", (int) a->arg3);
1262 }
1274 }
1263 return -1;
1275 return -1;
1264 default:
1276 default:
1265 return -1;
1277 return -1;
1266 }
1278 }
1267 }
1279 }
1268
1280
1269 static void
1281 static void
1270 signal_alarm(int unused UNUSED)
1282 signal_alarm(int unused UNUSED)
1271 {
1283 {
1272 /* Time limit checks are synchronous, so we only schedule them there. */
1284 /* Time limit checks are synchronous, so we only schedule them there. */
1273 timer_tick = 1;
1285 timer_tick = 1;
1274 alarm(1);
1286 alarm(1);
1275 }
1287 }
1276
1288
1277 static void
1289 static void
1278 signal_int(int unused UNUSED)
1290 signal_int(int unused UNUSED)
1279 {
1291 {
1280 /* Interrupts are fatal, so no synchronization requirements. */
1292 /* Interrupts are fatal, so no synchronization requirements. */
1281 meta_printf("exitsig:%d\n", SIGINT);
1293 meta_printf("exitsig:%d\n", SIGINT);
1282 err("SG: Interrupted");
1294 err("SG: Interrupted");
1283 }
1295 }
1284
1296
1285 #define PROC_BUF_SIZE 4096
1297 #define PROC_BUF_SIZE 4096
1286 static void
1298 static void
1287 read_proc_file(char *buf, char *name, int *fdp)
1299 read_proc_file(char *buf, char *name, int *fdp)
1288 {
1300 {
1289 int c;
1301 int c;
1290
1302
1291 if (!*fdp)
1303 if (!*fdp)
1292 {
1304 {
1293 sprintf(buf, "/proc/%d/%s", (int) box_pid, name);
1305 sprintf(buf, "/proc/%d/%s", (int) box_pid, name);
1294 *fdp = open(buf, O_RDONLY);
1306 *fdp = open(buf, O_RDONLY);
1295 if (*fdp < 0)
1307 if (*fdp < 0)
1296 die("open(%s): %m", buf);
1308 die("open(%s): %m", buf);
1297 }
1309 }
1298 lseek(*fdp, 0, SEEK_SET);
1310 lseek(*fdp, 0, SEEK_SET);
1299 if ((c = read(*fdp, buf, PROC_BUF_SIZE-1)) < 0)
1311 if ((c = read(*fdp, buf, PROC_BUF_SIZE-1)) < 0)
1300 die("read on /proc/$pid/%s: %m", name);
1312 die("read on /proc/$pid/%s: %m", name);
1301 if (c >= PROC_BUF_SIZE-1)
1313 if (c >= PROC_BUF_SIZE-1)
1302 die("/proc/$pid/%s too long", name);
1314 die("/proc/$pid/%s too long", name);
1303 buf[c] = 0;
1315 buf[c] = 0;
1304 }
1316 }
1305
1317
1306 static void
1318 static void
1307 check_timeout(void)
1319 check_timeout(void)
1308 {
1320 {
1309 if (wall_timeout)
1321 if (wall_timeout)
1310 {
1322 {
1311 struct timeval now, wall;
1323 struct timeval now, wall;
1312 int wall_ms;
1324 int wall_ms;
1313 gettimeofday(&now, NULL);
1325 gettimeofday(&now, NULL);
1314 timersub(&now, &start_time, &wall);
1326 timersub(&now, &start_time, &wall);
1315 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
1327 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
1316 if (wall_ms > wall_timeout)
1328 if (wall_ms > wall_timeout)
1317 err("TO: Time limit exceeded (wall clock)");
1329 err("TO: Time limit exceeded (wall clock)");
1318 if (verbose > 1)
1330 if (verbose > 1)
1319 fprintf(stderr, "[wall time check: %d msec]\n", wall_ms);
1331 fprintf(stderr, "[wall time check: %d msec]\n", wall_ms);
1320 }
1332 }
1321 if (timeout)
1333 if (timeout)
1322 {
1334 {
1323 char buf[PROC_BUF_SIZE], *x;
1335 char buf[PROC_BUF_SIZE], *x;
1324 int utime, stime, ms;
1336 int utime, stime, ms;
1325 static int proc_stat_fd;
1337 static int proc_stat_fd;
1326 read_proc_file(buf, "stat", &proc_stat_fd);
1338 read_proc_file(buf, "stat", &proc_stat_fd);
1327 x = buf;
1339 x = buf;
1328 while (*x && *x != ' ')
1340 while (*x && *x != ' ')
1329 x++;
1341 x++;
1330 while (*x == ' ')
1342 while (*x == ' ')
1331 x++;
1343 x++;
1332 if (*x++ != '(')
1344 if (*x++ != '(')
1333 die("proc stat syntax error 1");
1345 die("proc stat syntax error 1");
1334 while (*x && (*x != ')' || x[1] != ' '))
1346 while (*x && (*x != ')' || x[1] != ' '))
1335 x++;
1347 x++;
1336 while (*x == ')' || *x == ' ')
1348 while (*x == ')' || *x == ' ')
1337 x++;
1349 x++;
1338 if (sscanf(x, "%*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d", &utime, &stime) != 2)
1350 if (sscanf(x, "%*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d", &utime, &stime) != 2)
1339 die("proc stat syntax error 2");
1351 die("proc stat syntax error 2");
1340 ms = (utime + stime) * 1000 / ticks_per_sec;
1352 ms = (utime + stime) * 1000 / ticks_per_sec;
1341 if (verbose > 1)
1353 if (verbose > 1)
1342 fprintf(stderr, "[time check: %d msec]\n", ms);
1354 fprintf(stderr, "[time check: %d msec]\n", ms);
1343 if (ms > timeout && ms > extra_timeout)
1355 if (ms > timeout && ms > extra_timeout)
1344 err("TO: Time limit exceeded");
1356 err("TO: Time limit exceeded");
1345 }
1357 }
1346 }
1358 }
1347
1359
1348 static void
1360 static void
1349 sample_mem_peak(void)
1361 sample_mem_peak(void)
1350 {
1362 {
1351 /*
1363 /*
1352 * We want to find out the peak memory usage of the process, which is
1364 * We want to find out the peak memory usage of the process, which is
1353 * maintained by the kernel, but unforunately it gets lost when the
1365 * maintained by the kernel, but unforunately it gets lost when the
1354 * process exits (it is not reported in struct rusage). Therefore we
1366 * process exits (it is not reported in struct rusage). Therefore we
1355 * have to sample it whenever we suspect that the process is about
1367 * have to sample it whenever we suspect that the process is about
1356 * to exit.
1368 * to exit.
1357 */
1369 */
1358 char buf[PROC_BUF_SIZE], *x;
1370 char buf[PROC_BUF_SIZE], *x;
1359 static int proc_status_fd;
1371 static int proc_status_fd;
1360 read_proc_file(buf, "status", &proc_status_fd);
1372 read_proc_file(buf, "status", &proc_status_fd);
1361
1373
1362 x = buf;
1374 x = buf;
1363 while (*x)
1375 while (*x)
1364 {
1376 {
1365 char *key = x;
1377 char *key = x;
1366 while (*x && *x != ':' && *x != '\n')
1378 while (*x && *x != ':' && *x != '\n')
1367 x++;
1379 x++;
1368 if (!*x || *x == '\n')
1380 if (!*x || *x == '\n')
1369 break;
1381 break;
1370 *x++ = 0;
1382 *x++ = 0;
1371 while (*x == ' ' || *x == '\t')
1383 while (*x == ' ' || *x == '\t')
1372 x++;
1384 x++;
1373
1385
@@ -1,194 +1,196
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 require 'fileutils'
3 require 'fileutils'
4
4
5 ##############################
5 ##############################
6 #
6 #
7 # Standard Compile Script
7 # Standard Compile Script
8 #
8 #
9 # Supported compilers:
9 # Supported compilers:
10 # gcc, g++, and fpc.
10 # gcc, g++, and fpc.
11 #
11 #
12 ##############################
12 ##############################
13
13
14 def talk(str='')
14 def talk(str='')
15 if ENV['TALKATIVE']!=nil
15 if ENV['TALKATIVE']!=nil
16 puts str
16 puts str
17 end
17 end
18 if ENV['GRADER_LOGGING']!=nil
18 if ENV['GRADER_LOGGING']!=nil
19 log_fname = ENV['GRADER_LOGGING']
19 log_fname = ENV['GRADER_LOGGING']
20 fp = File.open(log_fname,"a")
20 fp = File.open(log_fname,"a")
21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
22 fp.close
22 fp.close
23 end
23 end
24 end
24 end
25
25
26 C_COMPILER = "/usr/bin/gcc"
26 C_COMPILER = "/usr/bin/gcc"
27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
28 PASCAL_COMPILER = "/usr/bin/fpc"
28 PASCAL_COMPILER = "/usr/bin/fpc"
29 JAVA_COMPILER = "/usr/bin/javac"
29 JAVA_COMPILER = "/usr/bin/javac"
30 RUBY_INTERPRETER = "/usr/bin/ruby"
30 RUBY_INTERPRETER = "/usr/bin/ruby"
31 PYTHON_INTERPRETER = "/usr/bin/python3"
31 PYTHON_INTERPRETER = "/usr/bin/python3"
32 PYTHON_CHECKER = "/usr/bin/pyflakes"
32 PYTHON_CHECKER = "/usr/bin/pyflakes"
33 PHP_INTERPRETER = "/usr/bin/php"
33 PHP_INTERPRETER = "/usr/bin/php"
34 HASKELL_COMPILER = "/usr/bin/ghc"
34 HASKELL_COMPILER = "/usr/bin/ghc"
35
35
36 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
36 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
37 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
37 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
38 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
38 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
39 JAVA_OPTIONS = ""
39 JAVA_OPTIONS = ""
40 PYTHON_OPTIONS = ""
40 PYTHON_OPTIONS = ""
41 PHP_OPTIONS = "-l"
41 PHP_OPTIONS = "-l"
42 HASKELL_OPTIONS = ""
42 HASKELL_OPTIONS = ""
43
43
44 # Check for the correct number of arguments. Otherwise, print usage.
44 # Check for the correct number of arguments. Otherwise, print usage.
45 if ARGV.length == 0 or ARGV.length > 4
45 if ARGV.length == 0 or ARGV.length > 4
46 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
46 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
47 puts
47 puts
48 puts "<source-file> is defaulted to \"source\"."
48 puts "<source-file> is defaulted to \"source\"."
49 puts "<output-file> is defaulted to \"a.out\"."
49 puts "<output-file> is defaulted to \"a.out\"."
50 puts "<message-file> is defaulted to \"compiler_message\"."
50 puts "<message-file> is defaulted to \"compiler_message\"."
51 puts
51 puts
52 exit(127)
52 exit(127)
53 end
53 end
54
54
55 PARAMS = {
55 PARAMS = {
56 :source_file => [1,'source'],
56 :source_file => [1,'source'],
57 :output_file => [2,'a.out'],
57 :output_file => [2,'a.out'],
58 :message_file => [3,'compiler_message']
58 :message_file => [3,'compiler_message']
59 }
59 }
60
60
61 params = {}
61 params = {}
62 params[:prog_lang] = ARGV[0]
62 params[:prog_lang] = ARGV[0]
63 PARAMS.each_key do |param_name|
63 PARAMS.each_key do |param_name|
64 index, default = PARAMS[param_name]
64 index, default = PARAMS[param_name]
65 if ARGV.length > index
65 if ARGV.length > index
66 params[param_name] = ARGV[index]
66 params[param_name] = ARGV[index]
67 else
67 else
68 params[param_name] = default
68 params[param_name] = default
69 end
69 end
70 talk "#{param_name}: #{params[param_name]}"
70 talk "#{param_name}: #{params[param_name]}"
71 end
71 end
72
72
73 # Remove any remaining output files or message files.
73 # Remove any remaining output files or message files.
74 if FileTest.exists? params[:output_file]
74 if FileTest.exists? params[:output_file]
75 FileUtils.rm(params[:output_file])
75 FileUtils.rm(params[:output_file])
76 end
76 end
77 if FileTest.exists? params[:message_file]
77 if FileTest.exists? params[:message_file]
78 FileUtils.rm(params[:message_file])
78 FileUtils.rm(params[:message_file])
79 end
79 end
80
80
81 # Check if the source file exists before attempt compiling.
81 # Check if the source file exists before attempt compiling.
82 if !FileTest.exists? params[:source_file]
82 if !FileTest.exists? params[:source_file]
83 talk("ERROR: The source file does not exist!")
83 talk("ERROR: The source file does not exist!")
84 open(params[:message_file],"w") do |f|
84 open(params[:message_file],"w") do |f|
85 f.puts "ERROR: The source file did not exist."
85 f.puts "ERROR: The source file did not exist."
86 end
86 end
87 exit(127)
87 exit(127)
88 end
88 end
89
89
90 if params[:prog_lang]=='cpp'
90 if params[:prog_lang]=='cpp'
91 params[:prog_lang] = 'c++'
91 params[:prog_lang] = 'c++'
92 end
92 end
93
93
94 # Compile.
94 # Compile.
95 case params[:prog_lang]
95 case params[:prog_lang]
96
96
97 when "c"
97 when "c"
98 command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS}"
98 command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS}"
99 system(command, err: params[:message_file])
99 system(command, err: params[:message_file])
100
100
101 when "c++"
101 when "c++"
102 command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS}"
102 command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS}"
103 system(command, err: params[:message_file])
103 system(command, err: params[:message_file])
104
104
105 when "pas"
105 when "pas"
106 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS}"
106 command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS}"
107 system(command,out: params[:message_file])
107 system(command,out: params[:message_file])
108 FileUtils.mv("output", params[:output_file])
108 FileUtils.mv("output", params[:output_file])
109
109
110 when "java"
110 when "java"
111 #rename the file to the public class name
111 #rename the file to the public class name
112
112
113 #get the class name
113 #get the class name
114 classname = 'DUMMY'
114 classname = 'DUMMY'
115 source = Array.new
115 source = Array.new
116 File.foreach(params[:source_file],'r:UTF-8') do |line|
116 File.foreach(params[:source_file],'r:UTF-8') do |line|
117 line.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
117 line.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
118 md = /\s*public\s*class\s*(\w*)/.match(line)
118 md = /\s*public\s*class\s*(\w*)/.match(line)
119 classname=md[1] if md
119 classname=md[1] if md
120 source << line unless line =~ /\s*package\s*\w+\s*\;/
120 source << line unless line =~ /\s*package\s*\w+\s*\;/
121 end
121 end
122 File.open("#{classname}.java","w") do |file|
122 File.open("#{classname}.java","w") do |file|
123 source.each do |s|
123 source.each do |s|
124 file.puts s
124 file.puts s
125 end
125 end
126 end
126 end
127 #system("cp #{params[:source_file]} #{classname}.java")
127 #system("cp #{params[:source_file]} #{classname}.java")
128 command = "#{JAVA_COMPILER} -encoding utf8 #{classname}.java"
128 command = "#{JAVA_COMPILER} -encoding utf8 #{classname}.java"
129 system(command, err: params[:message_file])
129 system(command, err: params[:message_file])
130 if File.exists?(classname + ".class")
130 if File.exists?(classname + ".class")
131 File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
131 File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
132 end
132 end
133 if classname == 'DUMMY'
133 if classname == 'DUMMY'
134 File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
134 File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
135 end
135 end
136
136
137 when "ruby"
137 when "ruby"
138 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
138 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
139 if system(command, err: params[:message_file])
139 if system(command, err: params[:message_file])
140 File.open(params[:output_file],"w") do |out_file|
140 File.open(params[:output_file],"w") do |out_file|
141 out_file.puts "#!#{RUBY_INTERPRETER}"
141 out_file.puts "#!#{RUBY_INTERPRETER}"
142 File.open(params[:source_file],"r").each do |line|
142 File.open(params[:source_file],"r").each do |line|
143 out_file.print line
143 out_file.print line
144 end
144 end
145 end
145 end
146 File.chmod(0755, params[:output_file])
146 File.chmod(0755, params[:output_file])
147 end
147 end
148
148
149 when "python"
149 when "python"
150 - command = "#{PYTHON_CHECKER} #{params[:source_file]}"
150 + #command = "#{PYTHON_CHECKER} #{params[:source_file]}"
151 - if system(command, out: params[:message_file])
151 + #if system(command, out: params[:message_file])
152 #compile to python bytecode
152 #compile to python bytecode
153 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
153 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
154 puts "compile: #{command}"
154 puts "compile: #{command}"
155 - system(command)
155 + system(command, err: params[:message_file])
156 - puts "pwd: " + Dir.pwd
156 + if FileTest.exists?("#{params[:source_file]}c")
157 - Dir.new('.').each {|file| puts file}
157 + puts "pwd: " + Dir.pwd
158 - File.open(params[:output_file],"w") do |out_file|
158 + Dir.new('.').each {|file| puts file}
159 - out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
159 + File.open(params[:output_file],"w") do |out_file|
160 + out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
161 + end
162 + File.chmod(0755, params[:output_file])
163 + FileUtils.cp("#{params[:source_file]}c",params[:output_file])
160 end
164 end
161 - File.chmod(0755, params[:output_file])
165 + #end
162 - FileUtils.cp("#{params[:source_file]}c",params[:output_file])
163 - end
164
166
165 when "php"
167 when "php"
166 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
168 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
167 if system(command, err: params[:message_file])
169 if system(command, err: params[:message_file])
168 File.open(params[:output_file],"w") do |out_file|
170 File.open(params[:output_file],"w") do |out_file|
169 out_file.puts "#!#{PHP_INTERPRETER}"
171 out_file.puts "#!#{PHP_INTERPRETER}"
170 File.open(params[:source_file],"r").each do |line|
172 File.open(params[:source_file],"r").each do |line|
171 out_file.print line
173 out_file.print line
172 end
174 end
173 end
175 end
174 File.chmod(0755, params[:output_file])
176 File.chmod(0755, params[:output_file])
175 end
177 end
176
178
177 when "haskell"
179 when "haskell"
178 command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
180 command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
179 system(command, err: params[:message_file])
181 system(command, err: params[:message_file])
180
182
181 else
183 else
182 talk("ERROR: Invalid language specified!")
184 talk("ERROR: Invalid language specified!")
183 open(params[:message_file],"w") do |f|
185 open(params[:message_file],"w") do |f|
184 f.puts "ERROR: Invalid language specified!"
186 f.puts "ERROR: Invalid language specified!"
185 end
187 end
186 exit(127)
188 exit(127)
187 end
189 end
188
190
189 # Report success or failure.
191 # Report success or failure.
190 if FileTest.exists? params[:output_file]
192 if FileTest.exists? params[:output_file]
191 talk "Compilation was successful!"
193 talk "Compilation was successful!"
192 else
194 else
193 talk "ERROR: Something was wrong during the compilation!"
195 talk "ERROR: Something was wrong during the compilation!"
194 end
196 end
@@ -1,192 +1,192
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 require 'fileutils'
3 require 'fileutils'
4
4
5 def log(str='')
5 def log(str='')
6 if ENV['TALKATIVE']!=nil
6 if ENV['TALKATIVE']!=nil
7 puts str
7 puts str
8 end
8 end
9 if ENV['GRADER_LOGGING']!=nil
9 if ENV['GRADER_LOGGING']!=nil
10 log_fname = ENV['GRADER_LOGGING']
10 log_fname = ENV['GRADER_LOGGING']
11 fp = File.open(log_fname,"a")
11 fp = File.open(log_fname,"a")
12 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
12 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
13 fp.close
13 fp.close
14 end
14 end
15 end
15 end
16
16
17 def extract_time(t)
17 def extract_time(t)
18 # puts "TIME: #{t}"
18 # puts "TIME: #{t}"
19 if (result=/^(.*)r(.*)u(.*)s/.match(t))
19 if (result=/^(.*)r(.*)u(.*)s/.match(t))
20 {:real => result[1], :user => result[2], :sys => result[3]}
20 {:real => result[1], :user => result[2], :sys => result[3]}
21 else
21 else
22 #{:real => 0, :user => 0, :sys => 0}
22 #{:real => 0, :user => 0, :sys => 0}
23 #puts "ERROR READING RUNNING TIME: #{t}"
23 #puts "ERROR READING RUNNING TIME: #{t}"
24 raise "Error reading running time: #{t}"
24 raise "Error reading running time: #{t}"
25 end
25 end
26 end
26 end
27
27
28 def compile_box(source,bin)
28 def compile_box(source,bin)
29 system("g++ #{source} -o #{bin}")
29 system("g++ #{source} -o #{bin}")
30 end
30 end
31
31
32 if ARGV.length < 2 || ARGV.length > 3
32 if ARGV.length < 2 || ARGV.length > 3
33 puts "Usage: run <language> <test-num> [<program-name>]"
33 puts "Usage: run <language> <test-num> [<program-name>]"
34 exit(127)
34 exit(127)
35 end
35 end
36
36
37 language = ARGV[0]
37 language = ARGV[0]
38 test_num = ARGV[1].to_i
38 test_num = ARGV[1].to_i
39 if ARGV.length > 2
39 if ARGV.length > 2
40 program_name = ARGV[2]
40 program_name = ARGV[2]
41 else
41 else
42 program_name = "a.out"
42 program_name = "a.out"
43 end
43 end
44
44
45 problem_home = ENV['PROBLEM_HOME']
45 problem_home = ENV['PROBLEM_HOME']
46 source_name = ENV['SOURCE_NAME']
46 source_name = ENV['SOURCE_NAME']
47 require "#{problem_home}/script/test_dsl.rb"
47 require "#{problem_home}/script/test_dsl.rb"
48 load "#{problem_home}/test_cases/all_tests.cfg"
48 load "#{problem_home}/test_cases/all_tests.cfg"
49 problem = Problem.get_instance
49 problem = Problem.get_instance
50
50
51 sandbox_dir = Dir.getwd
51 sandbox_dir = Dir.getwd
52
52
53 if problem.well_formed? == false
53 if problem.well_formed? == false
54 log "The problem specification is not well formed."
54 log "The problem specification is not well formed."
55 exit(127)
55 exit(127)
56 end
56 end
57
57
58 # Check if the test number is okay.
58 # Check if the test number is okay.
59 if test_num <= 0 || test_num > problem.num_tests
59 if test_num <= 0 || test_num > problem.num_tests
60 log "You have specified a wrong test number."
60 log "You have specified a wrong test number."
61 exit(127)
61 exit(127)
62 end
62 end
63
63
64 #####################################
64 #####################################
65 # Set the relavant file names here. #
65 # Set the relavant file names here. #
66 #####################################
66 #####################################
67
67
68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
69
69
70 #####################################
70 #####################################
71
71
72 time_limit = problem.get_time_limit test_num
72 time_limit = problem.get_time_limit test_num
73 mem_limit = problem.get_mem_limit(test_num) * 1024
73 mem_limit = problem.get_mem_limit(test_num) * 1024
74
74
75 # Copy the input file.
75 # Copy the input file.
76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
77
77
78 # check if box is there, if not, compile it!
78 # check if box is there, if not, compile it!
79 if !File.exists?("#{problem_home}/script/box")
79 if !File.exists?("#{problem_home}/script/box")
80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
81 compile_box("#{problem_home}/script/box.cc",
81 compile_box("#{problem_home}/script/box.cc",
82 "#{problem_home}/script/box")
82 "#{problem_home}/script/box")
83 end
83 end
84
84
85 # Hide PROBLEM_HOME
85 # Hide PROBLEM_HOME
86 ENV['PROBLEM_HOME'] = nil
86 ENV['PROBLEM_HOME'] = nil
87 ENV['SOURCE_NAME'] = nil
87 ENV['SOURCE_NAME'] = nil
88
88
89 # Run the program.
89 # Run the program.
90 #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}"
90 #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}"
91 #
91 #
92
92
93 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
93 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
94 RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe"
94 RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe"
95 - PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -E PYTHONNOUSERSITE=yes"
95 + PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/self/status -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -s getrandom -E PYTHONNOUSERSITE=yes"
96 PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
96 PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
97 HASKELL_OPTION = "-s set_robust_list -s clock_gettime -s sysinfo -s timer_create -s timer_settime -s futex -s timer_delete"
97 HASKELL_OPTION = "-s set_robust_list -s clock_gettime -s sysinfo -s timer_create -s timer_settime -s futex -s timer_delete"
98
98
99 case language
99 case language
100 when "java"
100 when "java"
101 # for java, extract the classname
101 # for java, extract the classname
102 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
102 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
103 classname = 'DUMMY'
103 classname = 'DUMMY'
104 File.open(program_name,"r").each do |line|
104 File.open(program_name,"r").each do |line|
105 classname = line
105 classname = line
106 end
106 end
107 #for java, we cannot really check the memory limit...
107 #for java, we cannot really check the memory limit...
108 run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java -A -Xmx#{mem_limit}k -A #{classname} "
108 run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java -A -Xmx#{mem_limit}k -A #{classname} "
109 when "ruby"
109 when "ruby"
110 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
110 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
111 when "python"
111 when "python"
112 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python3 #{program_name} "
112 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python3 #{program_name} "
113 when "haskell"
113 when "haskell"
114 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{[512 * 1024,mem_limit].max} #{HASKELL_OPTION} -i #{input_file_name} -o output.txt #{program_name} "
114 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{[512 * 1024,mem_limit].max} #{HASKELL_OPTION} -i #{input_file_name} -o output.txt #{program_name} "
115 when "php"
115 when "php"
116 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php -A -d -A memory_limit=#{mem_limit}k -A #{program_name} "
116 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128 * 1024,mem_limit].max} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php -A -d -A memory_limit=#{mem_limit}k -A #{program_name} "
117 else # for c++, pascal, we do the normal checking
117 else # for c++, pascal, we do the normal checking
118 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} "
118 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} "
119 end
119 end
120
120
121
121
122 log "Running test #{test_num}..."
122 log "Running test #{test_num}..."
123 log run_command
123 log run_command
124 log
124 log
125 system(run_command,err: 'run_result')
125 system(run_command,err: 'run_result')
126
126
127 # Restore PROBLEM_HOME
127 # Restore PROBLEM_HOME
128 ENV['PROBLEM_HOME'] = problem_home
128 ENV['PROBLEM_HOME'] = problem_home
129
129
130 # Create the result file.
130 # Create the result file.
131 result_file = File.new("result", "w")
131 result_file = File.new("result", "w")
132 comment_file = File.new("comment", "w")
132 comment_file = File.new("comment", "w")
133
133
134 # Check if the program actually produced any output.
134 # Check if the program actually produced any output.
135 run_result_file = File.new("run_result", "r")
135 run_result_file = File.new("run_result", "r")
136 run_result = run_result_file.readlines
136 run_result = run_result_file.readlines
137 run_result_file.close
137 run_result_file.close
138
138
139 run_stat = run_result[run_result.length-1]
139 run_stat = run_result[run_result.length-1]
140 running_time = extract_time(run_stat)
140 running_time = extract_time(run_stat)
141
141
142 report = lambda{ |status, points, comment|
142 report = lambda{ |status, points, comment|
143 result_file.write status.strip
143 result_file.write status.strip
144 result_file.write "\n"
144 result_file.write "\n"
145 result_file.write points.to_s.strip
145 result_file.write points.to_s.strip
146 result_file.write "\n"
146 result_file.write "\n"
147 result_file.write run_stat.strip
147 result_file.write run_stat.strip
148 result_file.write "\n"
148 result_file.write "\n"
149 result_file.close
149 result_file.close
150 FileUtils.rm "run_result"
150 FileUtils.rm "run_result"
151 # `rm output.txt` --- keep the output
151 # `rm output.txt` --- keep the output
152
152
153 comment_file.write comment
153 comment_file.write comment
154
154
155 # added for debuggin --- jittat
155 # added for debuggin --- jittat
156 comment_file.write "--run-result--\n"
156 comment_file.write "--run-result--\n"
157 run_result.each do |l|
157 run_result.each do |l|
158 comment_file.write l
158 comment_file.write l
159 end
159 end
160
160
161 comment_file.close
161 comment_file.close
162
162
163 log "Done!"
163 log "Done!"
164 exit(0)
164 exit(0)
165 }
165 }
166
166
167
167
168 if run_result[0][0,2] != "OK"
168 if run_result[0][0,2] != "OK"
169 log "There was a runtime error."
169 log "There was a runtime error."
170 report.call(run_result[0], 0, "No comment.\n")
170 report.call(run_result[0], 0, "No comment.\n")
171 end
171 end
172
172
173 if running_time[:user].to_f > time_limit
173 if running_time[:user].to_f > time_limit
174 log "Time limit exceeded."
174 log "Time limit exceeded."
175 report.call("Time limit exceeded", 0, "No comment.\n")
175 report.call("Time limit exceeded", 0, "No comment.\n")
176 end
176 end
177
177
178 # Run 'check' to evaluate the output.
178 # Run 'check' to evaluate the output.
179 #puts "There was no runtime error. Proceed to checking the output."
179 #puts "There was no runtime error. Proceed to checking the output."
180 check_command = "#{problem_home}/script/check #{language} #{test_num}"
180 check_command = "#{problem_home}/script/check #{language} #{test_num}"
181 log "Checking the output..."
181 log "Checking the output..."
182 log check_command
182 log check_command
183 if not system(check_command)
183 if not system(check_command)
184 log "Problem with check script"
184 log "Problem with check script"
185 report.call("Incorrect",0,"Check script error.\n")
185 report.call("Incorrect",0,"Check script error.\n")
186 exit(127)
186 exit(127)
187 end
187 end
188
188
189 check_file = File.new("check_result", "r")
189 check_file = File.new("check_result", "r")
190 check_file_lines = check_file.readlines
190 check_file_lines = check_file.readlines
191
191
192 report.call(check_file_lines[0], check_file_lines[1], "No comment.\n")
192 report.call(check_file_lines[0], check_file_lines[1], "No comment.\n")
You need to be logged in to leave comments. Login now