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

« back to all changes in this revision

Viewing changes to bin/trampoline/trampoline.c

  • Committer: Matt Giuca
  • Date: 2010-07-28 06:09:00 UTC
  • Revision ID: matt.giuca@gmail.com-20100728060900-6a0lcuexcv1juh5r
ivle/webapp/submit/submit.html: Rewrote error message when an offering could not be found to submit to. This can have one of several causes, and the old error assumed it was because you weren't in a subject dir. Now enumerates the possible reasons. (LP: #526853)

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...]
31
30
 * Must run as root. Will safely setuid to the supplied uid, checking that it
32
31
 * is not root. Recommended that the file is set up as follows:
33
32
 *  sudo chown root:root trampoline; sudo chroot +s trampoline
34
33
 */
35
34
 
36
35
#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>
48
49
#include <limits.h>
49
50
#include <signal.h>
50
51
 
121
122
static void usage(const char* nm)
122
123
{
123
124
    fprintf(stderr,
124
 
        "usage: %s [-d] [-u] <uid> <jail> <cwd> <program> [args...]\n", nm);
 
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");
125
135
    exit(1);
126
136
}
127
137
 
137
147
    return ptr;
138
148
}
139
149
 
 
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
 
140
166
/* Find the path of the user components of a jail, given a mountpoint. */
141
 
char *jail_src(const char* jailpath)
 
167
char *jail_src(const char *jail_src_base, const char *jail_base,
 
168
               const char *jailpath)
142
169
{
143
170
    char* src;
144
171
    int srclen;
146
173
 
147
174
    srclen = strlen(jail_src_base);
148
175
    dstlen = strlen(jail_base);
149
 
    
 
176
 
150
177
    src = die_if_null(malloc(strlen(jailpath) + (srclen - dstlen) + 1));
151
178
    strcpy(src, jail_src_base);
152
179
    strcat(src, jailpath+dstlen);
157
184
/* Check for the validity of a jail in the given path, mounting it if it looks
158
185
 * empty.
159
186
 * TODO: Updating /etc/mtab would be nice. */
160
 
void mount_if_needed(const char* jailpath)
 
187
void mount_if_needed(const char *jail_src_base, const char *jail_base,
 
188
                     const char *jail_system, const char *jailpath)
161
189
{
162
190
    char *jailsrc;
163
191
    char *jaillib;
164
 
    char *mountdata;
 
192
    char *source_bits;
 
193
    char *target_bits;
165
194
 
166
195
    /* Check if there is something useful in the jail. If not, it's probably
167
196
     * not mounted. */
181
210
             }
182
211
             syslog(LOG_NOTICE, "created mountpoint %s\n", jailpath);
183
212
        }
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
 
        } 
 
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);
194
228
 
195
229
        syslog(LOG_INFO, "mounted %s\n", jailpath);
196
230
 
197
231
        free(jailsrc);
198
 
        free(mountdata);
 
232
        free(source_bits);
 
233
        free(target_bits);
199
234
    }
200
235
 
201
236
    free(jaillib);
217
252
 
218
253
int main(int argc, char* const argv[])
219
254
{
 
255
    char* jail_base;
 
256
    char* jail_src_base;
 
257
    char* jail_system;
220
258
    char* jailpath;
221
259
    char* work_dir;
222
260
    char* prog;
223
261
    char* const * args;
224
262
    int uid;
 
263
    gid_t groups[1];
225
264
    int arg_num = 1;
226
265
    int daemon_mode = 0;
227
266
    int unlimited = 0;
260
299
        arg_num++;
261
300
    }
262
301
    uid = atoi(argv[arg_num++]);
 
302
    jail_base = argv[arg_num++];
 
303
    jail_src_base = argv[arg_num++];
 
304
    jail_system = argv[arg_num++];
263
305
    jailpath = argv[arg_num++];
264
306
    work_dir = argv[arg_num++];
265
307
    prog = argv[arg_num];
289
331
    openlog("trampoline", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
290
332
 
291
333
    #ifdef IVLE_AUFS_JAILS
292
 
    mount_if_needed(canonical_jailpath);
 
334
    mount_if_needed(jail_src_base, jail_base, jail_system, canonical_jailpath);
293
335
    #endif /* IVLE_AUFS_JAILS */
294
336
 
295
337
    /* chroot into the jail.
318
360
        perror("could not setgid");
319
361
        exit(1);
320
362
    }
 
363
    
 
364
    groups[0] = uid;
 
365
    if (setgroups(1, groups))
 
366
    {
 
367
        perror("could not setgroups");
 
368
        exit(1);
 
369
    }
321
370
 
322
371
    if (setuid(uid))
323
372
    {
330
379
    {
331
380
        struct rlimit l;
332
381
        /* Process adress space in memory */
333
 
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
334
 
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
 
382
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
 
383
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
335
384
        if (setrlimit(RLIMIT_AS, &l))
336
385
        {
337
386
            perror("could not setrlimit/RLIMIT_AS");
342
391
         * Note: This requires a kernel patch to work correctly otherwise it is  
343
392
         * ineffective (thus you are only limited by RLIMIT_AS)
344
393
         */
345
 
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
346
 
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
 
394
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
 
395
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
347
396
        if (setrlimit(RLIMIT_DATA, &l))
348
397
        {
349
398
            perror("could not setrlimit/RLIMIT_DATA");
371
420
        /* File Size */
372
421
        l.rlim_cur = 64 * 1024 * 1024; /* 64MiB */
373
422
        l.rlim_max = 72 * 1024 * 1024; /* 72MiB */
374
 
if (setrlimit(RLIMIT_FSIZE, &l))
 
423
        if (setrlimit(RLIMIT_FSIZE, &l))
375
424
        {
376
425
            perror("could not setrlimit/RLIMIT_FSIZE");
377
426
            exit(1);
378
427
        }
 
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
        }
379
437
    }
380
438
 
381
439
    /* Remove any signal handler masks so we can send signals to the child */