diff options
-rw-r--r-- | include/linux/audit.h | 5 | ||||
-rw-r--r-- | kernel/auditsc.c | 20 | ||||
-rw-r--r-- | kernel/seccomp.c | 58 |
3 files changed, 74 insertions, 9 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 75d5b031e802..d4e35e7a80c0 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -233,6 +233,8 @@ extern void __audit_inode_child(struct inode *parent, const struct dentry *dentry, const unsigned char type); extern void __audit_seccomp(unsigned long syscall, long signr, int code); +extern void audit_seccomp_actions_logged(const char *names, + const char *old_names, int res); extern void __audit_ptrace(struct task_struct *t); static inline bool audit_dummy_context(void) @@ -502,6 +504,9 @@ static inline void __audit_seccomp(unsigned long syscall, long signr, int code) { } static inline void audit_seccomp(unsigned long syscall, long signr, int code) { } +static inline void audit_seccomp_actions_logged(const char *names, + const char *old_names, int res) +{ } static inline int auditsc_get_stamp(struct audit_context *ctx, struct timespec64 *t, unsigned int *serial) { diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 479c031ec54c..46ef2c23618d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2480,6 +2480,26 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) audit_log_end(ab); } +void audit_seccomp_actions_logged(const char *names, const char *old_names, + int res) +{ + struct audit_buffer *ab; + + if (!audit_enabled) + return; + + ab = audit_log_start(current->audit_context, GFP_KERNEL, + AUDIT_CONFIG_CHANGE); + if (unlikely(!ab)) + return; + + audit_log_format(ab, "op=seccomp-logging"); + audit_log_format(ab, " actions=%s", names); + audit_log_format(ab, " old-actions=%s", old_names); + audit_log_format(ab, " res=%d", res); + audit_log_end(ab); +} + struct list_head *audit_killed_trees(void) { struct audit_context *ctx = current->audit_context; diff --git a/kernel/seccomp.c b/kernel/seccomp.c index b36ac1e0cd0e..f5630d1a88fe 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -1219,11 +1219,10 @@ static int read_actions_logged(struct ctl_table *ro_table, void __user *buffer, } static int write_actions_logged(struct ctl_table *ro_table, void __user *buffer, - size_t *lenp, loff_t *ppos) + size_t *lenp, loff_t *ppos, u32 *actions_logged) { char names[sizeof(seccomp_actions_avail)]; struct ctl_table table; - u32 actions_logged; int ret; if (!capable(CAP_SYS_ADMIN)) @@ -1238,24 +1237,65 @@ static int write_actions_logged(struct ctl_table *ro_table, void __user *buffer, if (ret) return ret; - if (!seccomp_actions_logged_from_names(&actions_logged, table.data)) + if (!seccomp_actions_logged_from_names(actions_logged, table.data)) return -EINVAL; - if (actions_logged & SECCOMP_LOG_ALLOW) + if (*actions_logged & SECCOMP_LOG_ALLOW) return -EINVAL; - seccomp_actions_logged = actions_logged; + seccomp_actions_logged = *actions_logged; return 0; } +static void audit_actions_logged(u32 actions_logged, u32 old_actions_logged, + int ret) +{ + char names[sizeof(seccomp_actions_avail)]; + char old_names[sizeof(seccomp_actions_avail)]; + const char *new = names; + const char *old = old_names; + + if (!audit_enabled) + return; + + memset(names, 0, sizeof(names)); + memset(old_names, 0, sizeof(old_names)); + + if (ret) + new = "?"; + else if (!actions_logged) + new = "(none)"; + else if (!seccomp_names_from_actions_logged(names, sizeof(names), + actions_logged, ",")) + new = "?"; + + if (!old_actions_logged) + old = "(none)"; + else if (!seccomp_names_from_actions_logged(old_names, + sizeof(old_names), + old_actions_logged, ",")) + old = "?"; + + return audit_seccomp_actions_logged(new, old, !ret); +} + static int seccomp_actions_logged_handler(struct ctl_table *ro_table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - if (write) - return write_actions_logged(ro_table, buffer, lenp, ppos); - else - return read_actions_logged(ro_table, buffer, lenp, ppos); + int ret; + + if (write) { + u32 actions_logged = 0; + u32 old_actions_logged = seccomp_actions_logged; + + ret = write_actions_logged(ro_table, buffer, lenp, ppos, + &actions_logged); + audit_actions_logged(actions_logged, old_actions_logged, ret); + } else + ret = read_actions_logged(ro_table, buffer, lenp, ppos); + + return ret; } static struct ctl_path seccomp_sysctl_path[] = { |