test: test more of sfsTest
This commit is contained in:
1 parent
f99e8eeed4
commit
28a39f4234
1 file changed
+157
+157
@@ -624,3 +624,160 @@ KTEST(sfsChownReassignsOwnerAndBumpsCtime)
|
|||||||
KT_FALSE(t, sfsChown(9999, 1000));
|
KT_FALSE(t, sfsChown(9999, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Same real point as sfsPersistsUidAcrossUnmountRemount above, but for a
|
||||||
|
uid REASSIGNED by sfsChown after creation, not just the creation-time
|
||||||
|
default -- proves the chown write path itself lands on disk, not just
|
||||||
|
that createNode's own initial stamp does. */
|
||||||
|
KTEST(sfsPersistsChownedUidAcrossUnmountRemount)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 f = sfsCreateFile("chownpersist.txt");
|
||||||
|
if (!KT_TRUE(t, f > 0))
|
||||||
|
return;
|
||||||
|
KT_TRUE(t, sfsChown(f, 8123));
|
||||||
|
|
||||||
|
sfsUnmount();
|
||||||
|
KT_TRUE(t, sfsMount());
|
||||||
|
|
||||||
|
int32 reloaded = sfsLookup("chownpersist.txt");
|
||||||
|
KT_EQ(t, reloaded, f);
|
||||||
|
KT_EQU(t, sfsUidOf(reloaded), 8123u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real chgrp(2)'s on-disk half (sfsChgrp), mirroring
|
||||||
|
sfsChownReassignsOwnerAndBumpsCtime exactly one field over -- same "no
|
||||||
|
privilege check of its own, ctime bumps, invalid inode fails the same
|
||||||
|
way" shape. */
|
||||||
|
KTEST(sfsChgrpReassignsGroupAndBumpsCtime)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 f = sfsCreateFile("chgrpfile.txt");
|
||||||
|
if (!KT_TRUE(t, f > 0))
|
||||||
|
return;
|
||||||
|
KT_EQU(t, sfsGidOf(f), 0u);
|
||||||
|
|
||||||
|
uint64 ctimeBefore = sfsCtimeOf(f);
|
||||||
|
int64 before = rtcNow();
|
||||||
|
KT_TRUE(t, sfsChgrp(f, 9002));
|
||||||
|
int64 after = rtcNow();
|
||||||
|
|
||||||
|
KT_EQU(t, sfsGidOf(f), 9002u);
|
||||||
|
KT_GE(t, sfsCtimeOf(f), ctimeBefore);
|
||||||
|
KT_GE(t, sfsCtimeOf(f), before);
|
||||||
|
KT_LE(t, sfsCtimeOf(f), after);
|
||||||
|
|
||||||
|
KT_FALSE(t, sfsChgrp(-1, 1000));
|
||||||
|
KT_FALSE(t, sfsChgrp(9999, 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same real point as sfsPersistsChownedUidAcrossUnmountRemount above, one
|
||||||
|
field over: proves the chgrp write path itself lands on disk. */
|
||||||
|
KTEST(sfsPersistsChgrpedGidAcrossUnmountRemount)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 f = sfsCreateFile("chgrppersist.txt");
|
||||||
|
if (!KT_TRUE(t, f > 0))
|
||||||
|
return;
|
||||||
|
KT_TRUE(t, sfsChgrp(f, 7124));
|
||||||
|
|
||||||
|
sfsUnmount();
|
||||||
|
KT_TRUE(t, sfsMount());
|
||||||
|
|
||||||
|
int32 reloaded = sfsLookup("chgrppersist.txt");
|
||||||
|
KT_EQ(t, reloaded, f);
|
||||||
|
KT_EQU(t, sfsGidOf(reloaded), 7124u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real directory-write enforcement at the on-disk choke point (sfs.c's
|
||||||
|
createNode, shared by sfsCreateFile/sfsCreateDir/sfsCreateFifo/
|
||||||
|
sfsCreateSymlink) -- mirrors coreTest.c's tmpfs
|
||||||
|
coreVfsMkdirAndCreateRequireParentWrite for the SFS backing store.
|
||||||
|
ktestRunAll always runs as uid 0, and vfsPermitted has no uid-0 bypass,
|
||||||
|
so removing the parent's own owner-write bit denies even its own
|
||||||
|
creator/owner. */
|
||||||
|
KTEST(sfsCreateNodeRequiresParentWrite)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsCreateDir("dwparent") > 0);
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("dwparent"), 0555)); /* r-x, no owner-write */
|
||||||
|
|
||||||
|
KT_EQ(t, sfsCreateFile("dwparent/f"), -1);
|
||||||
|
KT_EQ(t, sfsCreateDir("dwparent/sub"), -1);
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("dwparent"), fsModeDefaultDir));
|
||||||
|
KT_TRUE(t, sfsCreateFile("dwparent/f") > 0);
|
||||||
|
KT_TRUE(t, sfsCreateDir("dwparent/sub") > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same parent-write rule applied to sfsLink -- adding a new hardlink NAME
|
||||||
|
is a directory-entry creation exactly like sfsCreateFile, so it needs
|
||||||
|
write permission on the PARENT of the new name, not any permission on
|
||||||
|
the existing target being linked to. */
|
||||||
|
KTEST(sfsLinkRequiresParentWriteOnNewName)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsCreateFile("lwtarget.txt") > 0);
|
||||||
|
KT_TRUE(t, sfsCreateDir("lwparent") > 0);
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("lwparent"), 0555));
|
||||||
|
|
||||||
|
KT_EQ(t, sfsLink("lwtarget.txt", "lwparent/alias"), -1);
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("lwparent"), fsModeDefaultDir));
|
||||||
|
KT_TRUE(t, sfsLink("lwtarget.txt", "lwparent/alias") > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real unlink(2)/rmdir(2) semantics at the on-disk choke point (sfs.c's
|
||||||
|
sfsRemove) -- mirrors coreTest.c's tmpfs
|
||||||
|
coreVfsUnlinkAndRmdirRequireParentWrite: removing an entry needs write
|
||||||
|
permission on the PARENT, never the entry's own mode. */
|
||||||
|
KTEST(sfsRemoveRequiresParentWrite)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsCreateDir("rwparent") > 0);
|
||||||
|
KT_TRUE(t, sfsCreateFile("rwparent/f") > 0);
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("rwparent"), 0555));
|
||||||
|
KT_FALSE(t, sfsRemove("rwparent/f"));
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("rwparent"), fsModeDefaultDir));
|
||||||
|
KT_TRUE(t, sfsRemove("rwparent/f"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real POSIX search permission at the on-disk choke point (sfs.c's
|
||||||
|
lookupFrom, checked on every directory ANCESTOR a path walks through) --
|
||||||
|
mirrors coreTest.c's tmpfs coreVfsLookupRequiresAncestorExec. Removing
|
||||||
|
the exec bit on an ancestor makes every lookup THROUGH it fail even
|
||||||
|
though the target inode itself never changed. */
|
||||||
|
KTEST(sfsLookupRequiresAncestorExec)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsCreateDir("xancestor") > 0);
|
||||||
|
int32 leaf = sfsCreateFile("xancestor/leaf");
|
||||||
|
KT_TRUE(t, leaf > 0);
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("xancestor"), 0600)); /* rw-, no exec */
|
||||||
|
KT_EQ(t, sfsLookup("xancestor/leaf"), -1);
|
||||||
|
|
||||||
|
KT_TRUE(t, sfsChmod(sfsLookup("xancestor"), fsModeDefaultDir));
|
||||||
|
KT_EQ(t, sfsLookup("xancestor/leaf"), leaf);
|
||||||
|
}
|
||||||
|
|
||||||
|
KTEST(sfsSymlinkResolvesToTargetFile)
|
||||||
|
{
|
||||||
|
if (!KT_TRUE(t, sfsFormat()))
|
||||||
|
return;
|
||||||
|
|
||||||
Reference in new issue
Block a user