Claim that /zip itself is user-modifiable

This is in line with what I have learned about the TOCTOU stuff
regarding ape executables. If there is ever a check for whether
we are running in a secure set-id context, this can be disabled
by that check.

Adds basic sanity test for zipos stat as well.
This commit is contained in:
Jōshin 2023-12-17 12:31:37 -05:00
parent 77facc4f7b
commit f0971b6909
No known key found for this signature in database
2 changed files with 20 additions and 0 deletions

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
@ -34,6 +35,12 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
if (cf == ZIPOS_SYNTHETIC_DIRECTORY) { if (cf == ZIPOS_SYNTHETIC_DIRECTORY) {
st->st_mode = S_IFDIR | (0555 & ~atomic_load_explicit( st->st_mode = S_IFDIR | (0555 & ~atomic_load_explicit(
&__umask, memory_order_acquire)); &__umask, memory_order_acquire));
/* report that /zip is user-modifiable to clarify to programs that check
transitive writability of a secure file like doas.conf. at this time,
doas itself does not actually do this check (it only checks the file)
but it probably ought to. */
st->st_uid = getuid();
st->st_mode |= S_IWUSR;
} else { } else {
lf = GetZipCfileOffset(zipos->map + cf); lf = GetZipCfileOffset(zipos->map + cf);
st->st_mode = GetZipCfileMode(zipos->map + cf); st->st_mode = GetZipCfileMode(zipos->map + cf);

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/sysv/consts/s.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/gc.h" #include "libc/mem/gc.h"
@ -113,6 +114,18 @@ TEST(zipos, lseek) {
EXPECT_SYS(0, 0, close(3)); EXPECT_SYS(0, 0, close(3));
} }
TEST(zipos, stat) {
struct stat st;
umask(0777);
ASSERT_SYS(0, 0, stat("/zip", &st));
EXPECT_EQ(getuid(), st.st_uid);
EXPECT_TRUE(S_ISDIR(st.st_mode));
EXPECT_TRUE((st.st_mode & S_IWUSR) != 0);
ASSERT_SYS(0, 0, stat("/zip/libc/testlib/hyperion.txt", &st));
EXPECT_EQ(0, st.st_uid);
EXPECT_EQ(0100644, st.st_mode);
}
TEST(zipos, closeAfterVfork) { TEST(zipos, closeAfterVfork) {
ASSERT_SYS(0, 3, open("/zip/libc/testlib/hyperion.txt", O_RDONLY)); ASSERT_SYS(0, 3, open("/zip/libc/testlib/hyperion.txt", O_RDONLY));
SPAWN(vfork); SPAWN(vfork);