/* * * Copyright 2023 Oleg Borodin * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include //#include //#include //#include //#include //#include #include char* _gethostname(void) { size_t len; char* res = NULL; char* mibstr = "kern.hostname"; sysctlbyname(mibstr, NULL, &len, NULL, 0); res = malloc(len); sysctlbyname(mibstr, res, &len, NULL, 0); return res; } int getintsysctl(char* mibname) { int res = 0; size_t size = sizeof(int); sysctlbyname(mibname, &res, &size, NULL, 0); return res; } int setintsysctl(char* mibname, int val) { int res = 0; sysctlbyname(mibname, NULL, NULL, &val, sizeof(int)); return res; } int run() { pid_t childpid; int pstdout[2]; if (pipe(pstdout) < 0) { return -errno; } int pstderr[2]; if (pipe(pstderr) < 0) { return -errno; } //if (chroot("./newroot/") != 0) { //printf("child chroot error\n"); //return 0; //} if((childpid = fork()) < 0) { return -errno; } if (childpid == 0) { /* child */ printf("#1 child %d\n", getpid()); setintsysctl("security.jail.set_hostname_allowed", 0); setintsysctl("security.jail.set_hostname_allowed", 0); setintsysctl("security.jail.sysvipc_allowed", 0); setintsysctl("security.jail.allow_raw_sockets", 0); setintsysctl("security.jail.chflags_allowed", 0); setintsysctl("security.jail.mount_allowed", 0); setintsysctl("security.jail.socket_unixiproute_only", 0); close(pstdout[0]); close(pstderr[0]); dup2(pstdout[1], STDOUT_FILENO); dup2(pstderr[1], STDERR_FILENO); printf("#2 child %d\n", getpid()); //if (chroot("./newroot/") != 0) { // printf("child chroot error\n"); // return 0; //} //char cmd[] = "./newroot/foo"; //char cmd[] = "/bin/ls"; //char *const params[] = { cmd, NULL}; //if (execv(cmd, params) < 0) { // printf("child exec error\n"); // return 0; //}; struct in_addr inaddr; inet_pton(AF_INET, "192.168.52.7", &inaddr); struct jail j = { .version = JAIL_API_VERSION, .path = "./newroot", .hostname = "localhost", .jailname = "test", .ip4s = 1, .ip6s = 0, .ip4 = &inaddr, .ip6 = NULL }; int id = jail(&j); if (id < 0) { printf("cannon jail process, error: %s\n", strerror(errno)); exit(1); } printf("jailed = %d\n", getintsysctl("security.jail.jailed")); printf("jid = %d\n", id); //char* newhostname = "foohost"; // if (sethostname(newhostname, strlen(newhostname)) < 0) { // printf("hostname don't set, error: %s\n", strerror(errno)); //} char hostname[NAME_MAX]; gethostname(hostname, NAME_MAX); printf("host = %s\n", hostname); //lsif(); setgid(1000); setuid(1000); char* cmd = "./foo"; execl(cmd, cmd, NULL); } else { /* parent */ printf("parent %d\n", getpid()); close(pstdout[1]); close(pstderr[1]); char buffer[16]; int n = 0; while ((n = read(pstdout[0], buffer, sizeof(buffer) - 1)) != 0) { buffer[n] = '\0'; printf("%s", buffer); } } int status = 0; waitpid(childpid, &status, 0); return 0; } int main(int argc, char **argv) { if (run() < 0) { printf("run error\n"); return 1; } return 0; }