Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/audit

Pull audit updates from Paul Moore:
 "Seven audit patches for 4.5, all very minor despite the diffstat.

  The diffstat churn for linux/audit.h can be attributed to needing to
  reshuffle the linux/audit.h header to fix the seccomp auditing issue
  (see the commit description for details).

  Besides the seccomp/audit fix, most of the fixes are around trying to
  improve the connection with the audit daemon and a Kconfig
  simplification.  Nothing crazy, and everything passes our little
  audit-testsuite"

* 'upstream' of git://git.infradead.org/users/pcmoore/audit:
  audit: always enable syscall auditing when supported and audit is enabled
  audit: force seccomp event logging to honor the audit_enabled flag
  audit: Delete unnecessary checks before two function calls
  audit: wake up threads if queue switched from limited to unlimited
  audit: include auditd's threads in audit_log_start() wait exception
  audit: remove audit_backlog_wait_overflow
  audit: don't needlessly reset valid wait time
This commit is contained in:
Linus Torvalds 2016-01-17 18:48:49 -08:00
commit 2d663b5581
3 changed files with 114 additions and 118 deletions

View File

@ -113,6 +113,107 @@ struct filename;
extern void audit_log_session_info(struct audit_buffer *ab); extern void audit_log_session_info(struct audit_buffer *ab);
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
extern __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...);
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
extern __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
extern void audit_log_end(struct audit_buffer *ab);
extern bool audit_string_contains_control(const char *string,
size_t len);
extern void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf,
size_t len);
extern void audit_log_n_string(struct audit_buffer *ab,
const char *buf,
size_t n);
extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string,
size_t n);
extern void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string);
extern void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path);
extern void audit_log_key(struct audit_buffer *ab,
char *key);
extern void audit_log_link_denied(const char *operation,
struct path *link);
extern void audit_log_lost(const char *message);
#ifdef CONFIG_SECURITY
extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
#else
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
#endif
extern int audit_log_task_context(struct audit_buffer *ab);
extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */
extern int audit_filter_user(int type);
extern int audit_filter_type(int type);
extern int audit_rule_change(int type, __u32 portid, int seq,
void *data, size_t datasz);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern u32 audit_enabled;
#else /* CONFIG_AUDIT */
static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{ }
static inline struct audit_buffer *audit_log_start(struct audit_context *ctx,
gfp_t gfp_mask, int type)
{
return NULL;
}
static inline __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
{ }
static inline void audit_log_end(struct audit_buffer *ab)
{ }
static inline void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf, size_t len)
{ }
static inline void audit_log_n_string(struct audit_buffer *ab,
const char *buf, size_t n)
{ }
static inline void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string, size_t n)
{ }
static inline void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string)
{ }
static inline void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path)
{ }
static inline void audit_log_key(struct audit_buffer *ab, char *key)
{ }
static inline void audit_log_link_denied(const char *string,
const struct path *link)
{ }
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
static inline int audit_log_task_context(struct audit_buffer *ab)
{
return 0;
}
static inline void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk)
{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
#ifdef CONFIG_AUDIT_COMPAT_GENERIC #ifdef CONFIG_AUDIT_COMPAT_GENERIC
#define audit_is_compat(arch) (!((arch) & __AUDIT_ARCH_64BIT)) #define audit_is_compat(arch) (!((arch) & __AUDIT_ARCH_64BIT))
#else #else
@ -212,6 +313,9 @@ void audit_core_dumps(long signr);
static inline void audit_seccomp(unsigned long syscall, long signr, int code) static inline void audit_seccomp(unsigned long syscall, long signr, int code)
{ {
if (!audit_enabled)
return;
/* Force a record to be reported if a signal was delivered. */ /* Force a record to be reported if a signal was delivered. */
if (signr || unlikely(!audit_dummy_context())) if (signr || unlikely(!audit_dummy_context()))
__audit_seccomp(syscall, signr, code); __audit_seccomp(syscall, signr, code);
@ -446,106 +550,6 @@ static inline bool audit_loginuid_set(struct task_struct *tsk)
return uid_valid(audit_get_loginuid(tsk)); return uid_valid(audit_get_loginuid(tsk));
} }
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
extern __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...);
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
extern __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
extern void audit_log_end(struct audit_buffer *ab);
extern bool audit_string_contains_control(const char *string,
size_t len);
extern void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf,
size_t len);
extern void audit_log_n_string(struct audit_buffer *ab,
const char *buf,
size_t n);
extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string,
size_t n);
extern void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string);
extern void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path);
extern void audit_log_key(struct audit_buffer *ab,
char *key);
extern void audit_log_link_denied(const char *operation,
struct path *link);
extern void audit_log_lost(const char *message);
#ifdef CONFIG_SECURITY
extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
#else
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
#endif
extern int audit_log_task_context(struct audit_buffer *ab);
extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */
extern int audit_filter_user(int type);
extern int audit_filter_type(int type);
extern int audit_rule_change(int type, __u32 portid, int seq,
void *data, size_t datasz);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern u32 audit_enabled;
#else /* CONFIG_AUDIT */
static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{ }
static inline struct audit_buffer *audit_log_start(struct audit_context *ctx,
gfp_t gfp_mask, int type)
{
return NULL;
}
static inline __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
{ }
static inline void audit_log_end(struct audit_buffer *ab)
{ }
static inline void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf, size_t len)
{ }
static inline void audit_log_n_string(struct audit_buffer *ab,
const char *buf, size_t n)
{ }
static inline void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string, size_t n)
{ }
static inline void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string)
{ }
static inline void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path)
{ }
static inline void audit_log_key(struct audit_buffer *ab, char *key)
{ }
static inline void audit_log_link_denied(const char *string,
const struct path *link)
{ }
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
{ }
static inline int audit_log_task_context(struct audit_buffer *ab)
{
return 0;
}
static inline void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk)
{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf) static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
{ {
audit_log_n_string(ab, buf, strlen(buf)); audit_log_n_string(ab, buf, strlen(buf));

View File

@ -299,20 +299,15 @@ config AUDIT
help help
Enable auditing infrastructure that can be used with another Enable auditing infrastructure that can be used with another
kernel subsystem, such as SELinux (which requires this for kernel subsystem, such as SELinux (which requires this for
logging of avc messages output). Does not do system-call logging of avc messages output). System call auditing is included
auditing without CONFIG_AUDITSYSCALL. on architectures which support it.
config HAVE_ARCH_AUDITSYSCALL config HAVE_ARCH_AUDITSYSCALL
bool bool
config AUDITSYSCALL config AUDITSYSCALL
bool "Enable system-call auditing support" def_bool y
depends on AUDIT && HAVE_ARCH_AUDITSYSCALL depends on AUDIT && HAVE_ARCH_AUDITSYSCALL
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
can be used independently or with another kernel subsystem,
such as SELinux.
config AUDIT_WATCH config AUDIT_WATCH
def_bool y def_bool y

View File

@ -110,7 +110,6 @@ static u32 audit_backlog_limit = 64;
#define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ)
static u32 audit_backlog_wait_time_master = AUDIT_BACKLOG_WAIT_TIME; static u32 audit_backlog_wait_time_master = AUDIT_BACKLOG_WAIT_TIME;
static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
static u32 audit_backlog_wait_overflow = 0;
/* The identity of the user shutting down the audit system. */ /* The identity of the user shutting down the audit system. */
kuid_t audit_sig_uid = INVALID_UID; kuid_t audit_sig_uid = INVALID_UID;
@ -509,7 +508,6 @@ static void flush_hold_queue(void)
* if auditd just disappeared but we * if auditd just disappeared but we
* dequeued an skb we need to drop ref * dequeued an skb we need to drop ref
*/ */
if (skb)
consume_skb(skb); consume_skb(skb);
} }
@ -524,7 +522,8 @@ static int kauditd_thread(void *dummy)
skb = skb_dequeue(&audit_skb_queue); skb = skb_dequeue(&audit_skb_queue);
if (skb) { if (skb) {
if (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit) if (!audit_backlog_limit ||
(skb_queue_len(&audit_skb_queue) <= audit_backlog_limit))
wake_up(&audit_backlog_wait); wake_up(&audit_backlog_wait);
if (audit_pid) if (audit_pid)
kauditd_send_skb(skb); kauditd_send_skb(skb);
@ -1232,9 +1231,7 @@ static void audit_buffer_free(struct audit_buffer *ab)
if (!ab) if (!ab)
return; return;
if (ab->skb)
kfree_skb(ab->skb); kfree_skb(ab->skb);
spin_lock_irqsave(&audit_freelist_lock, flags); spin_lock_irqsave(&audit_freelist_lock, flags);
if (audit_freelist_count > AUDIT_MAXFREE) if (audit_freelist_count > AUDIT_MAXFREE)
kfree(ab); kfree(ab);
@ -1372,7 +1369,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
return NULL; return NULL;
if (gfp_mask & __GFP_DIRECT_RECLAIM) { if (gfp_mask & __GFP_DIRECT_RECLAIM) {
if (audit_pid && audit_pid == current->pid) if (audit_pid && audit_pid == current->tgid)
gfp_mask &= ~__GFP_DIRECT_RECLAIM; gfp_mask &= ~__GFP_DIRECT_RECLAIM;
else else
reserve = 0; reserve = 0;
@ -1395,12 +1392,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
skb_queue_len(&audit_skb_queue), skb_queue_len(&audit_skb_queue),
audit_backlog_limit); audit_backlog_limit);
audit_log_lost("backlog limit exceeded"); audit_log_lost("backlog limit exceeded");
audit_backlog_wait_time = audit_backlog_wait_overflow; audit_backlog_wait_time = 0;
wake_up(&audit_backlog_wait); wake_up(&audit_backlog_wait);
return NULL; return NULL;
} }
if (!reserve) if (!reserve && !audit_backlog_wait_time)
audit_backlog_wait_time = audit_backlog_wait_time_master; audit_backlog_wait_time = audit_backlog_wait_time_master;
ab = audit_buffer_alloc(ctx, gfp_mask, type); ab = audit_buffer_alloc(ctx, gfp_mask, type);