aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--internal/app/seal.go3
-rw-r--r--internal/linux/interface.go1
-rw-r--r--internal/linux/std.go18
-rw-r--r--main.go3
-rw-r--r--print.go5
-rw-r--r--test.nix21
6 files changed, 40 insertions, 11 deletions
diff --git a/internal/app/seal.go b/internal/app/seal.go
index 6ad7edb3..3ac31c8d 100644
--- a/internal/app/seal.go
+++ b/internal/app/seal.go
@@ -149,8 +149,7 @@ func (a *app) Seal(config *fst.Config) error {
// invoke fsu for full uid
if u, err := a.os.Uid(seal.sys.user.aid); err != nil {
- return fmsg.WrapErrorSuffix(err,
- "cannot obtain uid from fsu:")
+ return err
} else {
seal.sys.user.uid = u
seal.sys.user.us = strconv.Itoa(u)
diff --git a/internal/linux/interface.go b/internal/linux/interface.go
index cf25ecb1..762414c8 100644
--- a/internal/linux/interface.go
+++ b/internal/linux/interface.go
@@ -37,6 +37,7 @@ type System interface {
// Paths returns a populated [Paths] struct.
Paths() Paths
// Uid invokes fsu and returns target uid.
+ // Any errors returned by Uid is already wrapped [fmsg.BaseError].
Uid(aid int) (int, error)
}
diff --git a/internal/linux/std.go b/internal/linux/std.go
index fceba95f..89338f19 100644
--- a/internal/linux/std.go
+++ b/internal/linux/std.go
@@ -2,6 +2,7 @@ package linux
import (
"errors"
+ "fmt"
"io/fs"
"log"
"os"
@@ -56,13 +57,15 @@ func (s *Std) Uid(aid int) (int, error) {
})
})
- s.uidMu.RLock()
- if u, ok := s.uidCopy[aid]; ok {
+ {
+ s.uidMu.RLock()
+ u, ok := s.uidCopy[aid]
s.uidMu.RUnlock()
- return u.uid, u.err
+ if ok {
+ return u.uid, u.err
+ }
}
- s.uidMu.RUnlock()
s.uidMu.Lock()
defer s.uidMu.Unlock()
@@ -91,8 +94,13 @@ func (s *Std) Uid(aid int) (int, error) {
if p, u.err = cmd.Output(); u.err == nil {
u.uid, u.err = strconv.Atoi(string(p))
+ if u.err != nil {
+ u.err = fmsg.WrapErrorSuffix(u.err, "cannot parse uid from fsu:")
+ }
} else if errors.As(u.err, &exitError) && exitError != nil && exitError.ExitCode() == 1 {
- u.err = syscall.EACCES
+ u.err = fmsg.WrapError(syscall.EACCES, "") // fsu prints to stderr in this case
+ } else if os.IsNotExist(u.err) {
+ u.err = fmsg.WrapError(os.ErrNotExist, fmt.Sprintf("the setuid helper is missing: %s", fsu))
}
return u.uid, u.err
}
diff --git a/main.go b/main.go
index 14ca352c..8aec22d6 100644
--- a/main.go
+++ b/main.go
@@ -228,7 +228,8 @@ func main() {
passwdFunc = func() {
var us string
if uid, err := sys.Uid(aid); err != nil {
- log.Fatalf("cannot obtain uid from fsu: %v", err)
+ fmsg.PrintBaseError(err, "cannot obtain uid from fsu:")
+ os.Exit(1)
} else {
us = strconv.Itoa(uid)
}
diff --git a/print.go b/print.go
index 3c0c219d..1022ae11 100644
--- a/print.go
+++ b/print.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"log"
+ "os"
"slices"
"strconv"
"strings"
@@ -13,6 +14,7 @@ import (
"git.gensokyo.uk/security/fortify/dbus"
"git.gensokyo.uk/security/fortify/fst"
+ "git.gensokyo.uk/security/fortify/internal/fmsg"
"git.gensokyo.uk/security/fortify/internal/state"
)
@@ -24,7 +26,8 @@ func printShowSystem(output io.Writer, short bool) {
// get fid by querying uid of aid 0
if uid, err := sys.Uid(0); err != nil {
- log.Fatalf("cannot obtain uid from fsu: %v", err)
+ fmsg.PrintBaseError(err, "cannot obtain uid from fsu:")
+ os.Exit(1)
} else {
info.User = (uid / 10000) - 100
}
diff --git a/test.nix b/test.nix
index 6fdb249b..c85d3c6c 100644
--- a/test.nix
+++ b/test.nix
@@ -18,7 +18,12 @@ nixosTest {
skipTypeCheck = true;
nodes.machine =
- { lib, pkgs, ... }:
+ {
+ lib,
+ pkgs,
+ config,
+ ...
+ }:
{
users.users = {
alice = {
@@ -32,6 +37,9 @@ nixosTest {
description = "Untrusted user";
password = "foobar";
uid = 1001;
+
+ # For deny unmapped uid test:
+ packages = [ config.environment.fortify.package ];
};
};
@@ -284,7 +292,16 @@ nixosTest {
machine.wait_for_file("/tmp/sway-ipc.sock")
# Deny unmapped uid:
- print(machine.fail("sudo -u untrusted -i ${self.packages.${system}.fortify}/bin/fortify -v run"))
+ denyOutput = machine.fail("sudo -u untrusted -i fortify run &>/dev/stdout")
+ print(denyOutput)
+ denyOutputVerbose = machine.fail("sudo -u untrusted -i fortify -v run &>/dev/stdout")
+ print(denyOutputVerbose)
+
+ # Verify PrintBaseError behaviour:
+ if denyOutput != "fsu: uid 1001 is not in the fsurc file\n":
+ raise Exception(f"unexpected deny output:\n{denyOutput}")
+ if denyOutputVerbose != "fsu: uid 1001 is not in the fsurc file\nfortify: *cannot obtain uid from fsu: permission denied\n":
+ raise Exception(f"unexpected deny verbose output:\n{denyOutputVerbose}")
# Start fortify permissive defaults outside Wayland session:
print(machine.succeed("sudo -u alice -i fortify -v run -a 0 touch /tmp/success-bare"))