jart / jart/pledge

Confusing output (no error message) when tty is not pledged but program queries ioctl TIOCGWINSZ

Open
#6 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
143
Forks
7
PR merge metrics
No merged PRs in 30d

Description

Busybox programs queries TIOCGWINSZ on startup, meaning benign commands like `seq` needs to pledge "tty". Failing to do so causes pledge to "silently" fail, printing "Bad system call" (no error messages reported.)

```shell
$ pledge -p "stdio" /bin/seq 1
Bad system call
$ pledge -p "stdio tty" /bin/seq 1
1
```

Original issue:

----

On a barebones musl (Linux 6.5.8)

```shell
$ pledge -p "stdio" /bin/date
Bad system call
$ pledge -p "stdio exec" /bin/date
Mon Apr 29 22:44:12 UTC 2024
```

The culprit seems to be `__pledge_mode & PLEDGE_STDERR_LOGGING`

https://github.com/jart/pledge/blob/8693ebe15a30bd4235165ad72a469da29ca067cf/cmd/pledge.c#L841

since if I pass `-q` to pledge, exec works as expected:

```shell
$ pledge -q -p "stdio" /bin/date
Mon Apr 29 22:45:30 UTC 2024
```

Additionally, passing `-k` to pledge (sets __pledge_mode = PLEDGE_PENALTY_KILL_PROCESS) also results in "Bad system call", even with `-q`:

```shell
$ pledge -k -p "stdio" /bin/date
Bad system call
$ pledge -k -q -p "stdio" /bin/date
Bad system call
```

If I disable "implicit exec" by commenting out these lines...

https://github.com/jart/pledge/blob/8693ebe15a30bd4235165ad72a469da29ca067cf/cmd/pledge.c#L838-L843

... execv fails with the expected "Operation not permitted" error message:

```shell
$ pledge -p "stdio" /bin/date
/bin/date: execve failed: Operation not permitted
```

~The least messy fix I've come up with is to always include a SECCOMP_RET_ERRNO filter:~
**Edit: I realize now that this patch breaks stuff (as it returns early)**

```diff
--- a/libc/calls/pledge-linux.c 2023-11-08 18:18:17.000000000 +0000
+++ b/libc/calls/pledge-linux.c 2024-04-29 23:10:44.057225745 +0000
@@ -2129,6 +2129,9 @@
}
}

+ sf[0].k = SECCOMP_RET_ERRNO;
+ AppendFilter(&f, PLEDGE(sf));
+
// now determine what we'll do on sandbox violations
if (mode & PLEDGE_STDERR_LOGGING) {
// trapping mode
```

(Note: /bin/date in this example is a static executable, so sandbox.so is not involved)

Linux 6.5.8 is built with:

```
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the `pledge -p` and `-q` examples with `/bin/date` and `/bin/seq`, then inspect `cmd/pledge.c` around lines 838-843 and `libc/calls/pledge-linux.c` around line 2129. Compare the resulting sandbox behavior with the expected informative error handling, while ensuring the attempted filter change does not return early or break existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.