The kernel now checks owner/group/other on open, create, unlink, rename, exec and path search; honours set-user-id and set-group-id; restricts kill, mount, reboot and mknod; keeps supplementary groups; and implements chown. devtmpfs nodes carry owners and modes that chmod/chown keep. Terminals run login, the image has root and schos, X starts as the ordinary user. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
4.2 KiB
Users and permissions
SchOS has accounts, a login prompt, and file permissions that the kernel
enforces. Until now every process was root and uid was bookkeeping; this is
the part that makes it a multi-user system.
What you meet
loginon tty1–tty5.etc/schos-gettytakes the terminal back from whoever had it and runslogin, which asks who is there and starts their shell; when the shell exitsschinitstarts the prompt again.- tty6 is a root shell with no login, on purpose: the way in when login itself is what is broken.
- Two accounts in the image.
root, andschos(uid 1000, home/home/schos, inwheel tty video input audio cdrom). Both have empty passwords, sologinlets them in without asking — it is a live image.passwdsets one. suandpasswd(cmd/su,cmd/passwd) are setuid root and small programs of their own, not toybox applets: toybox is one binary under every name, and a setuid copy of it can be asked for any applet by naming it, as root.suto root takes membership inwheel, whatever the password.doas(Alpine's, setuid) withpermit nopass :wheelin/etc/doas.conf.
What the kernel enforces
| open, create, unlink, rename, link | the usual owner/group/other bits, w+x on the directory, and the sticky bit (/tmp) |
| path walk | x on every directory searched |
exec |
x on the file; set-user-id and set-group-id make the new image run as its owner or group, and the saved ids follow |
chmod, chown, utimensat |
owner or root; a non-root chown drops the set-id bits |
access / faccessat |
by the real ids (AT_EACCESS for the effective ones) |
kill, tkill, tgkill |
root, or a target whose real or saved uid is one of yours. The kernel's own signals (SIGPIPE, the terminal's) are nobody's to refuse |
mount, umount, chroot, reboot, shutdown, setgroups, mknod of a device |
root |
setuid family |
root may set anything; anyone else only to an id they already hold |
Root reads and writes everything and executes a file only if some execute bit
is set. A process's supplementary groups (setgroups) are consulted along with
its effective group. Ownership is stored by SchFS (it always had the fields);
FAT volumes belong to everyone, since they cannot say otherwise, and /proc
and /sys are root's.
inode_permission() in kernel/fs/fs.c is the one check; the rest of this is
call sites.
Devices
/dev is built by the kernel and each node has the owner, group and mode in the
devnodes[] table of kernel/fs/devfs.c: null and zero are 0666,
terminals root:tty 0660, fb0 root:video, input root:input, raw disks
root:disk, pci, dbg and netdev root's alone. chmod and chown on a
node are kept (login claims its terminal this way, and udev sets modes) in an
override table applied whenever the inode is loaded. A new pseudo-terminal's
slave belongs to whoever opened ptmx.
udev would set a node it has no rule for to 0600, which made /dev/null
root-only, so etc/udev-schos.rules (installed as 90-schos.rules) names the
kernel's devices with the answers the kernel gave.
The image
Everything in the image is owned by root: the build host's user means nothing
inside it. mkschfs --owners FILE takes the exceptions, one path uid gid [mode] per line (tools/posix/mkaroot.sh writes it: /home/schos 1000 1000 0700, and the modes of /tmp, /var/tmp and /root). The setuid bits are set
on su, passwd and doas in the root tree directly, because apk run as an
ordinary user may have dropped them.
Not done
- No PAM and no
/etc/securetty.loginis busybox's and checks/etc/shadowitself. - No capabilities. Root is
euid == 0, all of it. - No per-user
/run, no logind. X as a non-root user works (startxasschos, under QEMU: Window Maker up) by group permission alone — video, input and tty — and/etc/X11/Xwrapper.configlets anyone start it, because the wrapper's "console users" test looks for a Linux VT on a standard descriptor that xinit's server child does not keep. /procand/syshide nothing from other users.mprotectis still not enforced (kernel.md).