type=SYSCALL msg=audit(1224363342.919:60): arch=c000003e syscall=59 success=yes exit=0
a0=9f7460 a1=9fe7c0 a2=a059e0 a3=3445170a70 items=2 ppid=2328 pid=2356 auid=0 uid=500
gid=500 euid=500 suid=500 fsuid=500 egid=500 sgid=500 fsgid=500 tty=pts0 ses=1
comm="ping" exe="/bin/ping"
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=EXECVE msg=audit(1224363342.919:60): argc=2 a0="ping"
a1="127.0.0.1"
type=UNKNOWN[1321] msg=audit(1224363342.919:60): file_permitted=0000000000003000
file_inheritable=0000000000003000 task_permitted=0000000000000000
task_inheritable=0000000000000000 task_effective=0000000000000000
bprm_effective=0000000000003000
type=CWD msg=audit(1224363342.919:60): cwd="/home/test"
type=PATH msg=audit(1224363342.919:60): item=0 name="/bin/ping" inode=49227
dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ping_exec_t:s0
cap_permitted=0000000000003000 cap_inheritable=0000000000003000
type=PATH msg=audit(1224363342.919:60): item=1 name=(null) inode=507963 dev=fd:00
mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ld_so_t:s0
So here's an example of my new record which shows a process getting new
capabilities. This record will only be created
if !(cap_issubset(bprm->cap_post_exec_permitted, tsk->cap_effective)).
So if a file has caps and but we already have those in our effective set
we will not generate this record. So 'root' executing ping would look
the same only there would be no record of type 1321....
Does this show the type of information you guys think would be useful?
-Eric
---
include/linux/audit.h | 4 +++
kernel/auditsc.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
security/commoncap.c | 3 ++
3 files changed, 60 insertions(+)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 6272a39..ba62b3e 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -99,6 +99,7 @@
#define AUDIT_OBJ_PID 1318 /* ptrace target */
#define AUDIT_TTY 1319 /* Input on an administrative TTY */
#define AUDIT_EOE 1320 /* End of multi-record event */
+#define AUDIT_BPRM_FCAPS 1321 /* Information about fcaps increasing perms */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -569,6 +570,8 @@ extern void audit_log_d_path(struct audit_buffer *ab,
extern void audit_log_lost(const char *message);
extern int audit_update_lsm_rules(void);
+extern int audit_log_bprm_fcaps(struct linux_binprm *bprm, struct cpu_vfs_cap_data
*caps);
+
/* Private API (for audit.c only) */
extern int audit_filter_user(struct netlink_skb_parms *cb);
extern int audit_filter_type(int type);
@@ -588,6 +591,7 @@ extern int audit_enabled;
#define audit_log_n_untrustedstring(a,n,s) do { ; } while (0)
#define audit_log_untrustedstring(a,s) do { ; } while (0)
#define audit_log_d_path(b, p, d) do { ; } while (0)
+#define audit_log_bprm_fcaps(b, c) 0
#define audit_enabled 0
#endif
#endif
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d8eb36b..5809c6f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -187,6 +187,16 @@ struct audit_aux_data_pids {
int pid_count;
};
+struct audit_aux_data_bprm_fcaps {
+ struct audit_aux_data d;
+ kernel_cap_t file_permitted;
+ kernel_cap_t file_inheritable;
+ kernel_cap_t task_permitted;
+ kernel_cap_t task_inheritable;
+ kernel_cap_t task_effective;
+ kernel_cap_t bprm_effective;
+};
+
struct audit_tree_refs {
struct audit_tree_refs *next;
struct audit_chunk *c[31];
@@ -1205,6 +1215,39 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct
audit_names *name)
audit_log_cap(ab, "cap_inheritable", inh);
}
+int audit_log_bprm_fcaps(struct linux_binprm *bprm, struct cpu_vfs_cap_data *caps)
+{
+ struct audit_aux_data_bprm_fcaps *ax;
+ struct audit_context *context = current->audit_context;
+ struct task_struct *tsk = current;
+
+ if (likely(!audit_enabled || !context || context->dummy))
+ return 0;
+
+ /* find out if bprm has a new cap */
+ if (cap_issubset(bprm->cap_post_exec_permitted, tsk->cap_effective))
+ return 0;
+
+ ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+ if (!ax)
+ return -ENOMEM;
+
+ ax->d.type = AUDIT_BPRM_FCAPS;
+ ax->d.next = context->aux;
+ context->aux = (void *)ax;
+
+ ax->file_permitted = caps->permitted;
+ ax->file_inheritable = caps->inheritable;
+
+ ax->task_permitted = tsk->cap_permitted;
+ ax->task_inheritable = tsk->cap_inheritable;
+ ax->task_effective = tsk->cap_effective;
+
+ ax->bprm_effective = bprm->cap_post_exec_permitted;
+
+ return 0;
+}
+
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
{
int i, call_panic = 0;
@@ -1368,6 +1411,16 @@ static void audit_log_exit(struct audit_context *context, struct
task_struct *ts
audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
break; }
+ case AUDIT_BPRM_FCAPS: {
+ struct audit_aux_data_bprm_fcaps *axs = (void *)aux;
+ audit_log_cap(ab, "file_permitted", &axs->file_permitted);
+ audit_log_cap(ab, "file_inheritable", &axs->file_inheritable);
+ audit_log_cap(ab, "task_permitted", &axs->task_permitted);
+ audit_log_cap(ab, "task_inheritable", &axs->task_inheritable);
+ audit_log_cap(ab, "task_effective", &axs->task_effective);
+ audit_log_cap(ab, "bprm_effective", &axs->bprm_effective);
+ break; }
+
}
audit_log_end(ab);
}
diff --git a/security/commoncap.c b/security/commoncap.c
index 9f109b9..f1e6801 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -8,6 +8,7 @@
*/
#include <linux/capability.h>
+#include <linux/audit.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -321,6 +322,8 @@ static int get_file_caps(struct linux_binprm *bprm)
printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
__func__, rc, bprm->filename);
+ audit_log_bprm_fcaps(bprm, &vcaps);
+
out:
dput(dentry);
if (rc)