Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/audit
Pull audit updates from Paul Moore: "Seven audit patches for 4.4, but really only one of any significant value, the remainder are trivial cleanups that are described well enough in the patch descriptions. The one significant patch is an attempt to make communication between the kernel's audit subsystem and the userspace audit daemon a bit more robust by retrying on certain transient error conditions. All in all, it's a pretty small set of patches this time around with just fixes and cleanups" * 'upstream' of git://git.infradead.org/users/pcmoore/audit: audit: make audit_log_common_recv_msg() a void function audit: removing unused variable audit: fix comment block whitespace audit: audit_tree_match can be boolean audit: audit_string_contains_control can be boolean audit: audit_dummy_context can be boolean audit: try harder to send to auditd upon netlink failure
This commit is contained in:
commit
3460b01b12
|
@ -143,7 +143,7 @@ extern void __audit_inode_child(const struct inode *parent,
|
||||||
extern void __audit_seccomp(unsigned long syscall, long signr, int code);
|
extern void __audit_seccomp(unsigned long syscall, long signr, int code);
|
||||||
extern void __audit_ptrace(struct task_struct *t);
|
extern void __audit_ptrace(struct task_struct *t);
|
||||||
|
|
||||||
static inline int audit_dummy_context(void)
|
static inline bool audit_dummy_context(void)
|
||||||
{
|
{
|
||||||
void *p = current->audit_context;
|
void *p = current->audit_context;
|
||||||
return !p || *(int *)p;
|
return !p || *(int *)p;
|
||||||
|
@ -345,9 +345,9 @@ static inline void audit_syscall_entry(int major, unsigned long a0,
|
||||||
{ }
|
{ }
|
||||||
static inline void audit_syscall_exit(void *pt_regs)
|
static inline void audit_syscall_exit(void *pt_regs)
|
||||||
{ }
|
{ }
|
||||||
static inline int audit_dummy_context(void)
|
static inline bool audit_dummy_context(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
static inline struct filename *audit_reusename(const __user char *name)
|
static inline struct filename *audit_reusename(const __user char *name)
|
||||||
{
|
{
|
||||||
|
@ -457,7 +457,7 @@ extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp
|
||||||
extern __printf(2, 3)
|
extern __printf(2, 3)
|
||||||
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
|
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
|
||||||
extern void audit_log_end(struct audit_buffer *ab);
|
extern void audit_log_end(struct audit_buffer *ab);
|
||||||
extern int audit_string_contains_control(const char *string,
|
extern bool audit_string_contains_control(const char *string,
|
||||||
size_t len);
|
size_t len);
|
||||||
extern void audit_log_n_hex(struct audit_buffer *ab,
|
extern void audit_log_n_hex(struct audit_buffer *ab,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
|
|
|
@ -407,16 +407,33 @@ static void audit_printk_skb(struct sk_buff *skb)
|
||||||
static void kauditd_send_skb(struct sk_buff *skb)
|
static void kauditd_send_skb(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
int attempts = 0;
|
||||||
|
#define AUDITD_RETRIES 5
|
||||||
|
|
||||||
|
restart:
|
||||||
/* take a reference in case we can't send it and we want to hold it */
|
/* take a reference in case we can't send it and we want to hold it */
|
||||||
skb_get(skb);
|
skb_get(skb);
|
||||||
err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
|
err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
|
pr_err("netlink_unicast sending to audit_pid=%d returned error: %d\n",
|
||||||
|
audit_pid, err);
|
||||||
if (audit_pid) {
|
if (audit_pid) {
|
||||||
pr_err("*NO* daemon at audit_pid=%d\n", audit_pid);
|
if (err == -ECONNREFUSED || err == -EPERM
|
||||||
audit_log_lost("auditd disappeared");
|
|| ++attempts >= AUDITD_RETRIES) {
|
||||||
audit_pid = 0;
|
char s[32];
|
||||||
audit_sock = NULL;
|
|
||||||
|
snprintf(s, sizeof(s), "audit_pid=%d reset", audit_pid);
|
||||||
|
audit_log_lost(s);
|
||||||
|
audit_pid = 0;
|
||||||
|
audit_sock = NULL;
|
||||||
|
} else {
|
||||||
|
pr_warn("re-scheduling(#%d) write to audit_pid=%d\n",
|
||||||
|
attempts, audit_pid);
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
schedule();
|
||||||
|
__set_current_state(TASK_RUNNING);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* we might get lucky and get this in the next auditd */
|
/* we might get lucky and get this in the next auditd */
|
||||||
audit_hold_skb(skb);
|
audit_hold_skb(skb);
|
||||||
|
@ -684,25 +701,22 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
|
static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
|
||||||
uid_t uid = from_kuid(&init_user_ns, current_uid());
|
uid_t uid = from_kuid(&init_user_ns, current_uid());
|
||||||
pid_t pid = task_tgid_nr(current);
|
pid_t pid = task_tgid_nr(current);
|
||||||
|
|
||||||
if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
|
if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
|
||||||
*ab = NULL;
|
*ab = NULL;
|
||||||
return rc;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
||||||
if (unlikely(!*ab))
|
if (unlikely(!*ab))
|
||||||
return rc;
|
return;
|
||||||
audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
|
audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
|
||||||
audit_log_session_info(*ab);
|
audit_log_session_info(*ab);
|
||||||
audit_log_task_context(*ab);
|
audit_log_task_context(*ab);
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_audit_feature_set(int i)
|
int is_audit_feature_set(int i)
|
||||||
|
@ -1566,14 +1580,14 @@ void audit_log_n_string(struct audit_buffer *ab, const char *string,
|
||||||
* @string: string to be checked
|
* @string: string to be checked
|
||||||
* @len: max length of the string to check
|
* @len: max length of the string to check
|
||||||
*/
|
*/
|
||||||
int audit_string_contains_control(const char *string, size_t len)
|
bool audit_string_contains_control(const char *string, size_t len)
|
||||||
{
|
{
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
for (p = string; p < (const unsigned char *)string + len; p++) {
|
for (p = string; p < (const unsigned char *)string + len; p++) {
|
||||||
if (*p == '"' || *p < 0x21 || *p > 0x7e)
|
if (*p == '"' || *p < 0x21 || *p > 0x7e)
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -301,7 +301,7 @@ extern int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark
|
||||||
#ifdef CONFIG_AUDIT_TREE
|
#ifdef CONFIG_AUDIT_TREE
|
||||||
extern struct audit_chunk *audit_tree_lookup(const struct inode *);
|
extern struct audit_chunk *audit_tree_lookup(const struct inode *);
|
||||||
extern void audit_put_chunk(struct audit_chunk *);
|
extern void audit_put_chunk(struct audit_chunk *);
|
||||||
extern int audit_tree_match(struct audit_chunk *, struct audit_tree *);
|
extern bool audit_tree_match(struct audit_chunk *, struct audit_tree *);
|
||||||
extern int audit_make_tree(struct audit_krule *, char *, u32);
|
extern int audit_make_tree(struct audit_krule *, char *, u32);
|
||||||
extern int audit_add_tree_rule(struct audit_krule *);
|
extern int audit_add_tree_rule(struct audit_krule *);
|
||||||
extern int audit_remove_tree_rule(struct audit_krule *);
|
extern int audit_remove_tree_rule(struct audit_krule *);
|
||||||
|
|
|
@ -197,13 +197,13 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
|
bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
for (n = 0; n < chunk->count; n++)
|
for (n = 0; n < chunk->count; n++)
|
||||||
if (chunk->owners[n].owner == tree)
|
if (chunk->owners[n].owner == tree)
|
||||||
return 1;
|
return true;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tagging and untagging inodes with trees */
|
/* tagging and untagging inodes with trees */
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
* Locking model:
|
* Locking model:
|
||||||
*
|
*
|
||||||
* audit_filter_mutex:
|
* audit_filter_mutex:
|
||||||
* Synchronizes writes and blocking reads of audit's filterlist
|
* Synchronizes writes and blocking reads of audit's filterlist
|
||||||
* data. Rcu is used to traverse the filterlist and access
|
* data. Rcu is used to traverse the filterlist and access
|
||||||
* contents of structs audit_entry, audit_watch and opaque
|
* contents of structs audit_entry, audit_watch and opaque
|
||||||
* LSM rules during filtering. If modified, these structures
|
* LSM rules during filtering. If modified, these structures
|
||||||
* must be copied and replace their counterparts in the filterlist.
|
* must be copied and replace their counterparts in the filterlist.
|
||||||
* An audit_parent struct is not accessed during filtering, so may
|
* An audit_parent struct is not accessed during filtering, so may
|
||||||
* be written directly provided audit_filter_mutex is held.
|
* be written directly provided audit_filter_mutex is held.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Audit filter lists, defined in <linux/audit.h> */
|
/* Audit filter lists, defined in <linux/audit.h> */
|
||||||
|
|
Loading…
Reference in a new issue