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

« back to all changes in this revision

Viewing changes to bin/trampoline/trampoline.c

  • Committer: William Grant
  • Date: 2012-06-28 01:52:02 UTC
  • Revision ID: me@williamgrant.id.au-20120628015202-f6ru7o367gt6nvgz
Hah

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
 
122
123
{
123
124
    fprintf(stderr,
124
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
167
char *jail_src(const char *jail_src_base, const char *jail_base,
142
168
               const char *jailpath)
147
173
 
148
174
    srclen = strlen(jail_src_base);
149
175
    dstlen = strlen(jail_base);
150
 
    
 
176
 
151
177
    src = die_if_null(malloc(strlen(jailpath) + (srclen - dstlen) + 1));
152
178
    strcpy(src, jail_src_base);
153
179
    strcat(src, jailpath+dstlen);
163
189
{
164
190
    char *jailsrc;
165
191
    char *jaillib;
166
 
    char *mountdata;
 
192
    char *source_bits;
 
193
    char *target_bits;
167
194
 
168
195
    /* Check if there is something useful in the jail. If not, it's probably
169
196
     * not mounted. */
183
210
             }
184
211
             syslog(LOG_NOTICE, "created mountpoint %s\n", jailpath);
185
212
        }
186
 
       
 
213
 
187
214
        jailsrc = jail_src(jail_src_base, jail_base, jailpath);
188
 
        mountdata = die_if_null(malloc(3 + strlen(jailsrc) + 4 + strlen(jail_system) + 3 + 1));
189
 
        sprintf(mountdata, "br:%s=rw:%s=ro", jailsrc, jail_system);
190
 
        if (mount("none", jailpath, "aufs", 0, mountdata))
191
 
        {
192
 
            syslog(LOG_ERR, "could not mount %s\n", jailpath);
193
 
            perror("could not mount");
194
 
            exit(1);
195
 
        } 
 
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);
196
228
 
197
229
        syslog(LOG_INFO, "mounted %s\n", jailpath);
198
230
 
199
231
        free(jailsrc);
200
 
        free(mountdata);
 
232
        free(source_bits);
 
233
        free(target_bits);
201
234
    }
202
235
 
203
236
    free(jaillib);
227
260
    char* prog;
228
261
    char* const * args;
229
262
    int uid;
 
263
    gid_t groups[1];
230
264
    int arg_num = 1;
231
265
    int daemon_mode = 0;
232
266
    int unlimited = 0;
326
360
        perror("could not setgid");
327
361
        exit(1);
328
362
    }
 
363
    
 
364
    groups[0] = uid;
 
365
    if (setgroups(1, groups))
 
366
    {
 
367
        perror("could not setgroups");
 
368
        exit(1);
 
369
    }
329
370
 
330
371
    if (setuid(uid))
331
372
    {
338
379
    {
339
380
        struct rlimit l;
340
381
        /* Process adress space in memory */
341
 
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
342
 
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
 
382
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
 
383
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
343
384
        if (setrlimit(RLIMIT_AS, &l))
344
385
        {
345
386
            perror("could not setrlimit/RLIMIT_AS");
350
391
         * Note: This requires a kernel patch to work correctly otherwise it is  
351
392
         * ineffective (thus you are only limited by RLIMIT_AS)
352
393
         */
353
 
        l.rlim_cur = 192 * 1024 * 1024; /* 192MiB */
354
 
        l.rlim_max = 256 * 1024 * 1024; /* 256MiB */
 
394
        l.rlim_cur = 448 * 1024 * 1024; /* 512MiB - 64MiB */
 
395
        l.rlim_max = 512 * 1024 * 1024; /* 512MiB */
355
396
        if (setrlimit(RLIMIT_DATA, &l))
356
397
        {
357
398
            perror("could not setrlimit/RLIMIT_DATA");
379
420
        /* File Size */
380
421
        l.rlim_cur = 64 * 1024 * 1024; /* 64MiB */
381
422
        l.rlim_max = 72 * 1024 * 1024; /* 72MiB */
382
 
if (setrlimit(RLIMIT_FSIZE, &l))
 
423
        if (setrlimit(RLIMIT_FSIZE, &l))
383
424
        {
384
425
            perror("could not setrlimit/RLIMIT_FSIZE");
385
426
            exit(1);
386
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
        }
387
437
    }
388
438
 
389
439
    /* Remove any signal handler masks so we can send signals to the child */