Smail/backend/services/adminreset/numeric_security_linux_test.go
smail 37bb937c40
Some checks are pending
Security Checks / security (push) Waiting to run
加固管理员恢复边界并补充三库实机与安全复扫验收
2026-09-21 04:21:14 +08:00

97 lines
2.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build linux
package adminreset
import (
"context"
"errors"
"math"
"os"
"os/exec"
"path/filepath"
"strconv"
"testing"
"golang.org/x/sys/unix"
)
func TestTerminalDeviceSignedEncodingBoundaries(t *testing.T) {
tests := []struct {
raw int
major uint32
minor uint32
}{
{0, 0, 0},
{34817, 136, 1},
{math.MaxInt32, 4095, 524287},
{math.MinInt32, 0, 524288},
{-1, 4095, 1048575},
}
for _, test := range tests {
t.Run(strconv.Itoa(test.raw), func(t *testing.T) {
device, err := terminalDevice(test.raw)
if err != nil || device != unix.Mkdev(test.major, test.minor) {
t.Fatalf("终端设备编码错误:%x,%v", device, err)
}
})
}
if strconv.IntSize == 64 {
for _, raw := range []int64{int64(math.MinInt32) - 1, int64(math.MaxInt32) + 1, math.MaxInt64, math.MinInt64} {
if _, err := terminalDevice(int(raw)); !errors.Is(err, ErrUnauthorizedPeer) {
t.Fatalf("越界终端设备号未拒绝:%d", raw)
}
}
}
}
func TestTerminalPollDescriptorRejectsTruncation(t *testing.T) {
for _, fd := range []uintptr{0, 1, math.MaxInt32} {
actual, err := terminalPollDescriptor(fd)
if err != nil || uint64(actual) != uint64(fd) {
t.Fatalf("合法描述符转换失败:%d,%v", fd, err)
}
}
for _, fd := range []uintptr{math.MaxInt32 + 1, math.MaxUint32, ^uintptr(0)} {
if _, err := terminalPollDescriptor(fd); !errors.Is(err, ErrUnauthorizedPeer) {
t.Fatalf("越界描述符未拒绝:%d", fd)
}
}
}
func TestTerminalStreamRejectsClosedDescriptor(t *testing.T) {
file, err := os.Open(os.DevNull)
if err != nil {
t.Fatal(err)
}
if err := file.Close(); err != nil {
t.Fatal(err)
}
stream := &terminalStream{ctx: context.Background(), terminal: &invocationTerminal{file: file}}
if _, err := stream.Read(make([]byte, 1)); !errors.Is(err, ErrUnauthorizedPeer) {
t.Fatalf("已关闭描述符未拒绝:%v", err)
}
}
func TestProtectedCommandsIgnoreSearchPath(t *testing.T) {
directory := t.TempDir()
for _, name := range []string{"systemctl", "systemd-ask-password"} {
if err := os.WriteFile(filepath.Join(directory, name), []byte("#!/bin/sh\nexit 91\n"), 0700); err != nil {
t.Fatal(err)
}
}
t.Setenv("PATH", directory)
for _, name := range []string{"systemctl", "systemd-ask-password"} {
resolved, err := exec.LookPath(name)
if err != nil || resolved != filepath.Join(directory, name) {
t.Fatal("PATH 劫持反例未正确构造")
}
}
command := systemdInputCommand(context.Background(), "--no-tty", "--echo=no", "$(id);提示")
if command.Path != systemdInputAgentPath || command.Args[3] != "$(id);提示" {
t.Fatal("密码代理路径或原样参数不符合约束")
}
if command := systemdJobCommand(); command.Path != systemctlPath || len(command.Args) != 5 {
t.Fatal("systemctl 来源被搜索路径替换")
}
}