Skip to content

Commit

Permalink
[PATCH] audit signal recipients
Browse files Browse the repository at this point in the history
When auditing syscalls that send signals, log the pid and security
context for each target process. Optimize the data collection by
adding a counter for signal-related rules, and avoiding allocating an
aux struct unless we have more than one target process. For process
groups, collect pid/context data in blocks of 16. Move the
audit_signal_info() hook up in check_kill_permission() so we audit
attempts where permission is denied.

Signed-off-by: Amy Griffis <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Amy Griffis authored and Al Viro committed May 11, 2007
1 parent 7f13da4 commit e54dc24
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 29 deletions.
9 changes: 9 additions & 0 deletions arch/ia64/kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ static unsigned signal_class[] = {
~0U
};

int audit_classify_arch(int arch)
{
#ifdef CONFIG_IA32_SUPPORT
if (arch == AUDIT_ARCH_I386)
return 1;
#endif
return 0;
}

int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_IA32_SUPPORT
Expand Down
9 changes: 9 additions & 0 deletions arch/powerpc/kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ static unsigned signal_class[] = {
~0U
};

int audit_classify_arch(int arch)
{
#ifdef CONFIG_PPC64
if (arch == AUDIT_ARCH_PPC)
return 1;
#endif
return 0;
}

int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_PPC64
Expand Down
9 changes: 9 additions & 0 deletions arch/s390/kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ static unsigned signal_class[] = {
~0U
};

int audit_classify_arch(int arch)
{
#ifdef CONFIG_COMPAT
if (arch == AUDIT_ARCH_S390)
return 1;
#endif
return 0;
}

int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_COMPAT
Expand Down
9 changes: 9 additions & 0 deletions arch/sparc64/kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ static unsigned signal_class[] = {
~0U
};

int audit_classify_arch(int arch)
{
#ifdef CONFIG_SPARC32_COMPAT
if (arch == AUDIT_ARCH_SPARC)
return 1;
#endif
return 0;
}

int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_SPARC32_COMPAT
Expand Down
9 changes: 9 additions & 0 deletions arch/x86_64/kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ static unsigned signal_class[] = {
~0U
};

int audit_classify_arch(int arch)
{
#ifdef CONFIG_IA32_EMULATION
if (arch == AUDIT_ARCH_I386)
return 1;
#endif
return 0;
}

int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_IA32_EMULATION
Expand Down
3 changes: 3 additions & 0 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ struct mqstat;
#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
extern int __init audit_register_class(int class, unsigned *list);
extern int audit_classify_syscall(int abi, unsigned syscall);
extern int audit_classify_arch(int arch);
#ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */
/* Public API */
Expand Down Expand Up @@ -458,6 +459,7 @@ static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
return 0;
}
extern int audit_n_rules;
extern int audit_signals;
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
Expand Down Expand Up @@ -490,6 +492,7 @@ extern int audit_n_rules;
#define audit_mq_getsetattr(d,s) ({ 0; })
#define audit_ptrace(t) ((void)0)
#define audit_n_rules 0
#define audit_signals 0
#endif

#ifdef CONFIG_AUDIT
Expand Down
13 changes: 8 additions & 5 deletions kernel/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct audit_krule {
u32 field_count;
char *filterkey; /* ties events to rules */
struct audit_field *fields;
struct audit_field *arch_f; /* quick access to arch field */
struct audit_field *inode_f; /* quick access to an inode field */
struct audit_watch *watch; /* associated watch */
struct list_head rlist; /* entry in audit_watch.rules list */
Expand Down Expand Up @@ -131,17 +132,19 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
extern int selinux_audit_rule_update(void);

#ifdef CONFIG_AUDITSYSCALL
extern void __audit_signal_info(int sig, struct task_struct *t);
static inline void audit_signal_info(int sig, struct task_struct *t)
extern int __audit_signal_info(int sig, struct task_struct *t);
static inline int audit_signal_info(int sig, struct task_struct *t)
{
if (unlikely(audit_pid && t->tgid == audit_pid))
__audit_signal_info(sig, t);
if (unlikely((audit_pid && t->tgid == audit_pid) ||
(audit_signals && !audit_dummy_context())))
return __audit_signal_info(sig, t);
return 0;
}
extern enum audit_state audit_filter_inodes(struct task_struct *,
struct audit_context *);
extern void audit_set_auditable(struct audit_context *);
#else
#define audit_signal_info(s,t)
#define audit_signal_info(s,t) AUDIT_DISABLED
#define audit_filter_inodes(t,c) AUDIT_DISABLED
#define audit_set_auditable(c)
#endif
48 changes: 47 additions & 1 deletion kernel/auditfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,43 @@ int audit_match_class(int class, unsigned syscall)
return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
}

static inline int audit_match_class_bits(int class, u32 *mask)
{
int i;

if (classes[class]) {
for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
if (mask[i] & classes[class][i])
return 0;
}
return 1;
}

static int audit_match_signal(struct audit_entry *entry)
{
struct audit_field *arch = entry->rule.arch_f;

if (!arch) {
/* When arch is unspecified, we must check both masks on biarch
* as syscall number alone is ambiguous. */
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
entry->rule.mask) &&
audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
entry->rule.mask));
}

switch(audit_classify_arch(arch->val)) {
case 0: /* native */
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
entry->rule.mask));
case 1: /* 32bit on biarch */
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
entry->rule.mask));
default:
return 1;
}
}

/* Common user-space to kernel rule translation. */
static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
{
Expand Down Expand Up @@ -429,6 +466,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
err = -EINVAL;
goto exit_free;
}
entry->rule.arch_f = f;
break;
case AUDIT_PERM:
if (f->val & ~15)
Expand Down Expand Up @@ -519,7 +557,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
case AUDIT_FSGID:
case AUDIT_LOGINUID:
case AUDIT_PERS:
case AUDIT_ARCH:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
Expand All @@ -531,6 +568,9 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
case AUDIT_ARG2:
case AUDIT_ARG3:
break;
case AUDIT_ARCH:
entry->rule.arch_f = f;
break;
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
Expand Down Expand Up @@ -1221,6 +1261,9 @@ static inline int audit_add_rule(struct audit_entry *entry,
#ifdef CONFIG_AUDITSYSCALL
if (!dont_count)
audit_n_rules++;

if (!audit_match_signal(entry))
audit_signals++;
#endif
mutex_unlock(&audit_filter_mutex);

Expand Down Expand Up @@ -1294,6 +1337,9 @@ static inline int audit_del_rule(struct audit_entry *entry,
#ifdef CONFIG_AUDITSYSCALL
if (!dont_count)
audit_n_rules--;

if (!audit_match_signal(entry))
audit_signals--;
#endif
mutex_unlock(&audit_filter_mutex);

Expand Down
Loading

0 comments on commit e54dc24

Please sign in to comment.