- tty1-tty12 all run login; the image has only root. /dev/tty7..12 could not be written (cdev.c knew minors 10-16 only), which sent their jobs into a restart storm that took the supervisor down; fixed, and stat reports them as Linux's tty7..12. - Erasing text at a prompt did nothing: erase_one sent a bare backspace, which only moves; it and the echo path now send back-blank-back through vt_feed. - A white cursor block was left at the end of every line of a verbose boot: a line feed at the bottom scrolls the pixels, cursor included, and the cursor was erased after the scroll. It comes off first now. A blank cell is also marked dirty, which it was not. - ldlsd died with a general protection fault on real hardware in its variadic log function: Linux module code calls with an 8-byte-aligned stack and an unset %al, and the prologue's movaps faults. LDLS guest code is built with -mstackrealign. - make iso took over a minute for any change, because staging r8169 rewrote the same files and every mtime moved; it now replaces files only if their contents differ (about 10 s). - The loader's splash is redrawn in the boot manager's style, and the boot manager shows its cursor whenever a pointer device exists. - xf86-input-libinput is out of the image again: with it Xorg took both keyboard and pointer from libinput and, on the user's laptop, neither worked. 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 all twelve terminals, tty1–tty12.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. Alt+F1…F12 (or Ctrl+Alt+F1…F12) switches between them. (There is no longer a login-free root shell on tty6.)- One account in the image:
root, with an empty password, sologinlets it in without asking — it is a live image.passwdsets one. More users are anadduseraway;wheelis empty, sosuanddoashave no one to serve until then. 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: 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).