Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/samples/seccomp/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  bpf-direct.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Seccomp filter example for x86 (32-bit and 64-bit) with BPF macros
 *
 * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
 * Author: Will Drewry <wad@chromium.org>
 *
 * The code may be used by anyone for any purpose,
 * and can serve as a starting point for developing
 * applications using prctl(PR_SET_SECCOMP, 2, ...).
 */

#if defined(__i386__) || defined(__x86_64__)
#define SUPPORTED_ARCH 1
#endif

#if defined(SUPPORTED_ARCH)
#define __USE_GNU 1
#define _GNU_SOURCE 1

#include <linux/types.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <sys/prctl.h>
#include <unistd.h>

#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
#define syscall_nr (offsetof(struct seccomp_data, nr))

#if defined(__i386__)
#define REG_RESULT REG_EAX
#define REG_SYSCALL REG_EAX
#define REG_ARG0 REG_EBX
#define REG_ARG1 REG_ECX
#define REG_ARG2 REG_EDX
#define REG_ARG3 REG_ESI
#define REG_ARG4 REG_EDI
#define REG_ARG5 REG_EBP
#elif defined(__x86_64__)
#define REG_RESULT REG_RAX
#define REG_SYSCALL REG_RAX
#define REG_ARG0 REG_RDI
#define REG_ARG1 REG_RSI
#define REG_ARG2 REG_RDX
#define REG_ARG3 REG_R10
#define REG_ARG4 REG_R8
#define REG_ARG5 REG_R9
#endif

#ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38
#endif

#ifndef SYS_SECCOMP
#define SYS_SECCOMP 1
#endif

static void emulator(int nr, siginfo_t *info, void *void_context)
{
 ucontext_t *ctx = (ucontext_t *)(void_context);
 int syscall;
 char *buf;
 ssize_t bytes;
 size_t len;
 if (info->si_code != SYS_SECCOMP)
  return;
 if (!ctx)
  return;
 syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
 buf = (char *) ctx->uc_mcontext.gregs[REG_ARG1];
 len = (size_t) ctx->uc_mcontext.gregs[REG_ARG2];

 if (syscall != __NR_write)
  return;
 if (ctx->uc_mcontext.gregs[REG_ARG0] != STDERR_FILENO)
  return;
 /* Redirect stderr messages to stdout. Doesn't handle EINTR, etc */
 ctx->uc_mcontext.gregs[REG_RESULT] = -1;
 if (write(STDOUT_FILENO, "[ERR] ", 6) > 0) {
  bytes = write(STDOUT_FILENO, buf, len);
  ctx->uc_mcontext.gregs[REG_RESULT] = bytes;
 }
 return;
}

static int install_emulator(void)
{
 struct sigaction act;
 sigset_t mask;
 memset(&act, 0, sizeof(act));
 sigemptyset(&mask);
 sigaddset(&mask, SIGSYS);

 act.sa_sigaction = &emulator;
 act.sa_flags = SA_SIGINFO;
 if (sigaction(SIGSYS, &act, NULL) < 0) {
  perror("sigaction");
  return -1;
 }
 if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
  perror("sigprocmask");
  return -1;
 }
 return 0;
}

static int install_filter(void)
{
 struct sock_filter filter[] = {
  /* Grab the system call number */
  BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
  /* Jump table for the allowed syscalls */
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
#ifdef __NR_sigreturn
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
#endif
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0),
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2),

  /* Check that read is only using stdin. */
  BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),

  /* Check that write is only using stdout */
  BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0),
  /* Trap attempts to write to stderr */
  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2),

  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
  BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
 };
 struct sock_fprog prog = {
  .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
  .filter = filter,
 };

 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
  perror("prctl(NO_NEW_PRIVS)");
  return 1;
 }


 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
  perror("prctl");
  return 1;
 }
 return 0;
}

#define payload(_c) (_c), sizeof((_c))
int main(int argc, char **argv)
{
 char buf[4096];
 ssize_t bytes = 0;
 if (install_emulator())
  return 1;
 if (install_filter())
  return 1;
 syscall(__NR_write, STDOUT_FILENO,
  payload("OHAI! WHAT IS YOUR NAME? "));
 bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf));
 syscall(__NR_write, STDOUT_FILENO, payload("HELLO, "));
 syscall(__NR_write, STDOUT_FILENO, buf, bytes);
 syscall(__NR_write, STDERR_FILENO,
  payload("Error message going to STDERR\n"));
 return 0;
}
#else /* SUPPORTED_ARCH */
/*
 * This sample is x86-only.  Since kernel samples are compiled with the
 * host toolchain, a non-x86 host will result in using only the main()
 * below.
 */

int main(void)
{
 return 1;
}
#endif /* SUPPORTED_ARCH */

Messung V0.5
C=87 H=100 G=93

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.