diff --git a/apps/init.cpp b/apps/init.cpp index baf907da..cc7a8e69 100644 --- a/apps/init.cpp +++ b/apps/init.cpp @@ -272,6 +272,8 @@ int main() stdout = fopen("/dev/console", "w"); stderr = fopen("/dev/console", "w"); + umask(022); + g_init_log = fopen("/init.log", "w+"); fcntl(fileno(g_init_log), F_SETFD, FD_CLOEXEC); diff --git a/apps/mkdir.cpp b/apps/mkdir.cpp index 200b6a12..d2562a40 100644 --- a/apps/mkdir.cpp +++ b/apps/mkdir.cpp @@ -2,6 +2,14 @@ #include #include #include +#include + +static mode_t s_umask = 0; + +static void read_umask() +{ + s_umask = umask(0); +} Result mkdir_recursively(StringView path, mode_t mode) { @@ -15,7 +23,7 @@ begin: PathParser parser = TRY(PathParser::create(path.chars())); auto parent = TRY(parser.dirname()); - TRY(mkdir_recursively(parent.view(), mode)); + TRY(mkdir_recursively(parent.view(), (0777 & ~s_umask) | S_IWUSR | S_IXUSR)); goto begin; } @@ -33,12 +41,18 @@ Result luna_main(int argc, char** argv) parser.add_description("Create directories."_sv); parser.add_system_program_info("mkdir"_sv); parser.add_positional_argument(path, "path"_sv, true); - parser.add_positional_argument(mode_string, "mode"_sv, "755"_sv); + parser.add_value_argument(mode_string, 'm', "mode"_sv, true, "set the mode for the newly created directory"); parser.add_switch_argument(recursive, 'p', "parents"_sv, "if parent directories do not exist, create them as well"_sv); parser.parse(argc, argv); - mode_t mode = (mode_t)parse_unsigned_integer(mode_string.chars(), nullptr, 8); + read_umask(); + + mode_t mode; + + if (mode_string.is_empty()) mode = 0777 & ~s_umask; + else + mode = (mode_t)parse_unsigned_integer(mode_string.chars(), nullptr, 8) & 01777; if (recursive) { diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index 9ab10568..8cb10be2 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -134,6 +134,7 @@ Result sys_fork(Registers* regs, SyscallArgs) thread->auth = current->auth; thread->current_directory = current->current_directory; thread->current_directory_path = move(current_directory_path); + thread->umask = current->umask; thread->parent = current; for (int i = 0; i < FD_MAX; i++) diff --git a/kernel/src/sys/file.cpp b/kernel/src/sys/file.cpp index 735d224a..3838af14 100644 --- a/kernel/src/sys/file.cpp +++ b/kernel/src/sys/file.cpp @@ -194,3 +194,16 @@ Result sys_pipe(Registers*, SyscallArgs args) return 0; } + +Result sys_umask(Registers*, SyscallArgs args) +{ + mode_t new_umask = (mode_t)args[0]; + + auto* current = Scheduler::current(); + + mode_t old_umask = current->umask; + + current->umask = new_umask & 0777; + + return old_umask; +} diff --git a/kernel/src/sys/mkdir.cpp b/kernel/src/sys/mkdir.cpp index 19b5fbb1..e961d0a3 100644 --- a/kernel/src/sys/mkdir.cpp +++ b/kernel/src/sys/mkdir.cpp @@ -12,7 +12,7 @@ Result sys_mkdir(Registers*, SyscallArgs args) Thread* current = Scheduler::current(); auto inode = TRY(VFS::create_directory(path.chars(), current->auth, current->current_directory)); - inode->chmod(mode); + inode->chmod(mode & ~current->umask); inode->chown(current->auth.euid, current->auth.egid); return 0; diff --git a/kernel/src/sys/open.cpp b/kernel/src/sys/open.cpp index fb239854..abe904b5 100644 --- a/kernel/src/sys/open.cpp +++ b/kernel/src/sys/open.cpp @@ -38,7 +38,7 @@ Result sys_openat(Registers*, SyscallArgs args) if (error == ENOENT && (flags & O_CREAT) && !path.is_empty()) { inode = TRY(VFS::create_file(path.chars(), current->auth, parent_inode)); - inode->chmod(mode); + inode->chmod(mode & ~current->umask); inode->chown(current->auth.euid, current->auth.egid); } else diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index 0aebd05f..7c02dadf 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -87,6 +87,8 @@ struct Thread : public LinkedListNode u8 status { 0 }; + mode_t umask { 0 }; + StaticString<128> name; String current_directory_path = {}; diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index b8b3d192..cc603372 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -38,6 +38,9 @@ extern "C" /* Retrieve information about a file. */ int fstatat(int dirfd, const char* path, struct stat* st, int flags); + /* Change the process's file creation mask. */ + mode_t umask(mode_t mask); + #ifdef __cplusplus } #endif diff --git a/libc/src/sys/stat.cpp b/libc/src/sys/stat.cpp index d4ffa1e8..0a2a312e 100644 --- a/libc/src/sys/stat.cpp +++ b/libc/src/sys/stat.cpp @@ -47,4 +47,9 @@ extern "C" long rc = syscall(SYS_fstatat, dirfd, path, st, flags); __errno_return(rc, int); } + + mode_t umask(mode_t mask) + { + return (mode_t)syscall(SYS_umask, mask); + } } diff --git a/libluna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h index f450dde6..0a9583a4 100644 --- a/libluna/include/luna/Syscall.h +++ b/libluna/include/luna/Syscall.h @@ -5,7 +5,7 @@ _e(lseek) _e(mkdir) _e(execve) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) _e(geteuid) \ _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \ _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \ - _e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) + _e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) enum Syscalls {