static void setup(void) { struct stat c_buf, l_buf; if ((tst_kvercmp(2, 6, 16)) < 0) tst_brkm(TCONF, NULL, "This test needs kernel 2.6.16 or newer"); tst_require_root(NULL); tst_sig(NOFORK, DEF_HANDLER, cleanup); TEST_PAUSE; tst_tmpdir(); dirfd = SAFE_OPEN(cleanup, "./", O_DIRECTORY); SAFE_TOUCH(cleanup, TESTFILE, 0600, NULL); SAFE_SYMLINK(cleanup, TESTFILE, TESTFILE_LINK); SAFE_STAT(cleanup, TESTFILE_LINK, &c_buf); SAFE_LSTAT(cleanup, TESTFILE_LINK, &l_buf); if (l_buf.st_uid == set_uid || l_buf.st_gid == set_gid) { tst_brkm(TBROK | TERRNO, cleanup, "link_uid(%d) == set_uid(%d) or link_gid(%d) == " "set_gid(%d)", l_buf.st_uid, set_uid, l_buf.st_gid, set_gid); } }
/* * We try raising bdi readahead limit as much as we can. We write * and read back "read_ahead_kb" sysfs value, starting with filesize. * If that fails, we try again with lower value. * readahead_length used in the test is then set to MIN(bdi limit, 2M), * to respect kernels prior to commit 600e19afc5f8a6c. */ static void setup_readahead_length(void) { struct stat sbuf; char tmp[PATH_MAX], *backing_dev; int ra_new_limit, ra_limit; /* Find out backing device name */ SAFE_LSTAT(tst_device->dev, &sbuf); if (S_ISLNK(sbuf.st_mode)) SAFE_READLINK(tst_device->dev, tmp, PATH_MAX); else strcpy(tmp, tst_device->dev); backing_dev = basename(tmp); sprintf(sys_bdi_ra_path, "/sys/class/block/%s/bdi/read_ahead_kb", backing_dev); if (access(sys_bdi_ra_path, F_OK)) return; SAFE_FILE_SCANF(sys_bdi_ra_path, "%d", &orig_bdi_limit); /* raise bdi limit as much as kernel allows */ ra_new_limit = testfile_size / 1024; while (ra_new_limit > pagesize / 1024) { FILE_PRINTF(sys_bdi_ra_path, "%d", ra_new_limit); SAFE_FILE_SCANF(sys_bdi_ra_path, "%d", &ra_limit); if (ra_limit == ra_new_limit) { readahead_length = MIN(ra_new_limit * 1024, 2 * 1024 * 1024); break; } ra_new_limit = ra_new_limit / 2; } }
static void test_verify(void) { struct stat c_buf, l_buf; SAFE_STAT(cleanup, TESTFILE_LINK, &c_buf); SAFE_LSTAT(cleanup, TESTFILE_LINK, &l_buf); if (c_buf.st_uid != set_uid && l_buf.st_uid == set_uid && c_buf.st_gid != set_gid && l_buf.st_gid == set_gid) { tst_resm(TPASS, "fchownat() test AT_SYMLINK_NOFOLLOW success"); } else { tst_resm(TFAIL, "fchownat() test AT_SYMLINK_NOFOLLOW fail with uid=%d " "link_uid=%d set_uid=%d | gid=%d link_gid=%d " "set_gid=%d", c_buf.st_uid, l_buf.st_uid, set_uid, c_buf.st_gid, l_buf.st_gid, set_gid); } }