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

« back to all changes in this revision

Viewing changes to bin/trampoline/trampoline.c

  • Committer: William Grant
  • Date: 2009-01-13 01:36:15 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1123
Merge setup-refactor branch. This completely breaks existing installations;
every path (both filesystem and Python) has changed. Do not upgrade without
knowing what you are doing.

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