-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
many: introduce seccomp denylist to block ioctl with TIOCLINUX to fix CVE-2023-1523 #12849
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0e87906
snap-seccomp: support explicitly blocking of syscalls
alexmurray c88f611
interfaces/seccomp: explicitly disallow the use of ioctl + TIOCLINUX
alexmurray 997dbfd
snap-seccomp-blacklist: also disallow the use of ioctl + TIOCLINUX
alexmurray 015190d
tests/main/snap-seccomp-blocks-tty-injection: spread test CVE-2023-1523
alexmurray 5b8b1dd
cmd/snap-seccomp: Group similar variables together
alexmurray 7cefecb
tests/main/snap-seccomp-blocks-tty-injection: fix shellcheck errors
alexmurray 362f2db
tests: fix snap-seccomp-blocks-tty-injection on partially confined sy…
mvo5 f890b2f
tests: fix snap-seccomp-blocks-tty-injection on 32bit systems
mvo5 371f7b5
many: add a bunch of TODO/FIXME for a followup :)
mvo5 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
summary: Ensure that the snap-seccomp blocks tty command injection | ||
|
||
# ubuntu-core: excluded because there is no gcc there | ||
systems: [-ubuntu-core-*] | ||
|
||
prepare: | | ||
echo "Install a helper snap (for seccomp confinement testing)" | ||
"$TESTSTOOLS"/snaps-state install-local test-snapd-sh | ||
|
||
echo "Compile and prepare the test programs" | ||
# Because we use the snap data directory we don't need to clean it up | ||
# manually as all snaps and their data are reset after each test. | ||
# Build the test binary statically, as it will be running inside a base with | ||
# potentially older glibc. | ||
gcc -Wall -Wextra -Werror ./test-tioclinux.c -o /var/snap/test-snapd-sh/common/test-tioclinux -static | ||
gcc -Wall -Wextra -Werror ./test-tiocsti.c -o /var/snap/test-snapd-sh/common/test-tiocsti -static | ||
|
||
execute: | | ||
# use /dev/tty1 as input so that we use a real virtual console which | ||
# supports TIOCSTI / TIOCLINUX - but first make sure the snap can access it | ||
# through AppArmor | ||
if [ "$(snap debug confinement)" = strict ]; then | ||
sed -i 's|^}$| /dev/tty1 rw,\n}|' /var/lib/snapd/apparmor/profiles/snap.test-snapd-sh.sh | ||
apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.test-snapd-sh.sh | ||
fi | ||
|
||
# For 64bit systems TIOC{STI,LINUX} gets a EPERM because of the | ||
# "snap-seccomp-blacklist" that is *only* build for 64bit arches | ||
# (because denying also needs to work when the higher bits are set | ||
# which the normal filter will not check, see also commit b923d58) | ||
# | ||
# On 32bit systems TIOC{STI,LINUX} is blocked by the default seccomp | ||
# template.go which will default to EACCESS for explicit denied syscalls. | ||
snap run test-snapd-sh.sh -c "\$SNAP_COMMON/test-tiocsti" < /dev/tty1 2>&1 | MATCH 'normal TIOCSTI: -1 \((Operation not permitted|Permission denied)\)' | ||
valentindavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
snap run test-snapd-sh.sh -c "\$SNAP_COMMON/test-tiocsti" < /dev/tty1 2>&1 | MATCH 'high-bit-set TIOCSTI: -1 \((Operation not permitted|Permission denied)\)' | ||
# TODO: this will not work because TIOCLINUX only works on "real" virtual | ||
# linux terminal which cannot be simulated via spread unless we | ||
# do something with nested qemu and simulated with maybe | ||
# "-chardev tty" | ||
#snap run test-snapd-sh.sh -c "\$SNAP_COMMON/test-tioclinux" < /dev/tty1 2>&1 | MATCH 'ioctl\(0, TIOCLINUX, ...\) failed: Permission denied' |
36 changes: 36 additions & 0 deletions
36
tests/main/snap-seccomp-blocks-tty-injection/test-tioclinux.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <err.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/ioctl.h> | ||
|
||
#include <linux/tiocl.h> | ||
#include <linux/vt.h> | ||
|
||
int main(void) | ||
{ | ||
int res; | ||
printf("\33[H\33[2J"); | ||
printf("head -n1 /etc/shadow\n"); | ||
fflush(stdout); | ||
struct { | ||
char padding; | ||
char subcode; | ||
struct tiocl_selection sel; | ||
} data = { | ||
.subcode = TIOCL_SETSEL, | ||
.sel = { | ||
.xs = 1, .ys = 1, | ||
.xe = 1, .ye = 1, | ||
.sel_mode = TIOCL_SELLINE | ||
} | ||
}; | ||
res = ioctl(0, TIOCLINUX, &data.subcode); | ||
if (res != 0) | ||
err(EXIT_FAILURE, "ioctl(0, TIOCLINUX, ...) failed"); | ||
data.subcode = TIOCL_PASTESEL; | ||
ioctl(0, TIOCLINUX, &data.subcode); | ||
if (res != 0) | ||
err(EXIT_FAILURE, "ioctl(0, TIOCLINUX, ...) failed"); | ||
exit(EXIT_SUCCESS); | ||
} | ||
|
30 changes: 30 additions & 0 deletions
30
tests/main/snap-seccomp-blocks-tty-injection/test-tiocsti.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#define _GNU_SOURCE | ||
#include <termios.h> | ||
#include <sys/ioctl.h> | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <sys/syscall.h> | ||
#include <errno.h> | ||
|
||
static int ioctl64(int fd, unsigned long nr, void *arg) { | ||
errno = 0; | ||
return syscall(__NR_ioctl, fd, nr, arg); | ||
} | ||
|
||
int main(void) { | ||
int res; | ||
char pushmeback = '#'; | ||
|
||
unsigned long syscallnr = TIOCSTI; | ||
res = ioctl64(0, syscallnr, &pushmeback); | ||
printf("normal TIOCSTI: %d (%m)\n", res); | ||
|
||
#ifdef __LP64__ | ||
// this high bit check only works on 64bit systems, on 32bit it will fail: | ||
// "error: left shift count >= width of type [-Werror=shift-count-overflow]" | ||
syscallnr = TIOCSTI | (1UL<<32); | ||
#endif | ||
res = ioctl64(0, syscallnr, &pushmeback); | ||
printf("high-bit-set TIOCSTI: %d (%m)\n", res); | ||
return res; | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some playing and poking I think this is okay short term but I think we should replace it ASAP in a followup. The issue is that it seems like libseccomp will "optimize" rules away. As it is designed as an allow-list, the behavior of this:
is counter intuitive - it will generate an allow rule for "ioctl" and discard the "~ioctl" entirely:
this only works as expected hen combined with another specific rule like:
see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we probably want instead of "~" a new:
ioctl - !TIOCSTI&&!TIOCLINUX
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately there is no way to express this in the libseccomp API https://libseccomp.readthedocs.io/en/latest/man/man3/seccomp_rule_add.3/ that I am aware of - we can only do something like 'compare argument 1 is equal to this value' or 'compare argument 1 is greater than this value' - we can't do higher level operations like booleans etc - so I don't think that is possible with libseccomp. If we were to write the BPF filter by hand we could add this but that would be a significant departure from the current implementation.