git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
SUNRPC: cache must take a reference to the cache detail's module on open()
[safe/jmp/linux-2.6]
/
kernel
/
auditsc.c
diff --git
a/kernel/auditsc.c
b/kernel/auditsc.c
index
19d2c27
..
68d3c6a
100644
(file)
--- a/
kernel/auditsc.c
+++ b/
kernel/auditsc.c
@@
-66,6
+66,7
@@
#include <linux/syscalls.h>
#include <linux/inotify.h>
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/inotify.h>
#include <linux/capability.h>
+#include <linux/fs_struct.h>
#include "audit.h"
#include "audit.h"
@@
-198,6
+199,7
@@
struct audit_context {
struct audit_tree_refs *trees, *first_trees;
int tree_count;
struct audit_tree_refs *trees, *first_trees;
int tree_count;
+ struct list_head killed_trees;
int type;
union {
int type;
union {
@@
-328,6
+330,14
@@
static int audit_match_filetype(struct audit_context *ctx, int which)
*/
#ifdef CONFIG_AUDIT_TREE
*/
#ifdef CONFIG_AUDIT_TREE
+static void audit_set_auditable(struct audit_context *ctx)
+{
+ if (!ctx->prio) {
+ ctx->prio = 1;
+ ctx->current_state = AUDIT_RECORD_CONTEXT;
+ }
+}
+
static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
{
struct audit_tree_refs *p = ctx->trees;
static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
{
struct audit_tree_refs *p = ctx->trees;
@@
-539,9
+549,9
@@
static int audit_filter_rules(struct task_struct *tsk,
}
break;
case AUDIT_WATCH:
}
break;
case AUDIT_WATCH:
- if (name &&
rule->watch->ino
!= (unsigned long)-1)
- result = (name->dev ==
rule->watch->dev
&&
- name->ino ==
rule->watch->ino
);
+ if (name &&
audit_watch_inode(rule->watch)
!= (unsigned long)-1)
+ result = (name->dev ==
audit_watch_dev(rule->watch)
&&
+ name->ino ==
audit_watch_inode(rule->watch)
);
break;
case AUDIT_DIR:
if (ctx)
break;
case AUDIT_DIR:
if (ctx)
@@
-652,7
+662,7
@@
static int audit_filter_rules(struct task_struct *tsk,
* completely disabled for this task. Since we only have the task
* structure at this point, we can only check uid and gid.
*/
* completely disabled for this task. Since we only have the task
* structure at this point, we can only check uid and gid.
*/
-static enum audit_state audit_filter_task(struct task_struct *tsk)
+static enum audit_state audit_filter_task(struct task_struct *tsk
, char **key
)
{
struct audit_entry *e;
enum audit_state state;
{
struct audit_entry *e;
enum audit_state state;
@@
-660,6
+670,8
@@
static enum audit_state audit_filter_task(struct task_struct *tsk)
rcu_read_lock();
list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
rcu_read_lock();
list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
+ if (state == AUDIT_RECORD_CONTEXT)
+ *key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
rcu_read_unlock();
return state;
}
rcu_read_unlock();
return state;
}
@@
-739,17
+751,9
@@
void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
rcu_read_unlock();
}
rcu_read_unlock();
}
-static void audit_set_auditable(struct audit_context *ctx)
-{
- if (!ctx->prio) {
- ctx->prio = 1;
- ctx->current_state = AUDIT_RECORD_CONTEXT;
- }
-}
-
static inline struct audit_context *audit_get_context(struct task_struct *tsk,
int return_valid,
static inline struct audit_context *audit_get_context(struct task_struct *tsk,
int return_valid,
-
int
return_code)
+
long
return_code)
{
struct audit_context *context = tsk->audit_context;
{
struct audit_context *context = tsk->audit_context;
@@
-850,6
+854,7
@@
static inline struct audit_context *audit_alloc_context(enum audit_state state)
if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
return NULL;
audit_zero_context(context, state);
if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
return NULL;
audit_zero_context(context, state);
+ INIT_LIST_HEAD(&context->killed_trees);
return context;
}
return context;
}
@@
-866,18
+871,21
@@
int audit_alloc(struct task_struct *tsk)
{
struct audit_context *context;
enum audit_state state;
{
struct audit_context *context;
enum audit_state state;
+ char *key = NULL;
if (likely(!audit_ever_enabled))
return 0; /* Return if not auditing. */
if (likely(!audit_ever_enabled))
return 0; /* Return if not auditing. */
- state = audit_filter_task(tsk);
+ state = audit_filter_task(tsk
, &key
);
if (likely(state == AUDIT_DISABLED))
return 0;
if (!(context = audit_alloc_context(state))) {
if (likely(state == AUDIT_DISABLED))
return 0;
if (!(context = audit_alloc_context(state))) {
+ kfree(key);
audit_log_lost("out of memory in audit_alloc");
return -ENOMEM;
}
audit_log_lost("out of memory in audit_alloc");
return -ENOMEM;
}
+ context->filterkey = key;
tsk->audit_context = context;
set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
tsk->audit_context = context;
set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
@@
-1018,8
+1026,8
@@
static int audit_log_single_execve_arg(struct audit_context *context,
{
char arg_num_len_buf[12];
const char __user *tmp_p = p;
{
char arg_num_len_buf[12];
const char __user *tmp_p = p;
- /* how many digits are in arg_num?
3 is the length of a=\n
*/
- size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) +
3
;
+ /* how many digits are in arg_num?
5 is the length of ' a=""'
*/
+ size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) +
5
;
size_t len, len_left, to_send;
size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
unsigned int i, has_cntl = 0, too_long = 0;
size_t len, len_left, to_send;
size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
unsigned int i, has_cntl = 0, too_long = 0;
@@
-1104,7
+1112,7
@@
static int audit_log_single_execve_arg(struct audit_context *context,
* so we can be sure nothing was lost.
*/
if ((i == 0) && (too_long))
* so we can be sure nothing was lost.
*/
if ((i == 0) && (too_long))
- audit_log_format(*ab, "
a%d_len=%zu
", arg_num,
+ audit_log_format(*ab, "
a%d_len=%zu
", arg_num,
has_cntl ? 2*len : len);
/*
has_cntl ? 2*len : len);
/*
@@
-1124,15
+1132,14
@@
static int audit_log_single_execve_arg(struct audit_context *context,
buf[to_send] = '\0';
/* actually log it */
buf[to_send] = '\0';
/* actually log it */
- audit_log_format(*ab, "a%d", arg_num);
+ audit_log_format(*ab, "
a%d", arg_num);
if (too_long)
audit_log_format(*ab, "[%d]", i);
audit_log_format(*ab, "=");
if (has_cntl)
audit_log_n_hex(*ab, buf, to_send);
else
if (too_long)
audit_log_format(*ab, "[%d]", i);
audit_log_format(*ab, "=");
if (has_cntl)
audit_log_n_hex(*ab, buf, to_send);
else
- audit_log_format(*ab, "\"%s\"", buf);
- audit_log_format(*ab, "\n");
+ audit_log_string(*ab, buf);
p += to_send;
len_left -= to_send;
p += to_send;
len_left -= to_send;
@@
-1160,7
+1167,7
@@
static void audit_log_execve_info(struct audit_context *context,
p = (const char __user *)axi->mm->arg_start;
p = (const char __user *)axi->mm->arg_start;
- audit_log_format(*ab, "argc=%d
", axi->argc);
+ audit_log_format(*ab, "argc=%d", axi->argc);
/*
* we need some kernel buffer to hold the userspace args. Just
/*
* we need some kernel buffer to hold the userspace args. Just
@@
-1367,11
+1374,7
@@
static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_task_info(ab, tsk);
audit_log_task_info(ab, tsk);
- if (context->filterkey) {
- audit_log_format(ab, " key=");
- audit_log_untrustedstring(ab, context->filterkey);
- } else
- audit_log_format(ab, " key=(null)");
+ audit_log_key(ab, context->filterkey);
audit_log_end(ab);
for (aux = context->aux; aux; aux = aux->next) {
audit_log_end(ab);
for (aux = context->aux; aux; aux = aux->next) {
@@
-1473,7
+1476,7
@@
static void audit_log_exit(struct audit_context *context, struct task_struct *ts
case 0:
/* name was specified as a relative path and the
* directory component is the cwd */
case 0:
/* name was specified as a relative path and the
* directory component is the cwd */
- audit_log_d_path(ab, "
name=", &context->pwd);
+ audit_log_d_path(ab, "name=", &context->pwd);
break;
default:
/* log the name's directory component */
break;
default:
/* log the name's directory component */
@@
-1544,6
+1547,8
@@
void audit_free(struct task_struct *tsk)
/* that can happen only if we are called from do_exit() */
if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
audit_log_exit(context, tsk);
/* that can happen only if we are called from do_exit() */
if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
audit_log_exit(context, tsk);
+ if (!list_empty(&context->killed_trees))
+ audit_kill_trees(&context->killed_trees);
audit_free_context(context);
}
audit_free_context(context);
}
@@
-1687,6
+1692,9
@@
void audit_syscall_exit(int valid, long return_code)
context->in_syscall = 0;
context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
context->in_syscall = 0;
context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
+ if (!list_empty(&context->killed_trees))
+ audit_kill_trees(&context->killed_trees);
+
if (context->previous) {
struct audit_context *new_context = context->previous;
context->previous = NULL;
if (context->previous) {
struct audit_context *new_context = context->previous;
context->previous = NULL;
@@
-1703,8
+1711,10
@@
void audit_syscall_exit(int valid, long return_code)
context->sockaddr_len = 0;
context->type = 0;
context->fds[0] = -1;
context->sockaddr_len = 0;
context->type = 0;
context->fds[0] = -1;
- kfree(context->filterkey);
- context->filterkey = NULL;
+ if (context->state != AUDIT_RECORD_CONTEXT) {
+ kfree(context->filterkey);
+ context->filterkey = NULL;
+ }
tsk->audit_context = context;
}
}
tsk->audit_context = context;
}
}
@@
-2142,7
+2152,7
@@
int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
* __audit_mq_open - record audit data for a POSIX MQ open
* @oflag: open flag
* @mode: mode bits
* __audit_mq_open - record audit data for a POSIX MQ open
* @oflag: open flag
* @mode: mode bits
- * @
u_
attr: queue attributes
+ * @attr: queue attributes
*
*/
void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
*
*/
void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
@@
-2189,7
+2199,7
@@
void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
/**
* __audit_mq_notify - record audit data for a POSIX MQ notify
* @mqdes: MQ descriptor
/**
* __audit_mq_notify - record audit data for a POSIX MQ notify
* @mqdes: MQ descriptor
- * @
u_
notification: Notification event
+ * @notification: Notification event
*
*/
*
*/
@@
-2518,3
+2528,11
@@
void audit_core_dumps(long signr)
audit_log_format(ab, " sig=%ld", signr);
audit_log_end(ab);
}
audit_log_format(ab, " sig=%ld", signr);
audit_log_end(ab);
}
+
+struct list_head *audit_killed_trees(void)
+{
+ struct audit_context *ctx = current->audit_context;
+ if (likely(!ctx || !ctx->in_syscall))
+ return NULL;
+ return &ctx->killed_trees;
+}