rpms/kernel/devel linux-2.6.12-rc4-audit-git.patch, NONE, 1.1 kernel-2.6.spec, 1.1296, 1.1297 linux-2.6.12-rc3-audit-git.patch, 1.1, NONE
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Wed May 11 12:02:27 UTC 2005
- Previous message (by thread): rpms/nc/devel nc-1.78-pollhup.patch,NONE,1.1 nc.spec,1.16,1.17
- Next message (by thread): rpms/usermode/devel .cvsignore, 1.36, 1.37 sources, 1.39, 1.40 usermode.spec, 1.44, 1.45
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: dwmw2
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv15150
Modified Files:
kernel-2.6.spec
Added Files:
linux-2.6.12-rc4-audit-git.patch
Removed Files:
linux-2.6.12-rc3-audit-git.patch
Log Message:
audit update
linux-2.6.12-rc4-audit-git.patch:
arch/ppc/Kconfig | 17 ++
arch/ppc/kernel/entry.S | 16 +-
arch/ppc/kernel/ppc_ksyms.c | 2
arch/ppc/kernel/ptrace.c | 40 +++++
include/asm-ppc/seccomp.h | 10 +
include/asm-ppc/thread_info.h | 7
include/linux/audit.h | 45 ++++--
init/Kconfig | 3
kernel/audit.c | 296 ++++++++++++++++++------------------------
kernel/auditsc.c | 51 ++++---
kernel/signal.c | 7
security/selinux/avc.c | 2
security/selinux/nlmsgtab.c | 1
13 files changed, 277 insertions(+), 220 deletions(-)
--- NEW FILE linux-2.6.12-rc4-audit-git.patch ---
Index: arch/ppc/Kconfig
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/arch/ppc/Kconfig (mode:100644)
+++ uncommitted/arch/ppc/Kconfig (mode:100644)
@@ -1083,6 +1083,23 @@
source kernel/power/Kconfig
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
endmenu
config ISA_DMA_API
Index: arch/ppc/kernel/entry.S
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/arch/ppc/kernel/entry.S (mode:100644)
+++ uncommitted/arch/ppc/kernel/entry.S (mode:100644)
@@ -202,7 +202,7 @@
rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR
stw r11,TI_LOCAL_FLAGS(r10)
lwz r11,TI_FLAGS(r10)
- andi. r11,r11,_TIF_SYSCALL_TRACE
+ andi. r11,r11,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
syscall_dotrace_cont:
cmplwi 0,r0,NR_syscalls
@@ -237,7 +237,7 @@
SYNC
MTMSRD(r10)
lwz r9,TI_FLAGS(r12)
- andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
bne- syscall_exit_work
syscall_exit_cont:
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
@@ -277,7 +277,8 @@
SAVE_NVGPRS(r1)
li r0,0xc00
stw r0,TRAP(r1)
- bl do_syscall_trace
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_enter
lwz r0,GPR0(r1) /* Restore original registers */
lwz r3,GPR3(r1)
lwz r4,GPR4(r1)
@@ -291,7 +292,7 @@
syscall_exit_work:
stw r6,RESULT(r1) /* Save result */
stw r3,GPR3(r1) /* Update return value */
- andi. r0,r9,_TIF_SYSCALL_TRACE
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
beq 5f
ori r10,r10,MSR_EE
SYNC
@@ -303,7 +304,8 @@
li r4,0xc00
stw r4,TRAP(r1)
4:
- bl do_syscall_trace
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_leave
REST_NVGPRS(r1)
2:
lwz r3,GPR3(r1)
@@ -627,8 +629,8 @@
subi r1,r3,STACK_FRAME_OVERHEAD
rlwinm r12,r1,0,0,18 /* current_thread_info() */
lwz r9,TI_FLAGS(r12)
- andi. r0,r9,_TIF_SYSCALL_TRACE
- bnel- do_syscall_trace
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ bnel- do_syscall_trace_leave
/* fall through */
.globl ret_from_except_full
Index: arch/ppc/kernel/ppc_ksyms.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/arch/ppc/kernel/ppc_ksyms.c (mode:100644)
+++ uncommitted/arch/ppc/kernel/ppc_ksyms.c (mode:100644)
@@ -55,7 +55,6 @@
#define EXPORT_SYMTAB_STROPS
extern void transfer_to_handler(void);
-extern void do_syscall_trace(void);
extern void do_IRQ(struct pt_regs *regs);
extern void MachineCheckException(struct pt_regs *regs);
extern void AlignmentException(struct pt_regs *regs);
@@ -74,7 +73,6 @@
EXPORT_SYMBOL(clear_pages);
EXPORT_SYMBOL(clear_user_page);
EXPORT_SYMBOL(do_signal);
-EXPORT_SYMBOL(do_syscall_trace);
EXPORT_SYMBOL(transfer_to_handler);
EXPORT_SYMBOL(do_IRQ);
EXPORT_SYMBOL(MachineCheckException);
Index: arch/ppc/kernel/ptrace.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/arch/ppc/kernel/ptrace.c (mode:100644)
+++ uncommitted/arch/ppc/kernel/ptrace.c (mode:100644)
@@ -27,6 +27,9 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/signal.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -455,11 +458,10 @@
return ret;
}
-void do_syscall_trace(void)
+static void do_syscall_trace(void)
{
- if (!test_thread_flag(TIF_SYSCALL_TRACE)
- || !(current->ptrace & PT_PTRACED))
- return;
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
@@ -473,3 +475,33 @@
current->exit_code = 0;
}
}
+
+void do_syscall_trace_enter(struct pt_regs *regs)
+{
+ if (test_thread_flag(TIF_SYSCALL_TRACE)
+ && (current->ptrace & PT_PTRACED))
+ do_syscall_trace();
+
+ if (unlikely(current->audit_context))
+ audit_syscall_entry(current, AUDIT_ARCH_PPC,
+ regs->gpr[0],
+ regs->gpr[3], regs->gpr[4],
+ regs->gpr[5], regs->gpr[6]);
+}
+
+void do_syscall_trace_leave(struct pt_regs *regs)
+{
+ secure_computing(regs->gpr[0]);
+
+ if (unlikely(current->audit_context))
+ audit_syscall_exit(current,
+ (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+ regs->result);
+
+ if ((test_thread_flag(TIF_SYSCALL_TRACE))
+ && (current->ptrace & PT_PTRACED))
+ do_syscall_trace();
+}
+
+EXPORT_SYMBOL(do_syscall_trace_enter);
+EXPORT_SYMBOL(do_syscall_trace_leave);
Index: include/asm-ppc/seccomp.h
===================================================================
--- /dev/null (tree:eed337ef5e9ae7d62caa84b7974a11fddc7f06e0)
+++ uncommitted/include/asm-ppc/seccomp.h (mode:100644)
@@ -0,0 +1,10 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
Index: include/asm-ppc/thread_info.h
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/include/asm-ppc/thread_info.h (mode:100644)
+++ uncommitted/include/asm-ppc/thread_info.h (mode:100644)
@@ -77,12 +77,19 @@
#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_MEMDIE 5
+#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
+#define TIF_SECCOMP 7 /* secure computing */
+
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+
+#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
/*
* Non racy (local) flags bit numbers
Index: include/linux/audit.h
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/include/linux/audit.h (mode:100644)
+++ uncommitted/include/linux/audit.h (mode:100644)
@@ -28,14 +28,16 @@
#include <linux/elf.h>
/* Request and reply types */
-#define AUDIT_GET 1000 /* Get status */
-#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
-#define AUDIT_LIST 1002 /* List filtering rules */
-#define AUDIT_ADD 1003 /* Add filtering rule */
-#define AUDIT_DEL 1004 /* Delete filtering rule */
-#define AUDIT_USER 1005 /* Send a message from user-space */
-#define AUDIT_LOGIN 1006 /* Define the login id and informaiton */
-#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
+#define AUDIT_GET 1000 /* Get status */
+#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
+#define AUDIT_LIST 1002 /* List filtering rules */
+#define AUDIT_ADD 1003 /* Add filtering rule */
+#define AUDIT_DEL 1004 /* Delete filtering rule */
+#define AUDIT_USER 1005 /* Send a message from user-space */
+#define AUDIT_LOGIN 1006 /* Define the login id and information */
+#define AUDIT_SIGNAL_INFO 1010 /* Get information about sender of signal*/
+
+#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
/* Rule flags */
#define AUDIT_PER_TASK 0x01 /* Apply rule at task creation (not syscall) */
@@ -161,6 +163,11 @@
#ifdef __KERNEL__
+struct audit_sig_info {
+ uid_t uid;
+ pid_t pid;
+};
+
struct audit_buffer;
struct audit_context;
struct inode;
@@ -185,11 +192,12 @@
/* Private API (for audit.c only) */
extern int audit_receive_filter(int type, int pid, int uid, int seq,
void *data, uid_t loginuid);
-extern void audit_get_stamp(struct audit_context *ctx,
+extern int audit_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial);
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
+extern void audit_signal_info(int sig, struct task_struct *t);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
@@ -198,18 +206,24 @@
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i) do { ; } while (0)
+#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
+#define audit_get_stamp(c,t,s) ({ 0; })
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
+#define audit_signal_info(s,t) do { ; } while (0)
#endif
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
-extern void audit_log(struct audit_context *ctx,
- const char *fmt, ...)
- __attribute__((format(printf,2,3)));
+#define audit_log(ctx, fmt, args...) \
+ audit_log_type(ctx, AUDIT_KERNEL, 0, fmt, ##args)
+extern void audit_log_type(struct audit_context *ctx, int type,
+ int pid, const char *fmt, ...)
+ __attribute__((format(printf,4,5)));
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int type,
+ int pid);
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
@@ -229,8 +243,9 @@
void *payload, int size);
extern void audit_log_lost(const char *message);
#else
-#define audit_log(t,f,...) do { ; } while (0)
-#define audit_log_start(t) ({ NULL; })
+#define audit_log(c,f,...) do { ; } while (0)
+#define audit_log_type(c,t,p,f,...) do { ; } while (0)
+#define audit_log_start(c,t,p) ({ NULL; })
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
Index: init/Kconfig
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/init/Kconfig (mode:100644)
+++ uncommitted/init/Kconfig (mode:100644)
@@ -164,6 +164,7 @@
config AUDIT
bool "Auditing support"
+ depends on NET
default y if SECURITY_SELINUX
help
Enable auditing infrastructure that can be used with another
@@ -173,7 +174,7 @@
config AUDITSYSCALL
bool "Enable system-call auditing support"
- depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
+ depends on AUDIT && (X86 || PPC || PPC64 || ARCH_S390 || IA64 || UML)
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
Index: kernel/audit.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/kernel/audit.c (mode:100644)
+++ uncommitted/kernel/audit.c (mode:100644)
@@ -68,7 +68,7 @@
/* If audit records are to be written to the netlink socket, audit_pid
* contains the (non-zero) pid. */
-static int audit_pid;
+int audit_pid;
/* If audit_limit is non-zero, limit the rate of sending audit records
* to that number per second. This prevents DoS attacks, but results in
@@ -79,6 +79,10 @@
static int audit_backlog_limit = 64;
static atomic_t audit_backlog = ATOMIC_INIT(0);
+/* The identity of the user shutting down the audit system. */
+uid_t audit_sig_uid = -1;
+pid_t audit_sig_pid = -1;
+
/* Records can be lost in several ways:
0) [suppressed in audit_alloc]
1) out of memory in audit_log_start [kmalloc of struct audit_buffer]
@@ -132,23 +136,10 @@
* use simultaneously. */
struct audit_buffer {
struct list_head list;
- struct sk_buff_head sklist; /* formatted skbs ready to send */
+ struct sk_buff *skb; /* formatted skb ready to send */
struct audit_context *ctx; /* NULL or associated context */
- int len; /* used area of tmp */
- char tmp[AUDIT_BUFSIZ];
-
- /* Pointer to header and contents */
- struct nlmsghdr *nlh;
- int total;
- int type;
- int pid;
};
-void audit_set_type(struct audit_buffer *ab, int type)
-{
- ab->type = type;
-}
-
struct audit_entry {
struct list_head list;
struct audit_rule rule;
@@ -280,7 +271,6 @@
return old;
}
-#ifdef CONFIG_NET
void audit_send_reply(int pid, int seq, int type, int done, int multi,
void *payload, int size)
{
@@ -321,6 +311,7 @@
case AUDIT_SET:
case AUDIT_ADD:
case AUDIT_DEL:
+ case AUDIT_SIGNAL_INFO:
if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
@@ -341,9 +332,9 @@
void *data;
struct audit_status *status_get, status_set;
int err;
- struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
uid_t loginuid; /* loginuid of sender */
+ struct audit_sig_info sig_data;
err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
if (err)
@@ -392,19 +383,13 @@
loginuid);
break;
case AUDIT_USER:
- ab = audit_log_start(NULL);
- if (!ab)
- break; /* audit_panic has been called */
- audit_log_format(ab,
+ audit_log_type(NULL, AUDIT_USER, pid,
"user pid=%d uid=%d length=%d loginuid=%u"
" msg='%.1024s'",
pid, uid,
(int)(nlh->nlmsg_len
- ((char *)data - (char *)nlh)),
loginuid, (char *)data);
- ab->type = AUDIT_USER;
- ab->pid = pid;
- audit_log_end(ab);
break;
case AUDIT_ADD:
case AUDIT_DEL:
@@ -412,12 +397,14 @@
return -EINVAL;
/* fallthrough */
case AUDIT_LIST:
-#ifdef CONFIG_AUDITSYSCALL
err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
uid, seq, data, loginuid);
-#else
- err = -EOPNOTSUPP;
-#endif
+ break;
+ case AUDIT_SIGNAL_INFO:
+ sig_data.uid = audit_sig_uid;
+ sig_data.pid = audit_sig_pid;
+ audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
+ 0, 0, &sig_data, sizeof(sig_data));
break;
default:
err = -EINVAL;
@@ -467,64 +454,23 @@
up(&audit_netlink_sem);
}
-/* Move data from tmp buffer into an skb. This is an extra copy, and
- * that is unfortunate. However, the copy will only occur when a record
- * is being written to user space, which is already a high-overhead
- * operation. (Elimination of the copy is possible, for example, by
- * writing directly into a pre-allocated skb, at the cost of wasting
- * memory. */
-static void audit_log_move(struct audit_buffer *ab)
-{
- struct sk_buff *skb;
- char *start;
- int extra = ab->nlh ? 0 : NLMSG_SPACE(0);
-
- /* possible resubmission */
- if (ab->len == 0)
- return;
-
- skb = skb_peek_tail(&ab->sklist);
- if (!skb || skb_tailroom(skb) <= ab->len + extra) {
- skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
- if (!skb) {
- ab->len = 0; /* Lose information in ab->tmp */
- audit_log_lost("out of memory in audit_log_move");
- return;
- }
- __skb_queue_tail(&ab->sklist, skb);
- if (!ab->nlh)
- ab->nlh = (struct nlmsghdr *)skb_put(skb,
- NLMSG_SPACE(0));
- }
- start = skb_put(skb, ab->len);
- memcpy(start, ab->tmp, ab->len);
- ab->len = 0;
-}
-
-/* Iterate over the skbuff in the audit_buffer, sending their contents
- * to user space. */
+/* Grab skbuff from the audit_buffer and send to user space. */
static inline int audit_log_drain(struct audit_buffer *ab)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = ab->skb;
- while ((skb = skb_dequeue(&ab->sklist))) {
+ if (skb) {
int retval = 0;
if (audit_pid) {
- if (ab->nlh) {
- ab->nlh->nlmsg_len = ab->total;
- ab->nlh->nlmsg_type = ab->type;
- ab->nlh->nlmsg_flags = 0;
- ab->nlh->nlmsg_seq = 0;
- ab->nlh->nlmsg_pid = ab->pid;
- }
+ struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
+ nlh->nlmsg_len = skb->len - NLMSG_SPACE(0);
skb_get(skb); /* because netlink_* frees */
retval = netlink_unicast(audit_sock, skb, audit_pid,
MSG_DONTWAIT);
}
if (retval == -EAGAIN &&
(atomic_read(&audit_backlog)) < audit_backlog_limit) {
- skb_queue_head(&ab->sklist, skb);
audit_log_end_irq(ab);
return 1;
}
@@ -538,13 +484,11 @@
audit_log_lost("netlink socket too busy");
}
if (!audit_pid) { /* No daemon */
- int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
+ int offset = NLMSG_SPACE(0);
int len = skb->len - offset;
skb->data[offset + len] = '\0';
printk(KERN_ERR "%s\n", skb->data + offset);
}
- kfree_skb(skb);
- ab->nlh = NULL;
}
return 0;
}
@@ -563,35 +507,6 @@
audit_log(NULL, "initialized");
return 0;
}
-
-#else
-/* Without CONFIG_NET, we have no skbuffs. For now, print what we have
- * in the buffer. */
-static void audit_log_move(struct audit_buffer *ab)
-{
- printk(KERN_ERR "%*.*s\n", ab->len, ab->len, ab->tmp);
- ab->len = 0;
-}
-
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
- return 0;
-}
-
-/* Initialize audit support at boot time. */
-int __init audit_init(void)
-{
- printk(KERN_INFO "audit: initializing WITHOUT netlink support\n");
- audit_sock = NULL;
- audit_pid = 0;
-
- audit_initialized = 1;
- audit_enabled = audit_default;
- audit_log(NULL, "initialized");
- return 0;
-}
-#endif
-
__initcall(audit_init);
/* Process kernel command-line parameter at boot time. audit=0 or audit=1. */
@@ -608,6 +523,54 @@
__setup("audit=", audit_enable);
+static void audit_buffer_free(struct audit_buffer *ab)
+{
+ unsigned long flags;
+
+ if (!ab)
+ return;
+
+ if (ab->skb)
+ kfree_skb(ab->skb);
+ atomic_dec(&audit_backlog);
+ spin_lock_irqsave(&audit_freelist_lock, flags);
+ if (++audit_freelist_count > AUDIT_MAXFREE)
+ kfree(ab);
+ else
+ list_add(&ab->list, &audit_freelist);
+ spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
+{
+ unsigned long flags;
+ struct audit_buffer *ab = NULL;
+
+ spin_lock_irqsave(&audit_freelist_lock, flags);
+ if (!list_empty(&audit_freelist)) {
+ ab = list_entry(audit_freelist.next,
+ struct audit_buffer, list);
+ list_del(&ab->list);
+ --audit_freelist_count;
+ }
+ spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+ if (!ab) {
+ ab = kmalloc(sizeof(*ab), gfp_mask);
+ if (!ab)
+ goto err;
+ }
+ atomic_inc(&audit_backlog);
+
+ ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
+ if (!ab->skb)
+ goto err;
+
+ return ab;
+err:
+ audit_buffer_free(ab);
+ return NULL;
+}
/* Obtain an audit buffer. This routine does locking to obtain the
* audit buffer, but then no locking is required for calls to
@@ -615,12 +578,12 @@
* syscall, then the syscall is marked as auditable and an audit record
* will be written at syscall exit. If there is no associated task, tsk
* should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx)
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, int pid)
{
struct audit_buffer *ab = NULL;
- unsigned long flags;
struct timespec t;
unsigned int serial;
+ struct nlmsghdr *nlh;
if (!audit_initialized)
return NULL;
@@ -637,46 +600,47 @@
return NULL;
}
- spin_lock_irqsave(&audit_freelist_lock, flags);
- if (!list_empty(&audit_freelist)) {
- ab = list_entry(audit_freelist.next,
- struct audit_buffer, list);
- list_del(&ab->list);
- --audit_freelist_count;
- }
- spin_unlock_irqrestore(&audit_freelist_lock, flags);
-
- if (!ab)
- ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+ ab = audit_buffer_alloc(GFP_ATOMIC);
if (!ab) {
audit_log_lost("out of memory in audit_log_start");
return NULL;
}
- atomic_inc(&audit_backlog);
- skb_queue_head_init(&ab->sklist);
-
ab->ctx = ctx;
- ab->len = 0;
- ab->nlh = NULL;
- ab->total = 0;
- ab->type = AUDIT_KERNEL;
- ab->pid = 0;
-
-#ifdef CONFIG_AUDITSYSCALL
- if (ab->ctx)
- audit_get_stamp(ab->ctx, &t, &serial);
- else
-#endif
- {
+ nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
+ nlh->nlmsg_type = type;
+ nlh->nlmsg_flags = 0;
+ nlh->nlmsg_pid = pid;
+ nlh->nlmsg_seq = 0;
+
+ if (!audit_get_stamp(ab->ctx, &t, &serial)) {
t = CURRENT_TIME;
serial = 0;
}
+
audit_log_format(ab, "audit(%lu.%03lu:%u): ",
t.tv_sec, t.tv_nsec/1000000, serial);
return ab;
}
+/**
+ * audit_expand - expand skb in the audit buffer
+ * @ab: audit_buffer
+ *
+ * Returns 0 (no space) on failed expansion, or available space if
+ * successful.
+ */
+static inline int audit_expand(struct audit_buffer *ab, int extra)
+{
+ struct sk_buff *skb = ab->skb;
+ int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
+ GFP_ATOMIC);
+ if (ret < 0) {
+ audit_log_lost("out of memory in audit_expand");
+ return 0;
+ }
+ return skb_tailroom(skb);
+}
/* Format an audit message into the audit buffer. If there isn't enough
* room in the audit buffer, more room will be allocated and vsnprint
@@ -686,26 +650,34 @@
va_list args)
{
int len, avail;
+ struct sk_buff *skb;
+ va_list args2;
if (!ab)
return;
- avail = sizeof(ab->tmp) - ab->len;
- if (avail <= 0) {
- audit_log_move(ab);
- avail = sizeof(ab->tmp) - ab->len;
+ BUG_ON(!ab->skb);
+ skb = ab->skb;
+ avail = skb_tailroom(skb);
+ if (avail == 0) {
+ avail = audit_expand(ab, AUDIT_BUFSIZ);
+ if (!avail)
+ goto out;
}
- len = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
+ va_copy(args2, args);
+ len = vsnprintf(skb->tail, avail, fmt, args);
if (len >= avail) {
/* The printk buffer is 1024 bytes long, so if we get
* here and AUDIT_BUFSIZ is at least 1024, then we can
* log everything that printk could have logged. */
- audit_log_move(ab);
- avail = sizeof(ab->tmp) - ab->len;
- len = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
+ avail = audit_expand(ab, 1+len-avail);
+ if (!avail)
+ goto out;
+ len = vsnprintf(skb->tail, avail, fmt, args2);
}
- ab->len += (len < avail) ? len : avail;
- ab->total += (len < avail) ? len : avail;
+ skb_put(skb, (len < avail) ? len : avail);
+out:
+ return;
}
/* Format a message into the audit buffer. All the work is done in
@@ -751,23 +723,22 @@
struct dentry *dentry, struct vfsmount *vfsmnt)
{
char *p;
+ struct sk_buff *skb = ab->skb;
int len, avail;
- if (prefix) audit_log_format(ab, " %s", prefix);
+ if (prefix)
+ audit_log_format(ab, " %s", prefix);
- if (ab->len > 128)
- audit_log_move(ab);
- avail = sizeof(ab->tmp) - ab->len;
- p = d_path(dentry, vfsmnt, ab->tmp + ab->len, avail);
+ avail = skb_tailroom(skb);
+ p = d_path(dentry, vfsmnt, skb->tail, avail);
if (IS_ERR(p)) {
/* FIXME: can we save some information here? */
audit_log_format(ab, "<toolong>");
} else {
- /* path isn't at start of buffer */
- len = (ab->tmp + sizeof(ab->tmp) - 1) - p;
- memmove(ab->tmp + ab->len, p, len);
- ab->len += len;
- ab->total += len;
+ /* path isn't at start of buffer */
+ len = ((char *)skb->tail + avail - 1) - p;
+ memmove(skb->tail, p, len);
+ skb_put(skb, len);
}
}
@@ -812,26 +783,16 @@
* be called in an irq context. */
static void audit_log_end_fast(struct audit_buffer *ab)
{
- unsigned long flags;
-
BUG_ON(in_irq());
if (!ab)
return;
if (!audit_rate_check()) {
audit_log_lost("rate limit exceeded");
} else {
- audit_log_move(ab);
if (audit_log_drain(ab))
return;
}
-
- atomic_dec(&audit_backlog);
- spin_lock_irqsave(&audit_freelist_lock, flags);
- if (++audit_freelist_count > AUDIT_MAXFREE)
- kfree(ab);
- else
- list_add(&ab->list, &audit_freelist);
- spin_unlock_irqrestore(&audit_freelist_lock, flags);
+ audit_buffer_free(ab);
}
/* Send or queue the message in the audit buffer, depending on the
@@ -848,12 +809,13 @@
/* Log an audit record. This is a convenience function that calls
* audit_log_start, audit_log_vformat, and audit_log_end. It may be
* called in any context. */
-void audit_log(struct audit_context *ctx, const char *fmt, ...)
+void audit_log_type(struct audit_context *ctx, int type, int pid,
+ const char *fmt, ...)
{
struct audit_buffer *ab;
va_list args;
- ab = audit_log_start(ctx);
+ ab = audit_log_start(ctx, type, pid);
if (ab) {
va_start(args, fmt);
audit_log_vformat(ab, fmt, args);
Index: kernel/auditsc.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/kernel/auditsc.c (mode:100644)
+++ uncommitted/kernel/auditsc.c (mode:100644)
@@ -226,7 +226,6 @@
return -EFAULT; /* No matching rule */
}
-#ifdef CONFIG_NET
/* Copy rule from user-space to kernel-space. Called during
* AUDIT_ADD. */
static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
@@ -305,7 +304,6 @@
return err;
}
-#endif
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise. */
@@ -650,7 +648,7 @@
int i;
struct audit_buffer *ab;
- ab = audit_log_start(context);
+ ab = audit_log_start(context, AUDIT_KERNEL, 0);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "syscall=%d", context->major);
@@ -682,7 +680,7 @@
while (context->aux) {
struct audit_aux_data *aux;
- ab = audit_log_start(context);
+ ab = audit_log_start(context, AUDIT_KERNEL, 0);
if (!ab)
continue; /* audit_panic has been called */
@@ -703,7 +701,7 @@
}
for (i = 0; i < context->name_count; i++) {
- ab = audit_log_start(context);
+ ab = audit_log_start(context, AUDIT_KERNEL, 0);
if (!ab)
continue; /* audit_panic has been called */
audit_log_format(ab, "item=%d", i);
@@ -994,7 +992,7 @@
context->names[idx].rdev = inode->i_rdev;
}
-void audit_get_stamp(struct audit_context *ctx,
+int audit_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial)
{
if (ctx) {
@@ -1002,28 +1000,18 @@
t->tv_nsec = ctx->ctime.tv_nsec;
*serial = ctx->serial;
ctx->auditable = 1;
- } else {
- *t = CURRENT_TIME;
- *serial = 0;
+ return 1;
}
+ return 0;
}
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
{
if (task->audit_context) {
- struct audit_buffer *ab;
-
- ab = audit_log_start(NULL);
- if (ab) {
- audit_log_format(ab, "login pid=%d uid=%u "
- "old loginuid=%u new loginuid=%u",
- task->pid, task->uid,
- task->audit_context->loginuid, loginuid);
- audit_set_type(ab, AUDIT_LOGIN);
- audit_log_end(ab);
- }
+ audit_log_type(NULL, AUDIT_LOGIN, 0,
+ "login pid=%d uid=%u old loginuid=%u new loginuid=%u",
+ task->pid, task->uid, task->audit_context->loginuid,
+ loginuid);
task->audit_context->loginuid = loginuid;
}
return 0;
@@ -1056,3 +1044,22 @@
context->aux = (void *)ax;
return 0;
}
+
+void audit_signal_info(int sig, struct task_struct *t)
+{
+ extern pid_t audit_sig_pid;
+ extern uid_t audit_sig_uid;
+ extern int audit_pid;
+
+ if (unlikely(audit_pid && t->pid == audit_pid)) {
+ if (sig == SIGTERM || sig == SIGHUP) {
+ struct audit_context *ctx = current->audit_context;
+ audit_sig_pid = current->pid;
+ if (ctx)
+ audit_sig_uid = ctx->loginuid;
+ else
+ audit_sig_uid = current->uid;
+ }
+ }
+}
+
Index: kernel/signal.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/kernel/signal.c (mode:100644)
+++ uncommitted/kernel/signal.c (mode:100644)
@@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/posix-timers.h>
#include <linux/signal.h>
+#include <linux/audit.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -658,7 +659,11 @@
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
return error;
- return security_task_kill(t, info, sig);
+
+ error = security_task_kill(t, info, sig);
+ if (!error)
+ audit_signal_info(sig, t); /* Let audit system see the signal */
+ return error;
}
/* forward decl */
Index: security/selinux/avc.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/security/selinux/avc.c (mode:100644)
+++ uncommitted/security/selinux/avc.c (mode:100644)
@@ -549,7 +549,7 @@
return;
}
- ab = audit_log_start(current->audit_context);
+ ab = audit_log_start(current->audit_context, AUDIT_KERNEL, 0);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
Index: security/selinux/nlmsgtab.c
===================================================================
--- eed337ef5e9ae7d62caa84b7974a11fddc7f06e0/security/selinux/nlmsgtab.c (mode:100644)
+++ uncommitted/security/selinux/nlmsgtab.c (mode:100644)
@@ -97,6 +97,7 @@
{ AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
+ { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
};
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.1296
retrieving revision 1.1297
diff -u -r1.1296 -r1.1297
--- kernel-2.6.spec 11 May 2005 05:17:56 -0000 1.1296
+++ kernel-2.6.spec 11 May 2005 12:02:25 -0000 1.1297
@@ -336,7 +336,7 @@
Patch1800: linux-2.6.11-parport-sysctl-perms.patch
Patch1810: linux-2.6.11-libata-promise-pata-on-sata.patch
Patch1820: linux-2.6.12-input-kill-stupid-messages.patch
-Patch1830: linux-2.6.12-rc3-audit-git.patch
+Patch1830: linux-2.6.12-rc4-audit-git.patch
Patch2000: linux-2.6.11-vm-taint.patch
Patch2001: linux-2.6.9-vm-oomkiller-debugging.patch
@@ -762,7 +762,7 @@
# The input layer spews crap no-one cares about.
%patch1820 -p1
# Audit code from git tree which was imported into 2.6.12-rc4
-#%patch1830 -p1
+%patch1830 -p1
#
# VM related fixes.
@@ -1210,6 +1210,9 @@
%endif
%changelog
+* Wed May 11 2005 David Woodhouse <dwmw2 at redhat.com>
+- Import post-rc4 audit fixes from git, including ppc syscall auditing
+
* Wed May 11 2005 Dave Jones <davej at redhat.com>
- Revert NMI watchdog changes.
--- linux-2.6.12-rc3-audit-git.patch DELETED ---
- Previous message (by thread): rpms/nc/devel nc-1.78-pollhup.patch,NONE,1.1 nc.spec,1.16,1.17
- Next message (by thread): rpms/usermode/devel .cvsignore, 1.36, 1.37 sources, 1.39, 1.40 usermode.spec, 1.44, 1.45
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list