~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to bin/trampoline/trampoline.c

Modified the database so that exercises are now stored in the database, rather
than in flat files.

This also necessitated adding new tables and storm classes for test suites
and test cases.

Note that this commit merely changes the database and adds a script to
upload exercises. The code for actually reading exercises has yet
to be changed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 * Scripts (such as Python programs) should be executed by supplying
28
28
 * "/usr/bin/python" as the program, and the script as the first argument.
29
29
 *
 
30
 * Usage: trampoline uid jail-path working-path program [args...]
30
31
 * Must run as root. Will safely setuid to the supplied uid, checking that it
31
32
 * is not root. Recommended that the file is set up as follows:
32
33
 *  sudo chown root:root trampoline; sudo chroot +s trampoline
33
34
 */
34
35
 
35
36
#define _XOPEN_SOURCE
36
 
#define _BSD_SOURCE
37
37
 
38
38
#include <stdio.h>
39
39
#include <stdlib.h>
45
45
#include <sys/stat.h>
46
46
#include <sys/time.h>
47
47
#include <sys/resource.h>
48
 
#include <grp.h>
49
48
#include <limits.h>
50
49
#include <signal.h>
51
50
 
122
121
static void usage(const char* nm)
123
122
{
124
123
    fprintf(stderr,
125
 
        "usage: %s [-d] [-u] <uid> <base> <src> <system> <jail> <cwd> <program> [args...]\n", nm);
126
 
    fprintf(stderr, "  -d       \tDaemonize\n");
127
 
    fprintf(stderr, "  -u       \tPrint usage\n");
128
 
    fprintf(stderr, "  <uid>    \tUID to run program as\n");
129
 
    fprintf(stderr, "  <base>   \tDirectory that jails will be mounted in\n");
130
 
    fprintf(stderr, "  <src>    \tDirectory containing users jail data\n");
131
 
    fprintf(stderr, "  <system> \tDirectory containing main jail file system\n");
132
 
    fprintf(stderr, "  <jail>   \tDirectory of users mounted jail\n");
133
 
    fprintf(stderr, "  <cwd>    \tDirectory inside the jail to change dir to\n");
134
 
    fprintf(stderr, "  <program>\tProgram inside jail to execute\n");
 
124
        "usage: %s [-d] [-u] <uid> <jail> <cwd> <program> [args...]\n", nm);
135
125
    exit(1);
136
126
}
137
127
 
147
137
    return ptr;
148
138
}
149
139
 
150
 
int checked_mount(const char *source, const char *target,
151
 
                  const char *filesystemtype, unsigned long mountflags,
152
 
                  const void *data)
153
 
{
154
 
    int result = mount(source, target, filesystemtype, mountflags, data);
155
 
    if (result)
156
 
    {
157
 
        syslog(LOG_ERR, "could not mount %s on %s\n", source, target);
158
 
        perror("could not mount");
159
 
        exit(1);
160
 
    }
161
 
 
162
 
    return result;
163
 
}
164
 
 
165
 
 
166
140
/* Find the path of the user components of a jail, given a mountpoint. */
167
 
char *jail_src(const char *jail_src_base, const char *jail_base,
168
 
               const char *jailpath)
 
141
char *jail_src(const char* jailpath)
169
142
{
170
143
    char* src;
171
144
    int srclen;
173
146
 
174
147
    srclen = strlen(jail_src_base);
175
148
    dstlen = strlen(jail_base);
176
 
 
 
149
    
177
150
    src = die_if_null(malloc(strlen(jailpath) + (srclen - dstlen) + 1));
178
151
    strcpy(src, jail_src_base);
179
152
    strcat(src, jailpath+dstlen);
184
157
/* Check for the validity of a jail in the given path, mounting it if it looks
185
158
 * empty.
186
159
 * TODO: Updating /etc/mtab would be nice. */
187
 
void mount_if_needed(const char *jail_src_base, const char *jail_base,
188
 
                     const char *jail_system, const char *jailpath)
 
160
void mount_if_needed(const char* jailpath)
189
161
{
190
162
    char *jailsrc;
191
163
    char *jaillib;
192
 
    char *source_bits;
193
 
    char *target_bits;
 
164
    char *mountdata;
194
165
 
195
166
    /* Check if there is something useful in the jail. If not, it's probably
196
167
     * not mounted. */
210
181
             }
211
182
             syslog(LOG_NOTICE, "created mountpoint %s\n", jailpath);
212
183
        }
213
 
 
214
 
        jailsrc = jail_src(jail_src_base, jail_base, jailpath);
215
 
        checked_mount(jail_system, jailpath, NULL, MS_BIND | MS_RDONLY, NULL);
216
 
 
217
 
        source_bits = die_if_null(malloc(strlen(jailsrc) + 5 + 1));
