Description:
add numpy to installer and fix box64 to acknowldge more syscall
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r225:d275da5f0fc5 - - 2 files changed: 13 inserted, 1 deleted

@@ -1,181 +1,181
1 1 #!/bin/sh
2 2
3 3 echo "This script will install and configure Cafe grader."
4 4
5 5 RUBY_VERSION=2.1.2
6 6 echo "This will install Ruby $RUBY_VERSION under RVM"
7 7
8 8 echo "Installing required apts"
9 9
10 10 sudo apt-get update
11 11 sudo apt-get install mysql-server mysql-client \
12 12 g++ gcc apache2 libmysqlclient20 build-essential \
13 13 git-core openssl libreadline6 libreadline6-dev \
14 14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
15 15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
16 16 ncurses-dev automake libtool bison subversion \
17 17 pkg-config curl nodejs unzip pyflakes ruby default-jdk \
18 - libmysqld-dev mercurial python-setuptools python-dev
18 + libmysqld-dev mercurial python-setuptools python-dev python3-numpy
19 19
20 20 echo "Installing RVM"
21 21 curl -k -L https://get.rvm.io | bash -s stable
22 22 source ~/.rvm/scripts/rvm
23 23
24 24 echo "Installing Ruby $RUBY_VERSION in RVM"
25 25
26 26 rvm install $RUBY_VERSION
27 27 rvm use $RUBY_VERSION
28 28
29 29 echo "Fetching Cafe Grader from Git repositories"
30 30
31 31 echo "Fetching web interface"
32 32
33 33 mkdir cafe_grader
34 34 cd cafe_grader
35 35 git clone -q git://github.com/jittat/cafe-grader-web.git web
36 36
37 37 echo "Configuring rails app"
38 38
39 39 cp web/config/application.rb.SAMPLE web/config/application.rb
40 40 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
41 41
42 42 #replace UTC in application.rb with the system timezone
43 43 timezone='UTC'
44 44 if [ -f '/etc/timezone' ]; then
45 45 timezone=\"`cat /etc/timezone`\"
46 46 else
47 47 if [ -f '/etc/sysconfig/clock' ]; then
48 48 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
49 49 fi
50 50 fi
51 51 replace="s!'UTC'!$timezone!g"
52 52 sed -i $replace web/config/application.rb
53 53
54 54 echo "At this point we will need MySQL user and database."
55 55 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
56 56 read ch
57 57
58 58 if [ "$ch" = "n" -o "$ch" = "N" ]
59 59 then
60 60 echo "Please open another terminal and create the user and database for Cafe grader."
61 61 echo "Don't forget to grant access to that database for the user."
62 62 echo "Please have username, password, and database name ready before continue."
63 63 echo
64 64 echo "The following are instructions:"
65 65 echo "1. Run mysql:"
66 66 echo
67 67 echo " mysql -u root -p"
68 68 echo
69 69 echo " if you have just installed mysql, the root password is the one that you have just entered"
70 70 echo "2. Create a new database, a new user, and grant access to grader database:"
71 71 echo
72 72 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
73 73 echo " create database \`DATABASENEME\`;"
74 74 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
75 75 echo
76 76 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
77 77 echo
78 78 echo "Hit enter when ready..."
79 79 read dummy
80 80 fi
81 81
82 82 CAFE_PATH=`pwd`
83 83
84 84 cd web
85 85
86 86 echo "Please provide grader database:"
87 87 read database
88 88
89 89 echo "Please provide grader username:"
90 90 read username
91 91
92 92 echo "Please provide $username password:"
93 93 read password
94 94
95 95 echo "development:" > config/database.yml
96 96 echo " adapter: mysql2" >> config/database.yml
97 97 echo " encoding: utf8" >> config/database.yml
98 98 echo " reconnect: false" >> config/database.yml
99 99 echo " database: $database" >> config/database.yml
100 100 echo " pool: 5" >> config/database.yml
101 101 echo " username: $username" >> config/database.yml
102 102 echo " password: $password" >> config/database.yml
103 103 echo " host: localhost" >> config/database.yml
104 104 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
105 105 echo "" >> config/database.yml
106 106 echo "production:" >> config/database.yml
107 107 echo " adapter: mysql2" >> config/database.yml
108 108 echo " encoding: utf8" >> config/database.yml
109 109 echo " reconnect: false" >> config/database.yml
110 110 echo " database: $database" >> config/database.yml
111 111 echo " pool: 5" >> config/database.yml
112 112 echo " username: $username" >> config/database.yml
113 113 echo " password: $password" >> config/database.yml
114 114 echo " host: localhost" >> config/database.yml
115 115 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
116 116
117 117 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
118 118 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
119 119 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
120 120 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
121 121
122 122 echo "Installing required gems"
123 123 gem install bundler
124 124 bundle install
125 125
126 126 echo "Running rake tasks to initialize database"
127 127
128 128 rake db:migrate
129 129 rake db:seed
130 130
131 131 echo "Running rake tasks to precompile the assets"
132 132
133 133 rake assets:precompile
134 134
135 135 echo "Intalling web interface complete..."
136 136 echo
137 137 echo "Fetching grader"
138 138
139 139 cd ..
140 140
141 141 mkdir judge
142 142 cd judge
143 143 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
144 144 mkdir raw
145 145 mkdir ev-exam
146 146 mkdir ev
147 147 mkdir result
148 148 mkdir log
149 149
150 150 echo "Configuring grader"
151 151
152 152 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
153 153 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
154 154
155 155 # create new environment.rb file
156 156 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
157 157 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
158 158 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
159 159 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
160 160
161 161 # compiling box
162 162 MACHINE_TYPE=`uname -m`
163 163 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
164 164 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
165 165 else
166 166 g++ -o scripts/std-script/box scripts/std-script/box.cc
167 167 fi
168 168
169 169
170 170 cd ..
171 171
172 172 echo "Now you are ready to run cafe grader...."
173 173 echo
174 174 echo "Try:"
175 175 echo
176 176 echo " cd web"
177 177 echo " rails s"
178 178 echo
179 179 echo "and access web at http://localhost:3000/"
180 180 echo "The root username is 'root', its password is 'ioionrails'."
181 181
@@ -222,768 +222,780
222 222 partial_line = 0;
223 223 }
224 224
225 225 /* Report an error of the sandbox itself */
226 226 static void NONRET __attribute__((format(printf,1,2)))
227 227 die(char *msg, ...)
228 228 {
229 229 va_list args;
230 230 va_start(args, msg);
231 231 flush_line();
232 232 char buf[1024];
233 233 vsnprintf(buf, sizeof(buf), msg, args);
234 234 meta_printf("status:XX\nmessage:%s\n", buf);
235 235 fputs(buf, stderr);
236 236 fputc('\n', stderr);
237 237 box_exit(2);
238 238 }
239 239
240 240 /* Report an error of the program inside the sandbox */
241 241 static void NONRET __attribute__((format(printf,1,2)))
242 242 err(char *msg, ...)
243 243 {
244 244 va_list args;
245 245 va_start(args, msg);
246 246 flush_line();
247 247 if (msg[0] && msg[1] && msg[2] == ':' && msg[3] == ' ')
248 248 {
249 249 meta_printf("status:%c%c\n", msg[0], msg[1]);
250 250 msg += 4;
251 251 }
252 252 char buf[1024];
253 253 vsnprintf(buf, sizeof(buf), msg, args);
254 254 meta_printf("message:%s\n", buf);
255 255 fputs(buf, stderr);
256 256 fputc('\n', stderr);
257 257 box_exit(1);
258 258 }
259 259
260 260 /* Write a message, but only if in verbose mode */
261 261 static void __attribute__((format(printf,1,2)))
262 262 msg(char *msg, ...)
263 263 {
264 264 va_list args;
265 265 va_start(args, msg);
266 266 if (verbose)
267 267 {
268 268 int len = strlen(msg);
269 269 if (len > 0)
270 270 partial_line = (msg[len-1] != '\n');
271 271 vfprintf(stderr, msg, args);
272 272 fflush(stderr);
273 273 }
274 274 va_end(args);
275 275 }
276 276
277 277 static void *
278 278 xmalloc(size_t size)
279 279 {
280 280 void *p = malloc(size);
281 281 if (!p)
282 282 die("Out of memory");
283 283 return p;
284 284 }
285 285
286 286 /*** Syscall rules ***/
287 287
288 288 static const char * const syscall_names[] = {
289 289
290 290 /* Syscall table automatically generated by mk-syscall-table */
291 291
292 292 /* 0 */ [ __NR_read ] = "read",
293 293 /* 1 */ [ __NR_write ] = "write",
294 294 /* 2 */ [ __NR_open ] = "open",
295 295 /* 3 */ [ __NR_close ] = "close",
296 296 /* 4 */ [ __NR_stat ] = "stat",
297 297 /* 5 */ [ __NR_fstat ] = "fstat",
298 298 /* 6 */ [ __NR_lstat ] = "lstat",
299 299 /* 7 */ [ __NR_poll ] = "poll",
300 300 /* 8 */ [ __NR_lseek ] = "lseek",
301 301 /* 9 */ [ __NR_mmap ] = "mmap",
302 302 /* 10 */ [ __NR_mprotect ] = "mprotect",
303 303 /* 11 */ [ __NR_munmap ] = "munmap",
304 304 /* 12 */ [ __NR_brk ] = "brk",
305 305 /* 13 */ [ __NR_rt_sigaction ] = "rt_sigaction",
306 306 /* 14 */ [ __NR_rt_sigprocmask ] = "rt_sigprocmask",
307 307 /* 15 */ [ __NR_rt_sigreturn ] = "rt_sigreturn",
308 308 /* 16 */ [ __NR_ioctl ] = "ioctl",
309 309 /* 17 */ [ __NR_pread64 ] = "pread64",
310 310 /* 18 */ [ __NR_pwrite64 ] = "pwrite64",
311 311 /* 19 */ [ __NR_readv ] = "readv",
312 312 /* 20 */ [ __NR_writev ] = "writev",
313 313 /* 21 */ [ __NR_access ] = "access",
314 314 /* 22 */ [ __NR_pipe ] = "pipe",
315 315 /* 23 */ [ __NR_select ] = "select",
316 316 /* 24 */ [ __NR_sched_yield ] = "sched_yield",
317 317 /* 25 */ [ __NR_mremap ] = "mremap",
318 318 /* 26 */ [ __NR_msync ] = "msync",
319 319 /* 27 */ [ __NR_mincore ] = "mincore",
320 320 /* 28 */ [ __NR_madvise ] = "madvise",
321 321 /* 29 */ [ __NR_shmget ] = "shmget",
322 322 /* 30 */ [ __NR_shmat ] = "shmat",
323 323 /* 31 */ [ __NR_shmctl ] = "shmctl",
324 324 /* 32 */ [ __NR_dup ] = "dup",
325 325 /* 33 */ [ __NR_dup2 ] = "dup2",
326 326 /* 34 */ [ __NR_pause ] = "pause",
327 327 /* 35 */ [ __NR_nanosleep ] = "nanosleep",
328 328 /* 36 */ [ __NR_getitimer ] = "getitimer",
329 329 /* 37 */ [ __NR_alarm ] = "alarm",
330 330 /* 38 */ [ __NR_setitimer ] = "setitimer",
331 331 /* 39 */ [ __NR_getpid ] = "getpid",
332 332 /* 40 */ [ __NR_sendfile ] = "sendfile",
333 333 /* 41 */ [ __NR_socket ] = "socket",
334 334 /* 42 */ [ __NR_connect ] = "connect",
335 335 /* 43 */ [ __NR_accept ] = "accept",
336 336 /* 44 */ [ __NR_sendto ] = "sendto",
337 337 /* 45 */ [ __NR_recvfrom ] = "recvfrom",
338 338 /* 46 */ [ __NR_sendmsg ] = "sendmsg",
339 339 /* 47 */ [ __NR_recvmsg ] = "recvmsg",
340 340 /* 48 */ [ __NR_shutdown ] = "shutdown",
341 341 /* 49 */ [ __NR_bind ] = "bind",
342 342 /* 50 */ [ __NR_listen ] = "listen",
343 343 /* 51 */ [ __NR_getsockname ] = "getsockname",
344 344 /* 52 */ [ __NR_getpeername ] = "getpeername",
345 345 /* 53 */ [ __NR_socketpair ] = "socketpair",
346 346 /* 54 */ [ __NR_setsockopt ] = "setsockopt",
347 347 /* 55 */ [ __NR_getsockopt ] = "getsockopt",
348 348 /* 56 */ [ __NR_clone ] = "clone",
349 349 /* 57 */ [ __NR_fork ] = "fork",
350 350 /* 58 */ [ __NR_vfork ] = "vfork",
351 351 /* 59 */ [ __NR_execve ] = "execve",
352 352 /* 60 */ [ __NR_exit ] = "exit",
353 353 /* 61 */ [ __NR_wait4 ] = "wait4",
354 354 /* 62 */ [ __NR_kill ] = "kill",
355 355 /* 63 */ [ __NR_uname ] = "uname",
356 356 /* 64 */ [ __NR_semget ] = "semget",
357 357 /* 65 */ [ __NR_semop ] = "semop",
358 358 /* 66 */ [ __NR_semctl ] = "semctl",
359 359 /* 67 */ [ __NR_shmdt ] = "shmdt",
360 360 /* 68 */ [ __NR_msgget ] = "msgget",
361 361 /* 69 */ [ __NR_msgsnd ] = "msgsnd",
362 362 /* 70 */ [ __NR_msgrcv ] = "msgrcv",
363 363 /* 71 */ [ __NR_msgctl ] = "msgctl",
364 364 /* 72 */ [ __NR_fcntl ] = "fcntl",
365 365 /* 73 */ [ __NR_flock ] = "flock",
366 366 /* 74 */ [ __NR_fsync ] = "fsync",
367 367 /* 75 */ [ __NR_fdatasync ] = "fdatasync",
368 368 /* 76 */ [ __NR_truncate ] = "truncate",
369 369 /* 77 */ [ __NR_ftruncate ] = "ftruncate",
370 370 /* 78 */ [ __NR_getdents ] = "getdents",
371 371 /* 79 */ [ __NR_getcwd ] = "getcwd",
372 372 /* 80 */ [ __NR_chdir ] = "chdir",
373 373 /* 81 */ [ __NR_fchdir ] = "fchdir",
374 374 /* 82 */ [ __NR_rename ] = "rename",
375 375 /* 83 */ [ __NR_mkdir ] = "mkdir",
376 376 /* 84 */ [ __NR_rmdir ] = "rmdir",
377 377 /* 85 */ [ __NR_creat ] = "creat",
378 378 /* 86 */ [ __NR_link ] = "link",
379 379 /* 87 */ [ __NR_unlink ] = "unlink",
380 380 /* 88 */ [ __NR_symlink ] = "symlink",
381 381 /* 89 */ [ __NR_readlink ] = "readlink",
382 382 /* 90 */ [ __NR_chmod ] = "chmod",
383 383 /* 91 */ [ __NR_fchmod ] = "fchmod",
384 384 /* 92 */ [ __NR_chown ] = "chown",
385 385 /* 93 */ [ __NR_fchown ] = "fchown",
386 386 /* 94 */ [ __NR_lchown ] = "lchown",
387 387 /* 95 */ [ __NR_umask ] = "umask",
388 388 /* 96 */ [ __NR_gettimeofday ] = "gettimeofday",
389 389 /* 97 */ [ __NR_getrlimit ] = "getrlimit",
390 390 /* 98 */ [ __NR_getrusage ] = "getrusage",
391 391 /* 99 */ [ __NR_sysinfo ] = "sysinfo",
392 392 /* 100 */ [ __NR_times ] = "times",
393 393 /* 101 */ [ __NR_ptrace ] = "ptrace",
394 394 /* 102 */ [ __NR_getuid ] = "getuid",
395 395 /* 103 */ [ __NR_syslog ] = "syslog",
396 396 /* 104 */ [ __NR_getgid ] = "getgid",
397 397 /* 105 */ [ __NR_setuid ] = "setuid",
398 398 /* 106 */ [ __NR_setgid ] = "setgid",
399 399 /* 107 */ [ __NR_geteuid ] = "geteuid",
400 400 /* 108 */ [ __NR_getegid ] = "getegid",
401 401 /* 109 */ [ __NR_setpgid ] = "setpgid",
402 402 /* 110 */ [ __NR_getppid ] = "getppid",
403 403 /* 111 */ [ __NR_getpgrp ] = "getpgrp",
404 404 /* 112 */ [ __NR_setsid ] = "setsid",
405 405 /* 113 */ [ __NR_setreuid ] = "setreuid",
406 406 /* 114 */ [ __NR_setregid ] = "setregid",
407 407 /* 115 */ [ __NR_getgroups ] = "getgroups",
408 408 /* 116 */ [ __NR_setgroups ] = "setgroups",
409 409 /* 117 */ [ __NR_setresuid ] = "setresuid",
410 410 /* 118 */ [ __NR_getresuid ] = "getresuid",
411 411 /* 119 */ [ __NR_setresgid ] = "setresgid",
412 412 /* 120 */ [ __NR_getresgid ] = "getresgid",
413 413 /* 121 */ [ __NR_getpgid ] = "getpgid",
414 414 /* 122 */ [ __NR_setfsuid ] = "setfsuid",
415 415 /* 123 */ [ __NR_setfsgid ] = "setfsgid",
416 416 /* 124 */ [ __NR_getsid ] = "getsid",
417 417 /* 125 */ [ __NR_capget ] = "capget",
418 418 /* 126 */ [ __NR_capset ] = "capset",
419 419 /* 127 */ [ __NR_rt_sigpending ] = "rt_sigpending",
420 420 /* 128 */ [ __NR_rt_sigtimedwait ] = "rt_sigtimedwait",
421 421 /* 129 */ [ __NR_rt_sigqueueinfo ] = "rt_sigqueueinfo",
422 422 /* 130 */ [ __NR_rt_sigsuspend ] = "rt_sigsuspend",
423 423 /* 131 */ [ __NR_sigaltstack ] = "sigaltstack",
424 424 /* 132 */ [ __NR_utime ] = "utime",
425 425 /* 133 */ [ __NR_mknod ] = "mknod",
426 426 /* 134 */ [ __NR_uselib ] = "uselib",
427 427 /* 135 */ [ __NR_personality ] = "personality",
428 428 /* 136 */ [ __NR_ustat ] = "ustat",
429 429 /* 137 */ [ __NR_statfs ] = "statfs",
430 430 /* 138 */ [ __NR_fstatfs ] = "fstatfs",
431 431 /* 139 */ [ __NR_sysfs ] = "sysfs",
432 432 /* 140 */ [ __NR_getpriority ] = "getpriority",
433 433 /* 141 */ [ __NR_setpriority ] = "setpriority",
434 434 /* 142 */ [ __NR_sched_setparam ] = "sched_setparam",
435 435 /* 143 */ [ __NR_sched_getparam ] = "sched_getparam",
436 436 /* 144 */ [ __NR_sched_setscheduler ] = "sched_setscheduler",
437 437 /* 145 */ [ __NR_sched_getscheduler ] = "sched_getscheduler",
438 438 /* 146 */ [ __NR_sched_get_priority_max ] = "sched_get_priority_max",
439 439 /* 147 */ [ __NR_sched_get_priority_min ] = "sched_get_priority_min",
440 440 /* 148 */ [ __NR_sched_rr_get_interval ] = "sched_rr_get_interval",
441 441 /* 149 */ [ __NR_mlock ] = "mlock",
442 442 /* 150 */ [ __NR_munlock ] = "munlock",
443 443 /* 151 */ [ __NR_mlockall ] = "mlockall",
444 444 /* 152 */ [ __NR_munlockall ] = "munlockall",
445 445 /* 153 */ [ __NR_vhangup ] = "vhangup",
446 446 /* 154 */ [ __NR_modify_ldt ] = "modify_ldt",
447 447 /* 155 */ [ __NR_pivot_root ] = "pivot_root",
448 448 /* 156 */ [ __NR__sysctl ] = "_sysctl",
449 449 /* 157 */ [ __NR_prctl ] = "prctl",
450 450 /* 158 */ [ __NR_arch_prctl ] = "arch_prctl",
451 451 /* 159 */ [ __NR_adjtimex ] = "adjtimex",
452 452 /* 160 */ [ __NR_setrlimit ] = "setrlimit",
453 453 /* 161 */ [ __NR_chroot ] = "chroot",
454 454 /* 162 */ [ __NR_sync ] = "sync",
455 455 /* 163 */ [ __NR_acct ] = "acct",
456 456 /* 164 */ [ __NR_settimeofday ] = "settimeofday",
457 457 /* 165 */ [ __NR_mount ] = "mount",
458 458 /* 166 */ [ __NR_umount2 ] = "umount2",
459 459 /* 167 */ [ __NR_swapon ] = "swapon",
460 460 /* 168 */ [ __NR_swapoff ] = "swapoff",
461 461 /* 169 */ [ __NR_reboot ] = "reboot",
462 462 /* 170 */ [ __NR_sethostname ] = "sethostname",
463 463 /* 171 */ [ __NR_setdomainname ] = "setdomainname",
464 464 /* 172 */ [ __NR_iopl ] = "iopl",
465 465 /* 173 */ [ __NR_ioperm ] = "ioperm",
466 466 /* 174 */ [ __NR_create_module ] = "create_module",
467 467 /* 175 */ [ __NR_init_module ] = "init_module",
468 468 /* 176 */ [ __NR_delete_module ] = "delete_module",
469 469 /* 177 */ [ __NR_get_kernel_syms ] = "get_kernel_syms",
470 470 /* 178 */ [ __NR_query_module ] = "query_module",
471 471 /* 179 */ [ __NR_quotactl ] = "quotactl",
472 472 /* 180 */ [ __NR_nfsservctl ] = "nfsservctl",
473 473 /* 181 */ [ __NR_getpmsg ] = "getpmsg",
474 474 /* 182 */ [ __NR_putpmsg ] = "putpmsg",
475 475 /* 183 */ [ __NR_afs_syscall ] = "afs_syscall",
476 476 /* 184 */ [ __NR_tuxcall ] = "tuxcall",
477 477 /* 185 */ [ __NR_security ] = "security",
478 478 /* 186 */ [ __NR_gettid ] = "gettid",
479 479 /* 187 */ [ __NR_readahead ] = "readahead",
480 480 /* 188 */ [ __NR_setxattr ] = "setxattr",
481 481 /* 189 */ [ __NR_lsetxattr ] = "lsetxattr",
482 482 /* 190 */ [ __NR_fsetxattr ] = "fsetxattr",
483 483 /* 191 */ [ __NR_getxattr ] = "getxattr",
484 484 /* 192 */ [ __NR_lgetxattr ] = "lgetxattr",
485 485 /* 193 */ [ __NR_fgetxattr ] = "fgetxattr",
486 486 /* 194 */ [ __NR_listxattr ] = "listxattr",
487 487 /* 195 */ [ __NR_llistxattr ] = "llistxattr",
488 488 /* 196 */ [ __NR_flistxattr ] = "flistxattr",
489 489 /* 197 */ [ __NR_removexattr ] = "removexattr",
490 490 /* 198 */ [ __NR_lremovexattr ] = "lremovexattr",
491 491 /* 199 */ [ __NR_fremovexattr ] = "fremovexattr",
492 492 /* 200 */ [ __NR_tkill ] = "tkill",
493 493 /* 201 */ [ __NR_time ] = "time",
494 494 /* 202 */ [ __NR_futex ] = "futex",
495 495 /* 203 */ [ __NR_sched_setaffinity ] = "sched_setaffinity",
496 496 /* 204 */ [ __NR_sched_getaffinity ] = "sched_getaffinity",
497 497 /* 205 */ [ __NR_set_thread_area ] = "set_thread_area",
498 498 /* 206 */ [ __NR_io_setup ] = "io_setup",
499 499 /* 207 */ [ __NR_io_destroy ] = "io_destroy",
500 500 /* 208 */ [ __NR_io_getevents ] = "io_getevents",
501 501 /* 209 */ [ __NR_io_submit ] = "io_submit",
502 502 /* 210 */ [ __NR_io_cancel ] = "io_cancel",
503 503 /* 211 */ [ __NR_get_thread_area ] = "get_thread_area",
504 504 /* 212 */ [ __NR_lookup_dcookie ] = "lookup_dcookie",
505 505 /* 213 */ [ __NR_epoll_create ] = "epoll_create",
506 506 /* 214 */ [ __NR_epoll_ctl_old ] = "epoll_ctl_old",
507 507 /* 215 */ [ __NR_epoll_wait_old ] = "epoll_wait_old",
508 508 /* 216 */ [ __NR_remap_file_pages ] = "remap_file_pages",
509 509 /* 217 */ [ __NR_getdents64 ] = "getdents64",
510 510 /* 218 */ [ __NR_set_tid_address ] = "set_tid_address",
511 511 /* 219 */ [ __NR_restart_syscall ] = "restart_syscall",
512 512 /* 220 */ [ __NR_semtimedop ] = "semtimedop",
513 513 /* 221 */ [ __NR_fadvise64 ] = "fadvise64",
514 514 /* 222 */ [ __NR_timer_create ] = "timer_create",
515 515 /* 223 */ [ __NR_timer_settime ] = "timer_settime",
516 516 /* 224 */ [ __NR_timer_gettime ] = "timer_gettime",
517 517 /* 225 */ [ __NR_timer_getoverrun ] = "timer_getoverrun",
518 518 /* 226 */ [ __NR_timer_delete ] = "timer_delete",
519 519 /* 227 */ [ __NR_clock_settime ] = "clock_settime",
520 520 /* 228 */ [ __NR_clock_gettime ] = "clock_gettime",
521 521 /* 229 */ [ __NR_clock_getres ] = "clock_getres",
522 522 /* 230 */ [ __NR_clock_nanosleep ] = "clock_nanosleep",
523 523 /* 231 */ [ __NR_exit_group ] = "exit_group",
524 524 /* 232 */ [ __NR_epoll_wait ] = "epoll_wait",
525 525 /* 233 */ [ __NR_epoll_ctl ] = "epoll_ctl",
526 526 /* 234 */ [ __NR_tgkill ] = "tgkill",
527 527 /* 235 */ [ __NR_utimes ] = "utimes",
528 528 /* 236 */ [ __NR_vserver ] = "vserver",
529 529 /* 237 */ [ __NR_mbind ] = "mbind",
530 530 /* 238 */ [ __NR_set_mempolicy ] = "set_mempolicy",
531 531 /* 239 */ [ __NR_get_mempolicy ] = "get_mempolicy",
532 532 /* 240 */ [ __NR_mq_open ] = "mq_open",
533 533 /* 241 */ [ __NR_mq_unlink ] = "mq_unlink",
534 534 /* 242 */ [ __NR_mq_timedsend ] = "mq_timedsend",
535 535 /* 243 */ [ __NR_mq_timedreceive ] = "mq_timedreceive",
536 536 /* 244 */ [ __NR_mq_notify ] = "mq_notify",
537 537 /* 245 */ [ __NR_mq_getsetattr ] = "mq_getsetattr",
538 538 /* 246 */ [ __NR_kexec_load ] = "kexec_load",
539 539 /* 247 */ [ __NR_waitid ] = "waitid",
540 540 /* 248 */ [ __NR_add_key ] = "add_key",
541 541 /* 249 */ [ __NR_request_key ] = "request_key",
542 542 /* 250 */ [ __NR_keyctl ] = "keyctl",
543 543 /* 251 */ [ __NR_ioprio_set ] = "ioprio_set",
544 544 /* 252 */ [ __NR_ioprio_get ] = "ioprio_get",
545 545 /* 253 */ [ __NR_inotify_init ] = "inotify_init",
546 546 /* 254 */ [ __NR_inotify_add_watch ] = "inotify_add_watch",
547 547 /* 255 */ [ __NR_inotify_rm_watch ] = "inotify_rm_watch",
548 548 /* 256 */ [ __NR_migrate_pages ] = "migrate_pages",
549 549 /* 257 */ [ __NR_openat ] = "openat",
550 550 /* 258 */ [ __NR_mkdirat ] = "mkdirat",
551 551 /* 259 */ [ __NR_mknodat ] = "mknodat",
552 552 /* 260 */ [ __NR_fchownat ] = "fchownat",
553 553 /* 261 */ [ __NR_futimesat ] = "futimesat",
554 554 /* 262 */ [ __NR_newfstatat ] = "newfstatat",
555 555 /* 263 */ [ __NR_unlinkat ] = "unlinkat",
556 556 /* 264 */ [ __NR_renameat ] = "renameat",
557 557 /* 265 */ [ __NR_linkat ] = "linkat",
558 558 /* 266 */ [ __NR_symlinkat ] = "symlinkat",
559 559 /* 267 */ [ __NR_readlinkat ] = "readlinkat",
560 560 /* 268 */ [ __NR_fchmodat ] = "fchmodat",
561 561 /* 269 */ [ __NR_faccessat ] = "faccessat",
562 562 /* 270 */ [ __NR_pselect6 ] = "pselect6",
563 563 /* 271 */ [ __NR_ppoll ] = "ppoll",
564 564 /* 272 */ [ __NR_unshare ] = "unshare",
565 565 /* 273 */ [ __NR_set_robust_list ] = "set_robust_list",
566 566 /* 274 */ [ __NR_get_robust_list ] = "get_robust_list",
567 567 /* 275 */ [ __NR_splice ] = "splice",
568 568 /* 276 */ [ __NR_tee ] = "tee",
569 569 /* 277 */ [ __NR_sync_file_range ] = "sync_file_range",
570 570 /* 278 */ [ __NR_vmsplice ] = "vmsplice",
571 571 /* 279 */ [ __NR_move_pages ] = "move_pages",
572 572 /* 280 */ [ __NR_utimensat ] = "utimensat",
573 573 /* 281 */ [ __NR_epoll_pwait ] = "epoll_pwait",
574 574 /* 282 */ [ __NR_signalfd ] = "signalfd",
575 575 /* 283 */ [ __NR_timerfd_create ] = "timerfd_create",
576 576 /* 284 */ [ __NR_eventfd ] = "eventfd",
577 577 /* 285 */ [ __NR_fallocate ] = "fallocate",
578 578 /* 286 */ [ __NR_timerfd_settime ] = "timerfd_settime",
579 579 /* 287 */ [ __NR_timerfd_gettime ] = "timerfd_gettime",
580 580 /* 288 */ [ __NR_accept4 ] = "accept4",
581 581 /* 289 */ [ __NR_signalfd4 ] = "signalfd4",
582 582 /* 290 */ [ __NR_eventfd2 ] = "eventfd2",
583 583 /* 291 */ [ __NR_epoll_create1 ] = "epoll_create1",
584 584 /* 292 */ [ __NR_dup3 ] = "dup3",
585 585 /* 293 */ [ __NR_pipe2 ] = "pipe2",
586 586 /* 294 */ [ __NR_inotify_init1 ] = "inotify_init1",
587 587 /* 295 */ [ __NR_preadv ] = "preadv",
588 588 /* 296 */ [ __NR_pwritev ] = "pwritev",
589 589 /* 297 */ [ __NR_rt_tgsigqueueinfo ] = "rt_tgsigqueueinfo",
590 590 /* 298 */ [ __NR_perf_event_open ] = "perf_event_open",
591 591 /* 299 */ [ __NR_recvmmsg ] = "recvmmsg",
592 592 /* 300 */ [ __NR_fanotify_init ] = "fanotify_init",
593 593 /* 301 */ [ __NR_fanotify_mark ] = "fanotify_mark",
594 594 /* 302 */ [ __NR_prlimit64 ] = "prlimit64",
595 595 /* 303 */ [ __NR_name_to_handle_at ] = "name_to_handle_at",
596 596 /* 304 */ [ __NR_open_by_handle_at ] = "open_by_handle_at",
597 597 /* 305 */ [ __NR_clock_adjtime ] = "clock_adjtime",
598 598 /* 306 */ [ __NR_syncfs ] = "syncfs",
599 599 /* 307 */ [ __NR_sendmmsg ] = "sendmmsg",
600 600 /* 308 */ [ __NR_setns ] = "setns",
601 601 /* 309 */ [ __NR_getcpu ] = "getcpu",
602 602 /* 310 */ [ __NR_process_vm_readv ] = "process_vm_readv",
603 603 /* 311 */ [ __NR_process_vm_writev ] = "process_vm_writev",
604 604 /* 312 */ [ __NR_kcmp ] = "kcmp",
605 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 619 #define NUM_SYSCALLS ARRAY_SIZE(syscall_names)
608 620 #define NUM_ACTIONS (NUM_SYSCALLS+64)
609 621
610 622 enum action {
611 623 A_DEFAULT, // Use the default action
612 624 A_NO, // Always forbid
613 625 A_YES, // Always permit
614 626 A_FILENAME, // Permit if arg1 is a known filename
615 627 A_ACTION_MASK = 15,
616 628 A_NO_RETVAL = 32, // Does not return a value
617 629 A_SAMPLE_MEM = 64, // Sample memory usage before the syscall
618 630 A_LIBERAL = 128, // Valid only in liberal mode
619 631 // Must fit in a unsigned char
620 632 };
621 633
622 634 static unsigned char syscall_action[NUM_ACTIONS] = {
623 635 #define S(x) [__NR_##x]
624 636
625 637 // Syscalls permitted for specific file names
626 638 S(open) = A_FILENAME,
627 639 S(creat) = A_FILENAME,
628 640 S(unlink) = A_FILENAME,
629 641 S(access) = A_FILENAME,
630 642 S(truncate) = A_FILENAME,
631 643 S(stat) = A_FILENAME,
632 644 S(lstat) = A_FILENAME,
633 645 S(readlink) = A_FILENAME,
634 646 #ifndef CONFIG_BOX_USER_AMD64
635 647 S(oldstat) = A_FILENAME,
636 648 S(oldlstat) = A_FILENAME,
637 649 S(truncate64) = A_FILENAME,
638 650 S(stat64) = A_FILENAME,
639 651 S(lstat64) = A_FILENAME,
640 652 #endif
641 653
642 654 // Syscalls permitted always
643 655 S(exit) = A_YES | A_SAMPLE_MEM,
644 656 S(read) = A_YES,
645 657 S(write) = A_YES,
646 658 S(close) = A_YES,
647 659 S(lseek) = A_YES,
648 660 S(getpid) = A_YES,
649 661 S(getuid) = A_YES,
650 662 S(dup) = A_YES,
651 663 S(brk) = A_YES,
652 664 S(getgid) = A_YES,
653 665 S(geteuid) = A_YES,
654 666 S(getegid) = A_YES,
655 667 S(dup2) = A_YES,
656 668 S(ftruncate) = A_YES,
657 669 S(fstat) = A_YES,
658 670 S(personality) = A_YES,
659 671 S(readv) = A_YES,
660 672 S(writev) = A_YES,
661 673 S(getresuid) = A_YES,
662 674 #ifdef __NR_pread64
663 675 S(pread64) = A_YES,
664 676 S(pwrite64) = A_YES,
665 677 #else
666 678 S(pread) = A_YES,
667 679 S(pwrite) = A_YES,
668 680 #endif
669 681 S(fcntl) = A_YES,
670 682 S(mmap) = A_YES,
671 683 S(munmap) = A_YES,
672 684 S(ioctl) = A_YES,
673 685 S(uname) = A_YES,
674 686 S(gettid) = A_YES,
675 687 S(set_thread_area) = A_YES,
676 688 S(get_thread_area) = A_YES,
677 689 S(set_tid_address) = A_YES,
678 690 S(exit_group) = A_YES | A_SAMPLE_MEM,
679 691 #ifdef CONFIG_BOX_USER_AMD64
680 692 S(arch_prctl) = A_YES,
681 693 #else
682 694 S(oldfstat) = A_YES,
683 695 S(ftruncate64) = A_YES,
684 696 S(_llseek) = A_YES,
685 697 S(fstat64) = A_YES,
686 698 S(fcntl64) = A_YES,
687 699 S(mmap2) = A_YES,
688 700 #endif
689 701
690 702 // Syscalls permitted only in liberal mode
691 703 S(time) = A_YES | A_LIBERAL,
692 704 S(alarm) = A_YES | A_LIBERAL,
693 705 S(pause) = A_YES | A_LIBERAL,
694 706 S(fchmod) = A_YES | A_LIBERAL,
695 707 S(getrlimit) = A_YES | A_LIBERAL,
696 708 S(getrusage) = A_YES | A_LIBERAL,
697 709 S(gettimeofday) = A_YES | A_LIBERAL,
698 710 S(select) = A_YES | A_LIBERAL,
699 711 S(setitimer) = A_YES | A_LIBERAL,
700 712 S(getitimer) = A_YES | A_LIBERAL,
701 713 S(mprotect) = A_YES | A_LIBERAL,
702 714 S(getdents) = A_YES | A_LIBERAL,
703 715 S(getdents64) = A_YES | A_LIBERAL,
704 716 S(fdatasync) = A_YES | A_LIBERAL,
705 717 S(mremap) = A_YES | A_LIBERAL,
706 718 S(poll) = A_YES | A_LIBERAL,
707 719 S(getcwd) = A_YES | A_LIBERAL,
708 720 S(nanosleep) = A_YES | A_LIBERAL,
709 721 S(rt_sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
710 722 S(rt_sigaction) = A_YES | A_LIBERAL,
711 723 S(rt_sigprocmask) = A_YES | A_LIBERAL,
712 724 S(rt_sigpending) = A_YES | A_LIBERAL,
713 725 S(rt_sigtimedwait) = A_YES | A_LIBERAL,
714 726 S(rt_sigqueueinfo) = A_YES | A_LIBERAL,
715 727 S(rt_sigsuspend) = A_YES | A_LIBERAL,
716 728 S(_sysctl) = A_YES | A_LIBERAL,
717 729 #ifndef CONFIG_BOX_USER_AMD64
718 730 S(sigaction) = A_YES | A_LIBERAL,
719 731 S(sgetmask) = A_YES | A_LIBERAL,
720 732 S(ssetmask) = A_YES | A_LIBERAL,
721 733 S(sigsuspend) = A_YES | A_LIBERAL,
722 734 S(sigpending) = A_YES | A_LIBERAL,
723 735 S(sigreturn) = A_YES | A_LIBERAL | A_NO_RETVAL,
724 736 S(sigprocmask) = A_YES | A_LIBERAL,
725 737 S(ugetrlimit) = A_YES | A_LIBERAL,
726 738 S(readdir) = A_YES | A_LIBERAL,
727 739 S(signal) = A_YES | A_LIBERAL,
728 740 S(_newselect) = A_YES | A_LIBERAL,
729 741 #endif
730 742
731 743 #undef S
732 744 };
733 745
734 746 static const char *
735 747 syscall_name(unsigned int id, char *buf)
736 748 {
737 749 if (id < NUM_SYSCALLS && syscall_names[id])
738 750 return syscall_names[id];
739 751 else
740 752 {
741 753 sprintf(buf, "#%d", id);
742 754 return buf;
743 755 }
744 756 }
745 757
746 758 static int
747 759 syscall_by_name(char *name)
748 760 {
749 761 for (unsigned int i=0; i<NUM_SYSCALLS; i++)
750 762 if (syscall_names[i] && !strcmp(syscall_names[i], name))
751 763 return i;
752 764 if (name[0] == '#')
753 765 name++;
754 766 if (!*name)
755 767 return -1;
756 768 char *ep;
757 769 unsigned long l = strtoul(name, &ep, 0);
758 770 if (*ep)
759 771 return -1;
760 772 if (l >= NUM_ACTIONS)
761 773 return NUM_ACTIONS;
762 774 return l;
763 775 }
764 776
765 777 static int
766 778 set_syscall_action(char *a)
767 779 {
768 780 char *sep = strchr(a, '=');
769 781 enum action act = A_YES;
770 782 if (sep)
771 783 {
772 784 *sep++ = 0;
773 785 if (!strcmp(sep, "yes"))
774 786 act = A_YES;
775 787 else if (!strcmp(sep, "no"))
776 788 act = A_NO;
777 789 else if (!strcmp(sep, "file"))
778 790 act = A_FILENAME;
779 791 else
780 792 return 0;
781 793 }
782 794
783 795 int sys = syscall_by_name(a);
784 796 if (sys < 0)
785 797 die("Unknown syscall `%s'", a);
786 798 if (sys >= NUM_ACTIONS)
787 799 die("Syscall `%s' out of range", a);
788 800 syscall_action[sys] = act;
789 801 return 1;
790 802 }
791 803
792 804 /*** Path rules ***/
793 805
794 806 struct path_rule {
795 807 char *path;
796 808 enum action action;
797 809 struct path_rule *next;
798 810 };
799 811
800 812 static struct path_rule default_path_rules[] = {
801 813 { "/etc/", A_YES },
802 814 { "/lib/", A_YES },
803 815 { "/usr/lib/", A_YES },
804 816 { "/opt/lib/", A_YES },
805 817 { "/usr/share/zoneinfo/", A_YES },
806 818 { "/usr/share/locale/", A_YES },
807 819 { "/dev/null", A_YES },
808 820 { "/dev/zero", A_YES },
809 821 { "/proc/meminfo", A_YES },
810 822 { "/proc/self/stat", A_YES },
811 823 { "/proc/self/exe", A_YES }, // Needed by FPC 2.0.x runtime
812 824 { "/proc/self/maps", A_YES }, // Needed by glibc when it reports arena corruption
813 825 };
814 826
815 827 static struct path_rule *user_path_rules;
816 828 static struct path_rule **last_path_rule = &user_path_rules;
817 829
818 830 static int
819 831 set_path_action(char *a)
820 832 {
821 833 char *sep = strchr(a, '=');
822 834 enum action act = A_YES;
823 835 if (sep)
824 836 {
825 837 *sep++ = 0;
826 838 if (!strcmp(sep, "yes"))
827 839 act = A_YES;
828 840 else if (!strcmp(sep, "no"))
829 841 act = A_NO;
830 842 else
831 843 return 0;
832 844 }
833 845
834 846 struct path_rule *r = xmalloc(sizeof(*r) + strlen(a) + 1);
835 847 r->path = (char *)(r+1);
836 848 strcpy(r->path, a);
837 849 r->action = act;
838 850 r->next = NULL;
839 851 *last_path_rule = r;
840 852 last_path_rule = &r->next;
841 853 return 1;
842 854 }
843 855
844 856 static enum action
845 857 match_path_rule(struct path_rule *r, char *path)
846 858 {
847 859 char *rr = r->path;
848 860 while (*rr)
849 861 if (*rr++ != *path++)
850 862 {
851 863 if (rr[-1] == '/' && !path[-1])
852 864 break;
853 865 return A_DEFAULT;
854 866 }
855 867 if (rr > r->path && rr[-1] != '/' && *path)
856 868 return A_DEFAULT;
857 869 return r->action;
858 870 }
859 871
860 872 /*** Environment rules ***/
861 873
862 874 struct env_rule {
863 875 char *var; // Variable to match
864 876 char *val; // ""=clear, NULL=inherit
865 877 int var_len;
866 878 struct env_rule *next;
867 879 };
868 880
869 881 static struct env_rule *first_env_rule;
870 882 static struct env_rule **last_env_rule = &first_env_rule;
871 883
872 884 static struct env_rule default_env_rules[] = {
873 885 { "LIBC_FATAL_STDERR_", "1" }
874 886 };
875 887
876 888 static int
877 889 set_env_action(char *a0)
878 890 {
879 891 struct env_rule *r = xmalloc(sizeof(*r) + strlen(a0) + 1);
880 892 char *a = (char *)(r+1);
881 893 strcpy(a, a0);
882 894
883 895 char *sep = strchr(a, '=');
884 896 if (sep == a)
885 897 return 0;
886 898 r->var = a;
887 899 if (sep)
888 900 {
889 901 *sep++ = 0;
890 902 r->val = sep;
891 903 }
892 904 else
893 905 r->val = NULL;
894 906 *last_env_rule = r;
895 907 last_env_rule = &r->next;
896 908 r->next = NULL;
897 909 return 1;
898 910 }
899 911
900 912 static int
901 913 match_env_var(char *env_entry, struct env_rule *r)
902 914 {
903 915 if (strncmp(env_entry, r->var, r->var_len))
904 916 return 0;
905 917 return (env_entry[r->var_len] == '=');
906 918 }
907 919
908 920 static void
909 921 apply_env_rule(char **env, int *env_sizep, struct env_rule *r)
910 922 {
911 923 // First remove the variable if already set
912 924 int pos = 0;
913 925 while (pos < *env_sizep && !match_env_var(env[pos], r))
914 926 pos++;
915 927 if (pos < *env_sizep)
916 928 {
917 929 (*env_sizep)--;
918 930 env[pos] = env[*env_sizep];
919 931 env[*env_sizep] = NULL;
920 932 }
921 933
922 934 // What is the new value?
923 935 char *new;
924 936 if (r->val)
925 937 {
926 938 if (!r->val[0])
927 939 return;
928 940 new = xmalloc(r->var_len + 1 + strlen(r->val) + 1);
929 941 sprintf(new, "%s=%s", r->var, r->val);
930 942 }
931 943 else
932 944 {
933 945 pos = 0;
934 946 while (environ[pos] && !match_env_var(environ[pos], r))
935 947 pos++;
936 948 if (!(new = environ[pos]))
937 949 return;
938 950 }
939 951
940 952 // Add it at the end of the array
941 953 env[(*env_sizep)++] = new;
942 954 env[*env_sizep] = NULL;
943 955 }
944 956
945 957 static char **
946 958 setup_environment(void)
947 959 {
948 960 // Link built-in rules with user rules
949 961 for (int i=ARRAY_SIZE(default_env_rules)-1; i >= 0; i--)
950 962 {
951 963 default_env_rules[i].next = first_env_rule;
952 964 first_env_rule = &default_env_rules[i];
953 965 }
954 966
955 967 // Scan the original environment
956 968 char **orig_env = environ;
957 969 int orig_size = 0;
958 970 while (orig_env[orig_size])
959 971 orig_size++;
960 972
961 973 // For each rule, reserve one more slot and calculate length
962 974 int num_rules = 0;
963 975 for (struct env_rule *r = first_env_rule; r; r=r->next)
964 976 {
965 977 num_rules++;
966 978 r->var_len = strlen(r->var);
967 979 }
968 980
969 981 // Create a new environment
970 982 char **env = xmalloc((orig_size + num_rules + 1) * sizeof(char *));
971 983 int size;
972 984 if (pass_environ)
973 985 {
974 986 memcpy(env, environ, orig_size * sizeof(char *));
975 987 size = orig_size;
976 988 }
977 989 else
978 990 size = 0;
979 991 env[size] = NULL;
980 992
981 993 // Apply the rules one by one
982 994 for (struct env_rule *r = first_env_rule; r; r=r->next)
983 995 apply_env_rule(env, &size, r);
984 996
985 997 // Return the new env and pass some gossip
986 998 if (verbose > 1)
987 999 {
988 1000 fprintf(stderr, "Passing environment:\n");
989 1001 for (int i=0; env[i]; i++)
You need to be logged in to leave comments. Login now