View Issue Details

IDProjectCategoryView StatusLast Update
0000678fileGeneralpublic2025-09-07 12:41
Reportertobias Assigned Tochristos  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionreopened 
Product Version5.46 
Fixed in VersionHEAD 
Summary0000678: glibc on physical terminals with seccomp fails due to TCGETS2
DescriptionCurrent Arch Linux installations cannot run file on physical terminal.

This happens because file is built with seccomp and glibc uses the ioctl TCGETS2.

TCGETS is already part of the sandbox, but not TCGETS2.
Steps To Reproduce- Install Arch Linux or compile file with seccomp on a system with current glibc (2.24, maybe lower as well [not tested]).
- Switch to physical terminal.
- Run file /dev/null

The call fails due to bad system call, which is ioctl TCGETS2.
TagsNo tags attached.

Activities

tobias

2025-08-06 21:17

reporter  

tcgets2.patch (1,188 bytes)   
From 7b23bd3f87069fcebc9173c8d1637c2a2e1a12d1 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Wed, 6 Aug 2025 23:11:10 +0200
Subject: [PATCH] Extend seccomp for glibc and  physical terminals

New glibc implementations might also use TCGETS2 instead of TCGETS.
This happens on current Arch Linux systems. Allow TCGETS2 in seccomp
sandbox as well.
---
 src/seccomp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/seccomp.c b/src/seccomp.c
index f05c30f9..dddb821c 100644
--- a/src/seccomp.c
+++ b/src/seccomp.c
@@ -37,6 +37,8 @@ FILE_RCSID("@(#)$File: seccomp.c,v 1.31 2025/03/20 14:57:41 christos Exp $")
 #ifdef __powerpc64__
 // See: https://sourceware.org/bugzilla/show_bug.cgi?id=32806
 # include <asm/termbits.h>
+#elif defined __linux__
+# include <linux/termios.h>
 #else
 # include <termios.h>
 #endif
@@ -121,6 +123,10 @@ enable_sandbox(void)
 #ifdef TCGETS
 	// glibc may call ioctl TCGETS on stdout on physical terminal
 	ALLOW_IOCTL_RULE(TCGETS);
+#endif
+#ifdef TCGETS2
+	// glibc may call ioctl TCGETS2 on stdout on physical terminal
+	ALLOW_IOCTL_RULE(TCGETS2);
 #endif
 	ALLOW_RULE(lseek);
  	ALLOW_RULE(_llseek);
-- 
2.50.1

tcgets2.patch (1,188 bytes)   

tobias

2025-08-06 21:30

reporter   ~0004280

Description states glibc 2.24 instead of 2.42. Sorry for that, didn't test THAT far back in time. :)

bitstreamout

2025-09-04 09:23

reporter   ~0004283

I'd like also to suggest to use

```
#include <asm/termbits.h>
```

to get TCGETS correct even on PPC64 ... glibc uses internal the TCGETS and TCGETS2 other than in `<termios.h>`
code to check this

```
#include <asm/termbits.h>
#include <sys/ioctl.h>

#ifdef TCGETS
#error XXX
#endif
#ifdef TCGETS2
#error YYY
#endif
```

christos

2025-09-06 16:55

manager   ~0004284

added thanks!

christos

2025-09-06 16:55

manager   ~0004285

Added thanks

tobias

2025-09-06 21:36

reporter   ~0004289

This commit https://github.com/file/file/commit/9ebf54ab9e83f6c6b0187b5a3caae070a75c186e breaks compilation on Arch Linux.

```
In file included from seccomp.c:34:
seccomp.c: In function ‘enable_sandbox’:
seccomp.c:127:26: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’
  127 | ALLOW_IOCTL_RULE(TCGETS2);
      | ^~~~~~~
seccomp.c:127:9: note: in expansion of macro ‘ALLOW_IOCTL_RULE’
  127 | ALLOW_IOCTL_RULE(TCGETS2);
      | ^~~~~~~~~~~~~~~~
make[3]: *** [Makefile:554: seccomp.o] Error 1
```

The suggestion from bitstreamout fixes the issue, i.e. unconditionally:

```
#include <asm/termbits.h>
```

And not including termios.h.

tobias

2025-09-06 21:38

reporter   ~0004290

The attached patch fixes the issue on my Arch Linux system. Not sure if it's a universally correct solution.
file.diff (478 bytes)   
diff --git a/src/seccomp.c b/src/seccomp.c
index a10d0b6e..23d9903f 100644
--- a/src/seccomp.c
+++ b/src/seccomp.c
@@ -34,7 +34,7 @@ FILE_RCSID("@(#)$File: seccomp.c,v 1.33 2025/09/06 17:40:48 christos Exp $")
 #include <seccomp.h> /* libseccomp */
 #include <sys/prctl.h> /* prctl */
 #include <sys/socket.h>
-#ifdef __powerpc64__
+#if defined __powerpc64__ || defined __linux__
 // See: https://sourceware.org/bugzilla/show_bug.cgi?id=32806
 # include <asm/termbits.h>
 #else
file.diff (478 bytes)   

christos

2025-09-07 12:34

manager   ~0004291

basically this includes <asm/termbits.h> unconditionally since __linux__ is defined everywhere?

tobias

2025-09-07 12:41

reporter   ~0004292

I'd say that we follow bitstreamout's suggestion then and include it unconditionally, dropping the else block. I cannot include both because then compilation fails again.

Issue History

Date Modified Username Field Change
2025-08-06 21:17 tobias New Issue
2025-08-06 21:17 tobias File Added: tcgets2.patch
2025-08-06 21:30 tobias Note Added: 0004280
2025-09-04 09:23 bitstreamout Note Added: 0004283
2025-09-06 16:55 christos Assigned To => christos
2025-09-06 16:55 christos Status new => assigned
2025-09-06 16:55 christos Status assigned => resolved
2025-09-06 16:55 christos Resolution open => fixed
2025-09-06 16:55 christos Fixed in Version => HEAD
2025-09-06 16:55 christos Note Added: 0004284
2025-09-06 16:55 christos Note Added: 0004285
2025-09-06 21:36 tobias Status resolved => feedback
2025-09-06 21:36 tobias Resolution fixed => reopened
2025-09-06 21:36 tobias Note Added: 0004289
2025-09-06 21:38 tobias Note Added: 0004290
2025-09-06 21:38 tobias File Added: file.diff
2025-09-06 21:38 tobias Status feedback => assigned
2025-09-07 12:34 christos Note Added: 0004291
2025-09-07 12:41 tobias Note Added: 0004292