218
 
        target_bits = die_if_null(malloc(strlen(jailpath) + 5 + 1));
219
 
        sprintf(source_bits, "%s/home", jailsrc);
220
 
        sprintf(target_bits, "%s/home", jailpath);
221
 
 
222
 
        checked_mount(source_bits, target_bits, NULL, MS_BIND, NULL);
223
 
 
224
 
        sprintf(source_bits, "%s/tmp", jailsrc);
225
 
        sprintf(target_bits, "%s/tmp", jailpath);
226
 
 
227
 
        checked_mount(source_bits, target_bits, NULL, MS_BIND, NULL);
 
184
       
 
185
        jailsrc = jail_src(jailpath);
 
186
        mountdata = die_if_null(malloc(3 + strlen(jailsrc) + 4 + strlen(jail_system) + 3 + 1));
 
187
        sprintf(mountdata, "br:%s=rw:%s=ro", jailsrc, jail_system);
 
188
        if (mount("none", jailpath, "aufs", 0, mountdata))
 
189
        {
 
190
            syslog(LOG_ERR, "could not mount %s\n", jailpath);
 
191
            perror("could not mount");
 
192
            exit(1);
 
193
        } 
228
194
 
229
195
        syslog(LOG_INFO, "mounted %s\n", jailpath);
230
196
 
231
197
        free(jailsrc);
232
 
        free(source_bits);
233
 
        free(target_bits);
 
198
        free(mountdata);
234
199
    }
235
200
 
236
201
    free(jaillib);
252
217
 
253
218
int main(int argc, char* const argv[])
254
219
{
255
 
    char* jail_base;
256
 
    char* jail_src_base;
257
 
    char* jail_system;
258
220
    char* jailpath;
259
221
    char* work_dir;
260
222
    char* prog;
261
223
    char* const * args;
262
224
    int uid;
263
 
    gid_t groups[1];
264
225
    int arg_num = 1;
265
226
    int daemon_mode = 0;
266
227
    int unlimited = 0;
299
260
        arg_num++;
300
261
    }
301
262
    uid = atoi(argv[arg_num++]);
302
 
    jail_base = argv[arg_num++];
303
 
    jail_src_base = argv[arg_num++];
304
 
    jail_system = argv[arg_num++];
305
263
    jailpath = argv[arg_num++];
306
264
    work_dir = argv[arg_num++];
307
265
    prog = argv[arg_num];
331
289
    openlog("trampoline", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
332
290
 
333
291
    #ifdef IVLE_AUFS_JAILS
334
 
    mount_if_needed(jail_src_base, jail_base, jail_system, canonical_jailpath);
 
292
    mount_if_needed(canonical_jailpath);
335
293
    #endif /* IVLE_AUFS_JAILS */
336
294
 
337
295
    /* chroot into the jail.
360
318
        perror("could not setgid");
361
319
        exit(1);
362
320
    }
363
 
    
364
 
    groups[0] = uid;
365
 
    if (setgroups(1, groups))
366
 
    {
367
 
        perror("could not setgroups");
368
 
        exit(1);
369
 
    }
370
321
 
371
322
    if (setuid(uid))
372
323
    {
379
330
    {
380
331
        struct rlimit l;
381
332
        /* Process adress space in memory */
382
 
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
383
 
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
 
333
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
 
334
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
384
335
        if (setrlimit(RLIMIT_AS, &l))
385
336
        {
386
337
            perror("could not setrlimit/RLIMIT_AS");
391
342
         * Note: This requires a kernel patch to work correctly otherwise it is  
392
343
         * ineffective (thus you are only limited by RLIMIT_AS)
393
344
         */
394
 
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
395
 
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
 
345
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
 
346
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
396
347
        if (setrlimit(RLIMIT_DATA, &l))
397
348
        {
398
349
            perror("could not setrlimit/RLIMIT_DATA");
420
371
        /* File Size */
421
372
        l.rlim_cur = 64 * 1024 * 1024; /* 64MiB */
422
373
        l.rlim_max = 72 * 1024 * 1024; /* 72MiB */
423
 
        if (setrlimit(RLIMIT_FSIZE, &l))
 
374
if (setrlimit(RLIMIT_FSIZE, &l))
424
375
        {
425
376
            perror("could not setrlimit/RLIMIT_FSIZE");
426
377
            exit(1);
427
378
        }
428
 
        
429
 
        /* Number of Processes */
430
 
        l.rlim_cur = 50;
431
 
        l.rlim_max = 50;
432
 
        if (setrlimit(RLIMIT_NPROC, &l))
433
 
        {
434
 
            perror("could not setrlimit/RLIMIT_NPROC");
435
 
            exit(1);
436
 
        }
437
379
    }
438
380
 
439
381
    /* Remove any signal handler masks so we can send signals to the child */