Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd1dbf76 authored by John Johansen's avatar John Johansen
Browse files

apparmor: add the ability to mediate signals



Add signal mediation where the signal can be mediated based on the
signal, direction, or the label or the peer/target. The signal perms
are verified on a cross check to ensure policy consistency in the case
of incremental policy load/replacement.

The optimization of skipping the cross check when policy is guaranteed
to be consistent (single compile unit) remains to be done.

policy rules have the form of
  SIGNAL_RULE = [ QUALIFIERS ] 'signal' [ SIGNAL ACCESS PERMISSIONS ]
                [ SIGNAL SET ] [ SIGNAL PEER ]

  SIGNAL ACCESS PERMISSIONS = SIGNAL ACCESS | SIGNAL ACCESS LIST

  SIGNAL ACCESS LIST = '(' Comma or space separated list of SIGNAL
                           ACCESS ')'

  SIGNAL ACCESS = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' |
                    'receive' )

  SIGNAL SET = 'set' '=' '(' SIGNAL LIST ')'

  SIGNAL LIST = Comma or space separated list of SIGNALS

  SIGNALS = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' |
              'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' |
	      'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' |
	      'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' |
	      'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' |
	      'sys' | 'emt' | 'exists' | 'rtmin+0' ... 'rtmin+32'
            )

  SIGNAL PEER = 'peer' '=' AARE

eg.
  signal,                                 # allow all signals
  signal send set=(hup, kill) peer=foo,

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Acked-by: default avatarSeth Arnold <seth.arnold@canonical.com>
parent c5561700
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "include/audit.h"
#include "include/context.h"
#include "include/crypto.h"
#include "include/ipc.h"
#include "include/policy_ns.h"
#include "include/label.h"
#include "include/policy.h"
@@ -2129,6 +2130,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
	{ }
};

static struct aa_sfs_entry aa_sfs_entry_signal[] = {
	AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
	{ }
};

static struct aa_sfs_entry aa_sfs_entry_domain[] = {
	AA_SFS_FILE_BOOLEAN("change_hat",	1),
	AA_SFS_FILE_BOOLEAN("change_hatv",	1),
@@ -2179,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
	AA_SFS_DIR("rlimit",			aa_sfs_entry_rlimit),
	AA_SFS_DIR("caps",			aa_sfs_entry_caps),
	AA_SFS_DIR("ptrace",			aa_sfs_entry_ptrace),
	AA_SFS_DIR("signal",			aa_sfs_entry_signal),
	AA_SFS_DIR("query",			aa_sfs_entry_query),
	{ }
};
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#define AA_CLASS_RLIMITS	5
#define AA_CLASS_DOMAIN		6
#define AA_CLASS_PTRACE		9
#define AA_CLASS_SIGNAL		10
#define AA_CLASS_LABEL		16

#define AA_CLASS_LAST		AA_CLASS_LABEL
+2 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ enum audit_type {
#define OP_SHUTDOWN "socket_shutdown"

#define OP_PTRACE "ptrace"
#define OP_SIGNAL "signal"

#define OP_EXEC "exec"

@@ -126,6 +127,7 @@ struct apparmor_audit_data {
			long pos;
			const char *ns;
		} iface;
		int signal;
		struct {
			int rlim;
			unsigned long max;
+6 −0
Original line number Diff line number Diff line
@@ -27,8 +27,14 @@ struct aa_profile;

#define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
			     AA_MAY_BE_READ | AA_MAY_BE_TRACED)
#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)

#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
	"segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
	"xcpu xfsz vtalrm prof winch io pwr sys emt lost"

int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
		  u32 request);
int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);

#endif /* __AA_IPC_H */
+95 −0
Original line number Diff line number Diff line
#include <linux/signal.h>

#define SIGUNKNOWN 0
#define MAXMAPPED_SIG 35
/* provide a mapping of arch signal to internal signal # for mediation
 * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO
 * map to the same entry those that may/or may not get a separate entry
 */
static const int sig_map[MAXMAPPED_SIG] = {
	[0] = MAXMAPPED_SIG,	/* existence test */
	[SIGHUP] = 1,
	[SIGINT] = 2,
	[SIGQUIT] = 3,
	[SIGILL] = 4,
	[SIGTRAP] = 5,		/* -, 5, - */
	[SIGABRT] = 6,		/*  SIGIOT: -, 6, - */
	[SIGBUS] = 7,		/* 10, 7, 10 */
	[SIGFPE] = 8,
	[SIGKILL] = 9,
	[SIGUSR1] = 10,		/* 30, 10, 16 */
	[SIGSEGV] = 11,
	[SIGUSR2] = 12,		/* 31, 12, 17 */
	[SIGPIPE] = 13,
	[SIGALRM] = 14,
	[SIGTERM] = 15,
	[SIGSTKFLT] = 16,	/* -, 16, - */
	[SIGCHLD] = 17,		/* 20, 17, 18.  SIGCHLD -, -, 18 */
	[SIGCONT] = 18,		/* 19, 18, 25 */
	[SIGSTOP] = 19,		/* 17, 19, 23 */
	[SIGTSTP] = 20,		/* 18, 20, 24 */
	[SIGTTIN] = 21,		/* 21, 21, 26 */
	[SIGTTOU] = 22,		/* 22, 22, 27 */
	[SIGURG] = 23,		/* 16, 23, 21 */
	[SIGXCPU] = 24,		/* 24, 24, 30 */
	[SIGXFSZ] = 25,		/* 25, 25, 31 */
	[SIGVTALRM] = 26,	/* 26, 26, 28 */
	[SIGPROF] = 27,		/* 27, 27, 29 */
	[SIGWINCH] = 28,	/* 28, 28, 20 */
	[SIGIO] = 29,		/* SIGPOLL: 23, 29, 22 */
	[SIGPWR] = 30,		/* 29, 30, 19.  SIGINFO 29, -, - */
#ifdef SIGSYS
	[SIGSYS] = 31,		/* 12, 31, 12. often SIG LOST/UNUSED */
#endif
#ifdef SIGEMT
	[SIGEMT] = 32,		/* 7, - , 7 */
#endif
#if defined(SIGLOST) && SIGPWR != SIGLOST		/* sparc */
	[SIGLOST] = 33,		/* unused on Linux */
#endif
#if defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
	[SIGUNUSED] = 34,	/* -, 31, - */
#endif
};

/* this table is ordered post sig_map[sig] mapping */
static const char *const sig_names[MAXMAPPED_SIG + 1] = {
	"unknown",
	"hup",
	"int",
	"quit",
	"ill",
	"trap",
	"abrt",
	"bus",
	"fpe",
	"kill",
	"usr1",
	"segv",
	"usr2",
	"pipe",
	"alrm",
	"term",
	"stkflt",
	"chld",
	"cont",
	"stop",
	"stp",
	"ttin",
	"ttou",
	"urg",
	"xcpu",
	"xfsz",
	"vtalrm",
	"prof",
	"winch",
	"io",
	"pwr",
	"sys",
	"emt",
	"lost",
	"unused",

	"exists",	/* always last existence test mapped to MAXMAPPED_SIG */
};
Loading