alistair23-linux/include/linux/lsm_audit.h
Vivek Goyal 43af5de742 lsm,audit,selinux: Introduce a new audit data type LSM_AUDIT_DATA_FILE
Right now LSM_AUDIT_DATA_PATH type contains "struct path" in union "u"
of common_audit_data. This information is used to print path of file
at the same time it is also used to get to dentry and inode. And this
inode information is used to get to superblock and device and print
device information.

This does not work well for layered filesystems like overlay where dentry
contained in path is overlay dentry and not the real dentry of underlying
file system. That means inode retrieved from dentry is also overlay
inode and not the real inode.

SELinux helpers like file_path_has_perm() are doing checks on inode
retrieved from file_inode(). This returns the real inode and not the
overlay inode. That means we are doing check on real inode but for audit
purposes we are printing details of overlay inode and that can be
confusing while debugging.

Hence, introduce a new type LSM_AUDIT_DATA_FILE which carries file
information and inode retrieved is real inode using file_inode(). That
way right avc denied information is given to user.

For example, following is one example avc before the patch.

  type=AVC msg=audit(1473360868.399:214): avc:  denied  { read open } for
    pid=1765 comm="cat"
    path="/root/.../overlay/container1/merged/readfile"
    dev="overlay" ino=21443
    scontext=unconfined_u:unconfined_r:test_overlay_client_t:s0:c10,c20
    tcontext=unconfined_u:object_r:test_overlay_files_ro_t:s0
    tclass=file permissive=0

It looks as follows after the patch.

  type=AVC msg=audit(1473360017.388:282): avc:  denied  { read open } for
    pid=2530 comm="cat"
    path="/root/.../overlay/container1/merged/readfile"
    dev="dm-0" ino=2377915
    scontext=unconfined_u:unconfined_r:test_overlay_client_t:s0:c10,c20
    tcontext=unconfined_u:object_r:test_overlay_files_ro_t:s0
    tclass=file permissive=0

Notice that now dev information points to "dm-0" device instead of
"overlay" device. This makes it clear that check failed on underlying
inode and not on the overlay inode.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
[PM: slight tweaks to the description to make checkpatch.pl happy]
Signed-off-by: Paul Moore <paul@paul-moore.com>
2016-09-19 13:42:38 -04:00

109 lines
2.4 KiB
C

/*
* Common LSM logging functions
* Heavily borrowed from selinux/avc.h
*
* Author : Etienne BASSET <etienne.basset@ensta.org>
*
* All credits to : Stephen Smalley, <sds@epoch.ncsc.mil>
* All BUGS to : Etienne BASSET <etienne.basset@ensta.org>
*/
#ifndef _LSM_COMMON_LOGGING_
#define _LSM_COMMON_LOGGING_
#include <linux/stddef.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/audit.h>
#include <linux/in6.h>
#include <linux/path.h>
#include <linux/key.h>
#include <linux/skbuff.h>
struct lsm_network_audit {
int netif;
struct sock *sk;
u16 family;
__be16 dport;
__be16 sport;
union {
struct {
__be32 daddr;
__be32 saddr;
} v4;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
} v6;
} fam;
};
struct lsm_ioctlop_audit {
struct path path;
u16 cmd;
};
/* Auxiliary data to use in generating the audit record. */
struct common_audit_data {
char type;
#define LSM_AUDIT_DATA_PATH 1
#define LSM_AUDIT_DATA_NET 2
#define LSM_AUDIT_DATA_CAP 3
#define LSM_AUDIT_DATA_IPC 4
#define LSM_AUDIT_DATA_TASK 5
#define LSM_AUDIT_DATA_KEY 6
#define LSM_AUDIT_DATA_NONE 7
#define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9
#define LSM_AUDIT_DATA_DENTRY 10
#define LSM_AUDIT_DATA_IOCTL_OP 11
#define LSM_AUDIT_DATA_FILE 12
union {
struct path path;
struct dentry *dentry;
struct inode *inode;
struct lsm_network_audit *net;
int cap;
int ipc_id;
struct task_struct *tsk;
#ifdef CONFIG_KEYS
struct {
key_serial_t key;
char *key_desc;
} key_struct;
#endif
char *kmod_name;
struct lsm_ioctlop_audit *op;
struct file *file;
} u;
/* this union contains LSM specific data */
union {
#ifdef CONFIG_SECURITY_SMACK
struct smack_audit_data *smack_audit_data;
#endif
#ifdef CONFIG_SECURITY_SELINUX
struct selinux_audit_data *selinux_audit_data;
#endif
#ifdef CONFIG_SECURITY_APPARMOR
struct apparmor_audit_data *apparmor_audit_data;
#endif
}; /* per LSM data pointer union */
};
#define v4info fam.v4
#define v6info fam.v6
int ipv4_skb_to_auditdata(struct sk_buff *skb,
struct common_audit_data *ad, u8 *proto);
int ipv6_skb_to_auditdata(struct sk_buff *skb,
struct common_audit_data *ad, u8 *proto);
void common_lsm_audit(struct common_audit_data *a,
void (*pre_audit)(struct audit_buffer *, void *),
void (*post_audit)(struct audit_buffer *, void *));
#endif