static void owner(const atf_tc_t *tc, const char *mp) { USES_OWNER; FSTEST_ENTER(); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM) atf_tc_fail_errno("chown"); if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM) atf_tc_fail_errno("chmod"); rump_pub_lwproc_releaselwp(); if (rump_sys_chown(".", 1, -1) == -1) atf_tc_fail_errno("chown"); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (rump_sys_chown(".", 1, -1) == -1) atf_tc_fail_errno("chown"); if (rump_sys_chmod(".", 0000) == -1) atf_tc_fail_errno("chmod"); rump_pub_lwproc_releaselwp(); FSTEST_EXIT(); }
ATF_TC_BODY(proccreds, tc) { struct lwp *l1, *l2; rump_init(); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); l1 = rump_pub_lwproc_curlwp(); RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); l2 = rump_pub_lwproc_curlwp(); RL(rump_sys_setuid(22)); ATF_REQUIRE_EQ(rump_sys_getuid(), 22); rump_pub_lwproc_switch(l1); ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */ RL(rump_sys_setuid(11)); ATF_REQUIRE_EQ(rump_sys_getuid(), 11); rump_pub_lwproc_switch(l2); ATF_REQUIRE_EQ(rump_sys_getuid(), 22); rump_pub_lwproc_newlwp(rump_sys_getpid()); ATF_REQUIRE_EQ(rump_sys_getuid(), 22); }
static void times(const atf_tc_t *tc, const char *mp) { const char *name = "file.test"; int fd; unsigned int i, j; struct timeval tmv[2]; static struct timeval tmvs[] = { { QUAD_MIN, 0 }, { 0, 0 }, { QUAD_MAX, 999999 } }; FSTEST_ENTER(); if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) atf_tc_fail_errno("open"); if (rump_sys_close(fd) == -1) atf_tc_fail_errno("close"); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be broken"); if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES) atf_tc_fail_errno("utimes"); rump_pub_lwproc_releaselwp(); if (rump_sys_utimes(name, NULL) == -1) atf_tc_fail_errno("utimes"); for (i = 0; i < sizeof(tmvs) / sizeof(tmvs[0]); i++) { for (j = 0; j < sizeof(tmvs) / sizeof(tmvs[0]); j++) { tmv[0] = tmvs[i]; tmv[1] = tmvs[j]; rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM) atf_tc_fail_errno("utimes"); rump_pub_lwproc_releaselwp(); if (rump_sys_utimes(name, tmv) == -1) atf_tc_fail_errno("utimes"); } } if (rump_sys_unlink(name) == -1) atf_tc_fail_errno("unlink"); FSTEST_EXIT(); }
ATF_TC_BODY(rfork, tc) { struct stat sb; struct lwp *l, *l2; int fd; RZ(rump_init()); ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL); RZ(rump_pub_lwproc_rfork(0)); l = rump_pub_lwproc_curlwp(); RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777)); /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1); /* then check that rfork(0) does */ rump_pub_lwproc_switch(l); RZ(rump_pub_lwproc_rfork(0)); ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); RL(rump_sys_fstat(fd, &sb)); l2 = rump_pub_lwproc_curlwp(); /* * check that the shared fd table is really shared by * closing fd in parent */ rump_pub_lwproc_switch(l); RL(rump_sys_close(fd)); rump_pub_lwproc_switch(l2); ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1); /* redo, this time copying the fd table instead of sharing it */ rump_pub_lwproc_releaselwp(); rump_pub_lwproc_switch(l); RL(fd = rump_sys_open("/file", O_RDWR, 0777)); RZ(rump_pub_lwproc_rfork(RUMP_RFFDG)); ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); RL(rump_sys_fstat(fd, &sb)); l2 = rump_pub_lwproc_curlwp(); /* check that the fd table is copied */ rump_pub_lwproc_switch(l); RL(rump_sys_close(fd)); rump_pub_lwproc_switch(l2); RL(rump_sys_fstat(fd, &sb)); ATF_REQUIRE_EQ(sb.st_size, sizeof(fd)); }
int main() { struct sockaddr_in client; struct sockaddr_in server; char msg[500]; char buf[65535]; socklen_t clen; ssize_t nn; ssize_t off; int size = 1024 * 1024; int s; rump_init(); rump_pub_lwproc_rfork(0); if (rump_pub_netconfig_ifcreate(IFNAME) != 0) errx(1, "failed to create " IFNAME); if (rump_pub_netconfig_ipv4_ifaddr(IFNAME, IF_ADDR, "255.255.255.0") != 0) errx(1, "failed to create " IFNAME); //rump_pub_netconfig_dhcp_ipv4_oneshot(IFNAME); s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) err(1,"socket"); memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(ECHOSERVER_RX_PORT); server.sin_addr.s_addr = inet_addr(IF_ADDR); rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); if (rump_sys_bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) err(1, "binded"); printf("socket binded\r\n"); printf("Waiting connection on port = %d\r\n",ECHOSERVER_RX_PORT); memset(&client, 0, sizeof(client)); while(1) { memset(msg,0,sizeof(msg)); clen = sizeof(client); nn = rump_sys_recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&client,&clen); if (nn<0) { perror("Error receiving data"); } else { rump_sys_sendto(s,buf,nn,0,(struct sockaddr *)&client,clen); } } }
ATF_TC_BODY(makecn, tc) { struct componentname *cn; char pathstr[MAXPATHLEN] = TESTFILE; struct vnode *vp; extern struct vnode *rumpns_rootvnode; rump_init(); /* * Strategy is to create a componentname, edit the passed * string, and then do a lookup with the componentname. */ RL(rump_sys_mkdir("/" TESTFILE, 0777)); /* need stable lwp for componentname */ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); /* try it once with the right path */ cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); rump_pub_freecn(cn, RUMPCN_FREECRED); /* and then with modification-in-the-middle */ cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); strcpy(pathstr, "/muuta"); RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); rump_pub_freecn(cn, RUMPCN_FREECRED); }
ATF_TC_BODY(lwps, tc) { struct lwp *l[LOOPS]; pid_t mypid; struct lwp *l_orig; int i; rump_init(); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); mypid = rump_sys_getpid(); RL(rump_sys_setuid(375)); l_orig = rump_pub_lwproc_curlwp(); for (i = 0; i < LOOPS; i++) { mypid = rump_sys_getpid(); ATF_REQUIRE(mypid != -1 && mypid != 0); RZ(rump_pub_lwproc_newlwp(mypid)); l[i] = rump_pub_lwproc_curlwp(); ATF_REQUIRE_EQ(rump_sys_getuid(), 375); } rump_pub_lwproc_switch(l_orig); rump_pub_lwproc_releaselwp(); for (i = 0; i < LOOPS; i++) { rump_pub_lwproc_switch(l[i]); ATF_REQUIRE_EQ(rump_sys_getpid(), mypid); ATF_REQUIRE_EQ(rump_sys_getuid(), 375); rump_pub_lwproc_releaselwp(); ATF_REQUIRE_EQ(rump_sys_getpid(), 1); ATF_REQUIRE_EQ(rump_sys_getuid(), 0); } ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH); }
ATF_TC_BODY(inherit, tc) { rump_init(); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); RL(rump_sys_setuid(66)); ATF_REQUIRE_EQ(rump_sys_getuid(), 66); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); ATF_REQUIRE_EQ(rump_sys_getuid(), 66); /* release lwp and proc */ rump_pub_lwproc_releaselwp(); ATF_REQUIRE_EQ(rump_sys_getuid(), 0); }
static void dirperms(const atf_tc_t *tc, const char *mp) { char name[] = "dir.test/file.test"; char *dir = dirname(name); int fd; if (FSTYPE_SYSVBFS(tc)) atf_tc_skip("directories not supported by file system"); FSTEST_ENTER(); if (rump_sys_mkdir(dir, 0777) == -1) atf_tc_fail_errno("mkdir"); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be broken"); if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES) atf_tc_fail_errno("open"); rump_pub_lwproc_releaselwp(); if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) atf_tc_fail_errno("open"); if (rump_sys_close(fd) == -1) atf_tc_fail_errno("close"); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); if (rump_sys_unlink(name) != -1 || errno != EACCES) atf_tc_fail_errno("unlink"); rump_pub_lwproc_releaselwp(); if (rump_sys_unlink(name) == -1) atf_tc_fail_errno("unlink"); if (rump_sys_rmdir(dir) == -1) atf_tc_fail_errno("rmdir"); FSTEST_EXIT(); }
static void flags(const atf_tc_t *tc, const char *mp) { const char *name = "file.test"; int fd, fflags; struct stat st; FSTEST_ENTER(); if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) atf_tc_fail_errno("open"); if (rump_sys_close(fd) == -1) atf_tc_fail_errno("close"); if (rump_sys_stat(name, &st) == -1) atf_tc_fail_errno("stat"); if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be broken"); if (rump_sys_chflags(name, st.st_flags) == -1) { if (errno == EOPNOTSUPP) atf_tc_skip("file flags not supported by file system"); atf_tc_fail_errno("chflags"); } fflags = st.st_flags | UF_IMMUTABLE; rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); fflags |= UF_IMMUTABLE; if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) atf_tc_fail_errno("chflags"); rump_pub_lwproc_releaselwp(); if (rump_sys_chflags(name, fflags) == -1) atf_tc_fail_errno("chflags"); fflags &= ~UF_IMMUTABLE; if (rump_sys_chflags(name, fflags) == -1) atf_tc_fail_errno("chflags"); if (rump_sys_unlink(name) == -1) atf_tc_fail_errno("unlink"); FSTEST_EXIT(); }
static int precall(struct ukfs *ukfs, struct lwp **curlwp) { /* save previous. ensure start from pristine context */ *curlwp = rump_pub_lwproc_curlwp(); if (*curlwp) rump_pub_lwproc_switch(ukfs->ukfs_lwp); rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_chroot(ukfs->ukfs_mountpath) == -1) return errno; if (rump_sys_chdir(ukfs->ukfs_cwd) == -1) return errno; return 0; }
static void fcntl_lock(const atf_tc_t *tc, const char *mp) { int fd, fd2; struct flock l; struct lwp *lwp1, *lwp2; FSTEST_ENTER(); l.l_pid = 0; l.l_start = l.l_len = 1024; l.l_type = F_RDLCK | F_WRLCK; l.l_whence = SEEK_END; lwp1 = rump_pub_lwproc_curlwp(); RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755)); RL(rump_sys_ftruncate(fd, 8192)); /* PR kern/43321 */ if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be broken"); RL(rump_sys_fcntl(fd, F_SETLK, &l)); /* Next, we fork and try to lock the same area */ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); lwp2 = rump_pub_lwproc_curlwp(); RL(fd2 = rump_sys_open(TESTFILE, O_RDWR, 0)); ATF_REQUIRE_ERRNO(EAGAIN, rump_sys_fcntl(fd2, F_SETLK, &l)); /* Switch back and unlock... */ rump_pub_lwproc_switch(lwp1); l.l_type = F_UNLCK; RL(rump_sys_fcntl(fd, F_SETLK, &l)); /* ... and try to lock again */ rump_pub_lwproc_switch(lwp2); l.l_type = F_RDLCK | F_WRLCK; RL(rump_sys_fcntl(fd2, F_SETLK, &l)); RL(rump_sys_close(fd2)); rump_pub_lwproc_releaselwp(); RL(rump_sys_close(fd)); FSTEST_EXIT(); }
ATF_TC_BODY(makelwp, tc) { struct lwp *l; pid_t pid; rump_init(); RZ(rump_pub_lwproc_newlwp(0)); ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH); l = rump_pub_lwproc_curlwp(); RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); l = rump_pub_lwproc_curlwp(); RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); pid = rump_sys_getpid(); ATF_REQUIRE(pid != -1 && pid != 0); }
static void fcntl_getlock_pids(const atf_tc_t *tc, const char *mp) { /* test non-overlaping ranges */ struct flock expect[4]; const struct flock lock[4] = { { 0, 2, 0, F_WRLCK, SEEK_SET }, { 2, 1, 0, F_WRLCK, SEEK_SET }, { 7, 5, 0, F_WRLCK, SEEK_SET }, { 4, 3, 0, F_WRLCK, SEEK_SET }, }; /* Add extra element to make sure recursion does't stop at array end */ struct flock result[5]; /* Add 5th process */ int fd[5]; pid_t pid[5]; struct lwp *lwp[5]; unsigned int i, j; const off_t sz = 8192; int omode = 0755; int oflags = O_RDWR | O_CREAT; memcpy(expect, lock, sizeof(lock)); FSTEST_ENTER(); /* * First, we create 4 processes and let each lock a range of the * file. Note that the third and fourth processes lock in * "reverse" order, i.e. the greater pid locks a range before * the lesser pid. * Then, we create 5th process which doesn't lock anything. */ for (i = 0; i < __arraycount(lwp); i++) { RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); lwp[i] = rump_pub_lwproc_curlwp(); pid[i] = rump_sys_getpid(); RL(fd[i] = rump_sys_open(TESTFILE, oflags, omode)); oflags = O_RDWR; omode = 0; RL(rump_sys_ftruncate(fd[i], sz)); if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be " "broken"); if (i < __arraycount(lock)) { RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i])); expect[i].l_pid = pid[i]; } } qsort(expect, __arraycount(expect), sizeof(expect[0]), &flock_compare); /* * In the context of each process, recursively find all locks * that would block the current process. Processes 1-4 don't * see their own lock, we insert it to simplify checks. * Process 5 sees all 4 locks. */ for (i = 0; i < __arraycount(lwp); i++) { unsigned int nlocks; rump_pub_lwproc_switch(lwp[i]); memset(result, 0, sizeof(result)); nlocks = fcntl_getlocks(fd[i], 0, sz, result, result + __arraycount(result)); if (i < __arraycount(lock)) { ATF_REQUIRE(nlocks < __arraycount(result)); result[nlocks] = lock[i]; result[nlocks].l_pid = pid[i]; nlocks++; } ATF_CHECK_EQ(nlocks, __arraycount(expect)); qsort(result, nlocks, sizeof(result[0]), &flock_compare); for (j = 0; j < nlocks; j++) { ATF_CHECK_EQ(result[j].l_start, expect[j].l_start ); ATF_CHECK_EQ(result[j].l_len, expect[j].l_len ); ATF_CHECK_EQ(result[j].l_pid, expect[j].l_pid ); ATF_CHECK_EQ(result[j].l_type, expect[j].l_type ); ATF_CHECK_EQ(result[j].l_whence, expect[j].l_whence); } } /* * Release processes. This also releases the fds and locks * making fs unmount possible */ for (i = 0; i < __arraycount(lwp); i++) { rump_pub_lwproc_switch(lwp[i]); rump_pub_lwproc_releaselwp(); } FSTEST_EXIT(); }
static int mount_struct(_Bool verbose, struct mount_data_s *mntdp) { fsu_fs_t *fs; int rv; fs = mntdp->mntd_fs; /* * Switch the default process to the native syscalls. * The bad thing about this is that it will fail in unobvious * way if programs using this go multithreaded, but worry about * that if it happens. */ rump_i_know_what_i_am_doing_with_sysents = 1; rump_pub_lwproc_sysent_usenative(); rv = fs->fs_parseargs(mntdp->mntd_argc, mntdp->mntd_argv, fs->fs_args, &(mntdp->mntd_flags), mntdp->mntd_canon_dev, mntdp->mntd_canon_dir); if (rv != 0) return -1; if (rump_sys_mkdir(MOUNT_DIRECTORY, 0777) == -1 && errno != EEXIST) err(-1, "mkdir"); strcpy(mntdp->mntd_canon_dir, MOUNT_DIRECTORY); rv = fsu_load_fs(fs->fs_name); if (rv == 0) { rv = rump_sys_mount(fs->fs_name, mntdp->mntd_canon_dir, mntdp->mntd_flags, fs->fs_args, fs->fs_args_size); #if 0 /* * This will result in a lot of spam for fs type autodetection, * so need to come up with a better scheme here. */ if (rv == -1) warn("mount failed"); #endif } if (rv == 0) { /* fork a rump kernel process to chroot() to the mountpoint */ if ((rv = rump_pub_lwproc_rfork(RUMP_RFCFDG)) != 0) { warnx("fork failed!"); rump_sys_unmount(MOUNT_DIRECTORY, 0); } else { atexit(fsu_unmount); rump_sys_chroot(MOUNT_DIRECTORY); } } #ifdef WITH_SMBFS if (strcmp(fs->fs_name, MOUNT_SMBFS) == 0) { extern struct smb_ctx sctx; smb_ctx_done(&sctx); } #endif if (rv != 0 && verbose) { warn(NULL); fprintf(stderr, "%s is not a valid %s image\n", mntdp->mntd_fsdevice, fs->fs_name); } return rv; }