66#include "cmark.h"
77#include "node.h"
88
9+ #if defined(HAVE_LIBSECCOMP )
10+ # include <seccomp.h>
11+ # include <fcntl.h> /* O_RDONLY */
12+ #endif
13+
914#if defined(__OpenBSD__ )
1015# include <sys/param.h>
1116# if OpenBSD >= 201605
@@ -73,6 +78,70 @@ static void print_document(cmark_node *document, writer_format writer,
7378 document -> mem -> free (result );
7479}
7580
81+ #ifdef HAVE_LIBSECCOMP
82+ static void enable_seccomp (int argc , char * argv []) {
83+ int i ;
84+ int rc = -1 ;
85+ scmp_filter_ctx ctx ;
86+
87+ ctx = seccomp_init (SCMP_ACT_KILL );
88+ if (ctx == NULL )
89+ goto out ;
90+
91+ /* Allow opening files on the command line, and only as read-only */
92+ for (i = 1 ; i < argc ; i ++ ) {
93+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (openat ), 1 ,
94+ SCMP_A1 (SCMP_CMP_EQ , (size_t )argv [i ]),
95+ SCMP_A2 (SCMP_CMP_EQ , O_RDONLY ));
96+ if (rc < 0 )
97+ goto out ;
98+ }
99+
100+ /* Allow reading from open file descriptors */
101+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (read ), 0 );
102+ if (rc < 0 )
103+ goto out ;
104+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (close ), 0 );
105+ if (rc < 0 )
106+ goto out ;
107+
108+ /* Allow fstat (needed by C stdio) */
109+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (fstatat64 ), 0 );
110+ if (rc < 0 )
111+ goto out ;
112+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (newfstatat ), 0 );
113+ if (rc < 0 )
114+ goto out ;
115+
116+ /* Gracefully reject ioctl (needed by C stdio) */
117+ rc = seccomp_rule_add (ctx , SCMP_ACT_ERRNO (EACCES ), SCMP_SYS (ioctl ), 0 );
118+ if (rc < 0 )
119+ goto out ;
120+
121+ /* Allow writing to stdout */
122+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (write ), 1 ,
123+ SCMP_A0 (SCMP_CMP_EQ , 1 ));
124+ if (rc < 0 )
125+ goto out ;
126+
127+ /* Allow exiting */
128+ rc = seccomp_rule_add (ctx , SCMP_ACT_ALLOW , SCMP_SYS (exit_group ), 0 );
129+ if (rc < 0 )
130+ goto out ;
131+
132+ rc = seccomp_load (ctx );
133+ if (rc < 0 )
134+ goto out ;
135+
136+ rc = 0 ;
137+ out :
138+ if (rc < 0 ) {
139+ fprintf (stderr , "seccomp initialization failed: %d\n" , rc );
140+ }
141+ seccomp_release (ctx );
142+ }
143+ #endif
144+
76145int main (int argc , char * argv []) {
77146 int i , numfps = 0 ;
78147 int * files ;
@@ -91,6 +160,9 @@ int main(int argc, char *argv[]) {
91160 return 1 ;
92161 }
93162#endif
163+ #ifdef HAVE_LIBSECCOMP
164+ enable_seccomp (argc , argv );
165+ #endif
94166
95167#if defined(_WIN32 ) && !defined(__CYGWIN__ )
96168 _setmode (_fileno (stdin ), _O_BINARY );
0 commit comments