Stefanos Kornilios Misis Poiitidis 2022-08-12 10:50:46 +03:00
parent 9b3f6afec9
commit 06571ea748
2 changed files with 198 additions and 0 deletions

116
seccomp/secccomp.c Normal file
View File

@ -0,0 +1,116 @@
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2022. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 or (at your option) any *
* later version. This program is distributed without any warranty. See *
* the file COPYING.gpl-v3 for details. *
\*************************************************************************/
/* seccomp_trap_sigsys.c
Demonstrate that SECCOMP_RET_TRAP causes a SIGSYS signal that
can be caught by the program. After the handler returns, execution
of the main program continues.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <signal.h>
#include <fcntl.h>
#include <linux/audit.h>
#include <sys/syscall.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include "tlpi_hdr.h"
/* For the x32 ABI, all system call numbers have bit 30 set */
#define X32_SYSCALL_BIT 0x40000000
static int
seccomp(unsigned int operation, unsigned int flags, void *args)
{
return syscall(__NR_seccomp, operation, flags, args);
}
static void
install_filter(void)
{
struct sock_filter filter[] = {
/* Load architecture */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, arch))),
/* Kill process if the architecture is not what we expect */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
/* Load system call number */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, nr))),
/* Kill the process if this is an x32 system call (bit 30 is set) */
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, X32_SYSCALL_BIT, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
/* getppid() results in SIGSYS; all other system calls are allowed */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getppid, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
};
struct sock_fprog prog = {
.len = sizeof(filter) / sizeof(filter[0]),
.filter = filter,
};
if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog) == -1)
return -10;
/* On Linux 3.16 and earlier, we must instead use:
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog))
errExit("prctl-PR_SET_SECCOMP");
*/
}
static void /* Handler for SIGINT signal */
sigHandler(int sig)
{
printf("SIGSYS!\n"); /* UNSAFE (see Section 21.1.2) */
}
int
main(int argc, char *argv[])
{
/* Set up seccomp filter */
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
return -11;
install_filter();
/* Establish handler for SIGSYS */
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = sigHandler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSYS, &sa, NULL) == -1)
return -18;
printf("About to call getppid()\n");
(void) getppid(); /* Results in SIGSYS; system call is not executed */
/* After the SIGSYS handler returns, execution continues in main() */
printf("Bye\n");
exit(EXIT_SUCCESS);
}

82
seccomp/tlpi_hdr.h Normal file
View File

@ -0,0 +1,82 @@
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2022. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 or (at your option) *
* any later version. This program is distributed without any warranty. *
* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. *
\*************************************************************************/
/* tlpi_hdr.h
Standard header file used by nearly all of our example programs.
*/
#ifndef TLPI_HDR_H
#define TLPI_HDR_H /* Prevent accidental double inclusion */
#include <sys/types.h> /* Type definitions used by many programs */
#include <stdio.h> /* Standard I/O functions */
#include <stdlib.h> /* Prototypes of commonly used library functions,
plus EXIT_SUCCESS and EXIT_FAILURE constants */
#include <unistd.h> /* Prototypes for many system calls */
#include <errno.h> /* Declares errno and defines error constants */
#include <string.h> /* Commonly used string-handling functions */
#include <stdbool.h> /* 'bool' type plus 'true' and 'false' constants */
//#include "get_num.h" /* Declares our functions for handling numeric
// arguments (getInt(), getLong()) */
//#include "error_functions.h" /* Declares our error-handling functions */
/* Unfortunately some UNIX implementations define FALSE and TRUE -
here we'll undefine them */
#ifdef TRUE
#undef TRUE
#endif
#ifdef FALSE
#undef FALSE
#endif
typedef enum { FALSE, TRUE } Boolean;
#define min(m,n) ((m) < (n) ? (m) : (n))
#define max(m,n) ((m) > (n) ? (m) : (n))
/* Some systems don't define 'socklen_t' */
#if defined(__sgi)
typedef int socklen_t;
#endif
#if defined(__sun)
#include <sys/file.h> /* Has definition of FASYNC */
#endif
#if ! defined(O_ASYNC) && defined(FASYNC)
/* Some systems define FASYNC instead of O_ASYNC */
#define O_ASYNC FASYNC
#endif
#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
/* BSD derivatives usually have MAP_ANON, not MAP_ANONYMOUS */
#define MAP_ANONYMOUS MAP_ANON
#endif
#if ! defined(O_SYNC) && defined(O_FSYNC)
/* Some implementations have O_FSYNC instead of O_SYNC */
#define O_SYNC O_FSYNC
#endif
#if defined(__FreeBSD__)
/* FreeBSD uses these alternate names for fields in the sigval structure */
#define sival_int sigval_int
#define sival_ptr sigval_ptr
#endif
#endif