Add a new record which shows when fcaps escalate permissions

Eric Paris eparis at redhat.com
Sat Oct 18 21:08:02 UTC 2008


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)





More information about the Linux-audit mailing list