示例#1
0
int main(int argc, char **argv) {
	unsigned pid = 0;
	int i;

	// handle CTRL-C
	signal (SIGINT, my_handler);
	signal (SIGTERM, my_handler);

	for (i = 1; i < argc; i++) {
		// default options
		if (strcmp(argv[i], "--help") == 0 ||
		    strcmp(argv[i], "-?") == 0) {
			usage();
			return 0;
		}
		else if (strcmp(argv[i], "--version") == 0) {
			printf("firemon version %s\n\n", VERSION);
			return 0;
		}
		
		// options without a pid argument
		else if (strcmp(argv[i], "--top") == 0) {
			top(); // never to return
		}
		else if (strcmp(argv[i], "--list") == 0) {
			list();
			return 0;
		}
		else if (strcmp(argv[i], "--netstats") == 0) {
			struct stat s;
			if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0) {
				fprintf(stderr, "Error: this feature is not available on Grsecurity systems\n");
				exit(1);
			}	

			netstats();
			return 0;
		}


		// cumulative options with or without a pid argument
		else if (strcmp(argv[i], "--x11") == 0) {
			arg_x11 = 1;
		}
		else if (strcmp(argv[i], "--cgroup") == 0) {
			arg_cgroup = 1;
		}
		else if (strcmp(argv[i], "--cpu") == 0) {
			arg_cpu = 1;
		}
		else if (strcmp(argv[i], "--seccomp") == 0) {
			arg_seccomp = 1;
		}
		else if (strcmp(argv[i], "--caps") == 0) {
			arg_caps = 1;
		}
		else if (strcmp(argv[i], "--tree") == 0) {
			arg_tree = 1;
		}
		else if (strcmp(argv[i], "--interface") == 0) {
			arg_interface = 1;
		}
		else if (strcmp(argv[i], "--route") == 0) {
			arg_route = 1;
		}
		else if (strcmp(argv[i], "--arp") == 0) {
			arg_arp = 1;
		}

		else if (strncmp(argv[i], "--name=", 7) == 0) {
			char *name = argv[i] + 7;
			if (name2pid(name, (pid_t *) &pid)) {
				fprintf(stderr, "Error: cannot find sandbox %s\n", name);
				return 1;
			}
		}
		
		// etc
		else if (strcmp(argv[i], "--nowrap") == 0)
			arg_nowrap = 1;
		
		// invalid option
		else if (*argv[i] == '-') {
			fprintf(stderr, "Error: invalid option\n");		
			return 1;
		}
		
		// PID argument
		else {
			// this should be a pid number
			char *ptr = argv[i];
			while (*ptr != '\0') {
				if (!isdigit(*ptr)) {
					fprintf(stderr, "Error: not a valid PID number\n");
					exit(1);
				}
				ptr++;
			}

			sscanf(argv[i], "%u", &pid);
			break;
		}
	}

	if (arg_tree)
		tree((pid_t) pid);
	if (arg_interface)
		interface((pid_t) pid);
	if (arg_route)
		route((pid_t) pid);
	if (arg_arp)
		arp((pid_t) pid);
	if (arg_seccomp)
		seccomp((pid_t) pid);
	if (arg_caps)
		caps((pid_t) pid);
	if (arg_cpu)
		cpu((pid_t) pid);
	if (arg_cgroup)
		cgroup((pid_t) pid);
	if (arg_x11)
		x11((pid_t) pid);
	
	if (!arg_route && !arg_arp && !arg_interface && !arg_tree && !arg_caps && !arg_seccomp && !arg_x11)
		procevent((pid_t) pid); // never to return
		
	return 0;
}
int main(int argc, char *argv[])
{
    int c;
    int fd;
    char path[PATH_MAX];
    int nsid;
    int pid;
    int tdf;

    static struct sched_param sp;
    while ((c = getopt(argc, argv, "+cdn:t:pa:g:r:vh")) != -1) {
        switch(c) {
        case 'c':
            /* close file descriptors except stdin/out/error */
            for (fd = getdtablesize(); fd > 2; fd--)
                close(fd);
            break;
        case 'd':
            /* detach from tty */
            if (getpgrp() == getpid()) {
                switch(fork()) {
                    case -1:
                        perror("fork");
                        return 1;
                    case 0:     /* child */
                        break;
                    default:    /* parent */
                        return 0;
                }
            }
            setsid();
            break;
        case 'n':
            // /* run in network and mount namespaces */
            // if (unshare(CLONE_NEWNET|CLONE_NEWNS) == -1) {
            //     perror("unshare");
            //     return 1;
            // }
            tdf = atoi(optarg);
            /* run in network, mount namespaces and set dilation */
            if (virtualtimeunshare(CLONE_NEWNET|CLONE_NEWNS, tdf) == -1) {
               perror("virtualtimeunshare");
               return 1;
            }
            /* mount sysfs to pick up the new network namespace */
            if (mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL) == -1) {
                perror("mount");
                return 1;
            }
            break;
        case 't':
            tdf = atoi(optarg);
            int ppid = getppid(); // maybe ppid, by which we ID host, should give as argument parameter
            /* try set tdf to be another value */
            if (settimedilationfactor(tdf, ppid) == -1) {
                perror("settimedilationfactor");
                printf("[process %d child of %d] settimedilationfactor fail\n", getpid(), getppid());
                return 1;
            }
            // printf("[process %d child of %d] settimedilationfactor success\n", getpid(), getppid());
            break;
        case 'p':
            /* print pid */
            printf("\001%d\n", getpid());
            fflush(stdout);
            break;
        case 'a':
            /* Attach to pid's network namespace and mount namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/net", pid);
            nsid = open(path, O_RDONLY);
            if (nsid < 0) {
                perror(path);
                return 1;
            }
            if (setns(nsid, 0) != 0) {
                perror("setns");
                return 1;
            }
            /* Plan A: call setns() to attach to mount namespace */
            sprintf(path, "/proc/%d/ns/mnt", pid);
            nsid = open(path, O_RDONLY);
            if (nsid < 0 || setns(nsid, 0) != 0) {
                char *cwd = get_current_dir_name();
                /* Plan B: chroot/chdir into pid's root file system */
                sprintf(path, "/proc/%d/root", pid);
                if (chroot(path) < 0) {
                    perror(path);
                    return 1;
                }
                /* need to chdir to correct working directory */
                if (chdir(cwd) != 0) {
                    perror(cwd);
                    return 1;
                }
            }
            break;
        case 'g':
            /* Attach to cgroup */
            cgroup(optarg);
            break;
        case 'r':
            /* Set RT scheduling priority */
            sp.sched_priority = atoi(optarg);
            if (sched_setscheduler(getpid(), SCHED_RR, &sp) < 0) {
                perror("sched_setscheduler");
                return 1;
            }
            break;
        case 'v':
            printf("%s\n", VERSION);
            exit(0);
        case 'h':
            usage(argv[0]);
            exit(0);
        default:
            usage(argv[0]);
            exit(1);
        }

    }

    if (optind < argc) {
        execvp(argv[optind], &argv[optind]);
        perror(argv[optind]);
        return 1;
    }

    // usage(argv[0]);

    return 0;
}
示例#3
0
int main(int argc, char *argv[])
{
    int c;
    int fd;
    char path[PATH_MAX];
    int nsid;
    int pid;
    char *cwd = get_current_dir_name();

    static struct sched_param sp;
    while ((c = getopt(argc, argv, "+cdnpa:g:r:vh")) != -1)
        switch(c) {
        case 'c':
            /* close file descriptors except stdin/out/error */
            for (fd = getdtablesize(); fd > 2; fd--)
                close(fd);
            break;
        case 'd':
            /* detach from tty */
            if (getpgrp() == getpid()) {
                switch(fork()) {
                    case -1:
                        perror("fork");
                        return 1;
                    case 0:     /* child */
                        break;
                    default:    /* parent */
                        return 0;
                }
            }
            setsid();
            break;
        case 'n':
            /* run in network and mount namespaces */
            if (unshare(CLONE_NEWNET|CLONE_NEWNS) == -1) {
                perror("unshare");
                return 1;
            }

            /* Mark our whole hierarchy recursively as private, so that our
             * mounts do not propagate to other processes.
             */

            if (mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) == -1) {
                perror("remount");
                return 1;
            }
            /* mount sysfs to pick up the new network namespace */
            if (mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL) == -1) {
                perror("mount");
                return 1;
            }
            break;
        case 'p':
            /* print pid */
            printf("\001%d\n", getpid());
            fflush(stdout);
            break;
        case 'a':
            /* Attach to pid's network namespace and mount namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/net", pid);
            nsid = open(path, O_RDONLY);
            if (nsid < 0) {
                perror(path);
                return 1;
            }
            if (setns(nsid, 0) != 0) {
                perror("setns");
                return 1;
            }
            /* Plan A: call setns() to attach to mount namespace */
            sprintf(path, "/proc/%d/ns/mnt", pid);
            nsid = open(path, O_RDONLY);
            if (nsid < 0 || setns(nsid, 0) != 0) {
                /* Plan B: chroot/chdir into pid's root file system */
                sprintf(path, "/proc/%d/root", pid);
                if (chroot(path) < 0) {
                    perror(path);
                    return 1;
                }
            }
            /* chdir to correct working directory */
            if (chdir(cwd) != 0) {
                perror(cwd);
                return 1;
            }
            break;
        case 'g':
            /* Attach to cgroup */
            cgroup(optarg);
            break;
        case 'r':
            /* Set RT scheduling priority */
            sp.sched_priority = atoi(optarg);
            if (sched_setscheduler(getpid(), SCHED_RR, &sp) < 0) {
                perror("sched_setscheduler");
                return 1;
            }
            break;
        case 'v':
            printf("%s\n", VERSION);
            exit(0);
        case 'h':
            usage(argv[0]);
            exit(0);
        default:
            usage(argv[0]);
            exit(1);
        }

    if (optind < argc) {
        execvp(argv[optind], &argv[optind]);
        perror(argv[optind]);
        return 1;
    }

    usage(argv[0]);

    return 0;
}
示例#4
0
文件: mxexec.c 项目: Mohdrz/miniNExT
int main(int argc, char *argv[]) {
    int c;
    int fd;
    char path[PATH_MAX];
    int pid;
    int detach = 0;
    int netns = 0;
    int mountns = 0;
    int mountnspid = 0;
    int pidns = 0;
    int printpid = 0;
    int mountprocfs = 0;
    static struct sched_param sp;
    while ((c = getopt(argc, argv, "+cdnmiufpa:b:k:j:g:r:vh")) != -1)
        switch (c) {
        case 'c':
            /* close file descriptors except stdin/out/error */
            for (fd = getdtablesize(); fd > 2; fd--)
                close(fd);
            break;
        case 'd':
            /* detach from tty */
            detach = 1; /* delay setsid() incase new PID namespace */
            break;
        case 'n':
            /* run in network namespace */
            if (unshare(CLONE_NEWNET) == -1) {
                perror("unshare");
                return 1;
            }
            netns = NET_NS_CREATE;
            break;
        case 'm':
            /* run in mount namespace */
            if (unshare(CLONE_NEWNS) == -1) {
                perror("unshare");
                return 1;
            }
            /* mount sysfs to pick up the new network namespace */
            mountns = MOUNT_NS_CREATE; /* delay mount of /sysfs */
            break;
        case 'i':
            /* run in new PID namespace */
            if (unshare(CLONE_NEWPID) == -1) {
                perror("unshare");
                return 1;
            }
            pidns = PID_NS_CREATE; /* record creation of PID namespace */
            break;
        case 'u':
            /* run in new UTS namespace */
            if (unshare(CLONE_NEWUTS) == -1) {
                perror("unshare");
                return 1;
            }
            break;
        case 'f':
            /* mount procfs (for new PID namespaces) */
            mountprocfs = TRUE; /* delay mounting proc until new NS established */
            break;
        case 'p':
            /* print pid */
            printpid = TRUE; /* delay printing PID until after NS procesisng*/
            break;
        case 'a':
            /* Attach to pid's network namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/net", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            netns = NET_NS_JOIN;
            break;
        case 'b':
            /* Attach to pid's mount namespace */
            mountns = MOUNT_NS_JOIN; /* delay joining mount namespace */
            mountnspid = atoi(optarg); /* record PID to join */
            break;
        case 'k':
            /* Attach to pid's PID namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/pid", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            pidns = PID_NS_JOIN; /* record join of PID namespace */
            break;
        case 'j':
            /* Attach to pid's UTS namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/uts", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            break;
        case 'g':
            /* Attach to cgroup */
            cgroup(optarg);
            break;
        case 'r':
            /* Set RT scheduling priority */
            sp.sched_priority = atoi(optarg);
            if (sched_setscheduler(getpid(), SCHED_RR, &sp) < 0) {
                perror("sched_setscheduler");
                return 1;
            }
            break;
        case 'v':
            printf("%s\n", VERSION);
            exit(0);
        case 'h':
            usage(argv[0]);
            exit(0);
        default:
            usage(argv[0]);
            exit(1);
        }

    /* fork to create / join PID namespace */
    if (pidns == PID_NS_CREATE || pidns == PID_NS_JOIN) {
        int status = 0;
        pid_t pid = fork();
        switch (pid) {
        case -1:
            perror("fork");
            return 1;
        case 0: /* child */
            break;
        default: /* parent */
            /* print global PID (not namespace PID)*/
            if (printpid == 1) {
                printf("\001%d\n", pid);
                fflush(stdout);
            }
            /* wait on the PID to handle attachment for 'mx'*/
            if (waitpid(pid, &status, 0) == -1)
                return 1;
            if (WIFEXITED(status))
                /* caught child exit, forward return code*/
                return WEXITSTATUS(status);
            else if (WIFSIGNALED(status))
                kill(getpid(), WTERMSIG(status));
            /* child exit failed, (although return won't distinguish) */
            return 1;
        }
    }

    /* if requested, we are in the new/requested PID namespace */
    /* completed performing other namespaces (PID/network) operations */

    /* go ahead and join the mount namespace if requested */
    if (mountns == MOUNT_NS_JOIN && mountnspid != FALSE) {
        sprintf(path, "/proc/%d/ns/mnt", pid);
        if (attachToNS(path) != 0) {
            return 1;
        }
    }

    /* if mount of procfs requested, check for pidns and mountns */
    if (mountprocfs && (pidns != PID_NS_CREATE || mountns != MOUNT_NS_CREATE)) {
        /* requested procfs, but required PID and/or mount namespace missing  */
        return 1;
    }

    /* mount procfs to pick up the new PID namespace */
    if (mountprocfs
            && (mount("none", "/proc", NULL, MS_PRIVATE | MS_REC, NULL) != 0
                    || mount("proc", "/proc", "proc",
                            MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL) != 0)) {
        perror("mount");
    }

    /* mount sysfs to pick up the new PID namespace */
    if (netns == NET_NS_CREATE && mountns == MOUNT_NS_CREATE) {
        if (mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL) == -1) {
            perror("mount");
            return 1;
        }
    }

    /* setsid() if requested & required (not needed if using PID namespace) */
    if (detach == 1 && pidns == FALSE) {
        if (getpgrp() == getpid()) {
            switch (fork()) {
            case -1:
                perror("fork");
                return 1;
            case 0: /* child */
                break;
            default: /* parent */
                return 0;
            }
        }
        setsid();
    }

    /* print pid if requested (if in new namespace, we don't print local PID) */
    if (printpid == 1 && pidns == 0) {
        printf("\001%d\n", getpid());
        fflush(stdout);
    }

    /* launch if requested */
    if (optind < argc) {
        execvp(argv[optind], &argv[optind]);
        perror(argv[optind]);
        return 1;
    }

    usage(argv[0]);

    return 0;
}
int main(int argc, char *argv[])
{
    int c;
    int fd;
    char path[PATH_MAX];
    int nsid;
    int pid;
    static struct sched_param sp;
    while ((c = getopt(argc, argv, "+cdnpa:g:r:vh")) != -1)
        switch(c) {
        case 'c':
            /* close file descriptors except stdin/out/error */
            for (fd = getdtablesize(); fd > 2; fd--)
                close(fd);
            break;
        case 'd':
            /* detach from tty */
            if (getpgrp() == getpid()) {
                switch(fork()) {
                    case -1:
                        perror("fork");
                        return 1;
                    case 0:     /* child */
                        break;
                    default:    /* parent */
                        return 0;
                }
            }
            setsid();
            break;
        case 'n':
            /* run in network namespace */
            if (unshare(CLONE_NEWNET) == -1) {
                perror("unshare");
                return 1;
            }
            break;
        case 'p':
            /* print pid */
            printf("\001%d\n", getpid());
            fflush(stdout);
            break;
        case 'a':
            /* Attach to pid's network namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/net", pid );
            nsid = open(path, O_RDONLY);
            if (nsid < 0) {
                perror(path);
                return 1;
            }
            if (setns(nsid, 0) != 0) {
                perror("setns");
                return 1;
            }
            break;
        case 'g':
            /* Attach to cgroup */
            cgroup(optarg);
            break;
        case 'r':
            /* Set RT scheduling priority */
            sp.sched_priority = atoi(optarg);
            if (sched_setscheduler(getpid(), SCHED_RR, &sp) < 0) {
                perror("sched_setscheduler");
                return 1;
            }
            break;
        case 'v':
            printf("%s\n", VERSION);
            exit(0);
        case 'h':
            usage(argv[0]);
            exit(0);
        default:
            usage(argv[0]);
            exit(1); 
        }

    if (optind < argc) {
        execvp(argv[optind], &argv[optind]);
        perror(argv[optind]);
        return 1;
    }
    
    usage(argv[0]);
}