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

« back to all changes in this revision

Viewing changes to bin/trampoline/trampoline.c

  • Committer: William Grant
  • Date: 2010-02-25 07:34:50 UTC
  • Revision ID: grantw@unimelb.edu.au-20100225073450-zcl8ev5hlyhbszeu
Activate the Storm C extensions if possible. Moar speed.

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 */