mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 19:06:34 +00:00
fix(terminal+journal): use systemd-run to escape NoNewPrivileges
The kiosk runs under NoNewPrivileges=yes (WebKit bwrap needs it). sudo and nsenter both fail because they need privilege escalation which the flag blocks. systemd-run --pipe spawns a SEPARATE service unit as root in its own process tree, connected via stdin/stdout pipe. Not a child of the kiosk process → NoNewPrivileges doesn't apply. Also: enable rauc.service in pi-gen chroot (was never enabled → RAUC daemon not running → rauc install fails → OS update silently broken).
This commit is contained in:
parent
6244fe26e0
commit
16412d5ad6
2 changed files with 25 additions and 11 deletions
|
|
@ -159,6 +159,7 @@ update-alternatives --install /usr/share/icons/default/index.theme x-cursor-them
|
||||||
systemctl enable seatd
|
systemctl enable seatd
|
||||||
systemctl enable betterframe-kiosk.service
|
systemctl enable betterframe-kiosk.service
|
||||||
systemctl enable betterframe-rauc-mark-good.service
|
systemctl enable betterframe-rauc-mark-good.service
|
||||||
|
systemctl enable rauc.service 2>/dev/null || true
|
||||||
|
|
||||||
# Boot to multi-user, no display manager, no welcome wizard, no getty on tty1.
|
# Boot to multi-user, no display manager, no welcome wizard, no getty on tty1.
|
||||||
systemctl set-default multi-user.target
|
systemctl set-default multi-user.target
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,13 @@ impl JournalStream {
|
||||||
let kill_clone = kill.clone();
|
let kill_clone = kill.clone();
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
// Use sudo so bfkiosk user can read system journal.
|
// Use systemd-run to escape NoNewPrivileges and read journal as root.
|
||||||
let mut child = match Command::new("sudo")
|
let mut child = match Command::new("systemd-run")
|
||||||
.args(["journalctl", "-u", "betterframe-kiosk", "-f", "--no-pager", "-o", "short-iso", "-n", "50"])
|
.args([
|
||||||
|
"--pipe", "--quiet", "--service-type=exec",
|
||||||
|
"--property=User=root",
|
||||||
|
"journalctl", "-u", "betterframe-kiosk", "-f", "--no-pager", "-o", "short-iso", "-n", "50",
|
||||||
|
])
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
|
|
@ -219,18 +223,27 @@ pub struct TerminalSession {
|
||||||
|
|
||||||
impl TerminalSession {
|
impl TerminalSession {
|
||||||
pub fn spawn() -> Result<(Self, std::process::ChildStdout, std::process::ChildStderr), String> {
|
pub fn spawn() -> Result<(Self, std::process::ChildStdout, std::process::ChildStderr), String> {
|
||||||
// Run as root so the operator can actually fix things (journal,
|
// The kiosk runs under NoNewPrivileges=yes (WebKit bwrap needs
|
||||||
// rauc, systemctl, usermod). The on-screen code + lockout ladder
|
// it), which blocks sudo/nsenter from this process tree. Use
|
||||||
// gates access; once past that, full root is the point.
|
// systemd-run to spawn a SEPARATE service unit that runs bash
|
||||||
let mut child = Command::new("sudo")
|
// as root in its own process tree — not a child of the kiosk.
|
||||||
.args(["bash", "--login"])
|
// The --pipe flag connects stdin/stdout/stderr to our process.
|
||||||
|
let mut child = Command::new("systemd-run")
|
||||||
|
.args([
|
||||||
|
"--pipe", // connect stdio to us
|
||||||
|
"--quiet", // suppress service info on stderr
|
||||||
|
"--service-type=exec",
|
||||||
|
"--property=User=root",
|
||||||
|
"-E", "TERM=xterm-256color",
|
||||||
|
"-E", "HOME=/root",
|
||||||
|
"bash", "--login",
|
||||||
|
])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.env("TERM", "xterm-256color")
|
|
||||||
.spawn()
|
.spawn()
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
// Fallback if sudo not available / not configured for bfkiosk.
|
// Fallback: plain bash as bfkiosk (limited but something).
|
||||||
Command::new("bash")
|
Command::new("bash")
|
||||||
.args(["--login"])
|
.args(["--login"])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
|
|
@ -239,7 +252,7 @@ impl TerminalSession {
|
||||||
.env("TERM", "xterm-256color")
|
.env("TERM", "xterm-256color")
|
||||||
.spawn()
|
.spawn()
|
||||||
})
|
})
|
||||||
.map_err(|e| format!("bash spawn: {e}"))?;
|
.map_err(|e| format!("shell spawn: {e}"))?;
|
||||||
|
|
||||||
let stdout = child.stdout.take().ok_or("no stdout")?;
|
let stdout = child.stdout.take().ok_or("no stdout")?;
|
||||||
let stderr = child.stderr.take().ok_or("no stderr")?;
|
let stderr = child.stderr.take().ok_or("no stderr")?;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue