Skip to content

Commit

Permalink
[PATCH] Capture selinux subject/object context information.
Browse files Browse the repository at this point in the history
This patch extends existing audit records with subject/object context
information. Audit records associated with filesystem inodes, ipc, and
tasks now contain SELinux label information in the field "subj" if the
item is performing the action, or in "obj" if the item is the receiver
of an action.

These labels are collected via hooks in SELinux and appended to the
appropriate record in the audit code.

This additional information is required for Common Criteria Labeled
Security Protection Profile (LSPP).

[AV: fixed kmalloc flags use]
[folded leak fixes]
[folded cleanup from akpm (kfree(NULL)]
[folded audit_inode_context() leak fix]
[folded akpm's fix for audit_ipc_perm() definition in case of !CONFIG_AUDIT]

Signed-off-by: Dustin Kirkland <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Dustin Kirkland authored and Al Viro committed Mar 20, 2006
1 parent c8edc80 commit 8c8570f
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 69 deletions.
8 changes: 6 additions & 2 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,14 @@ extern void auditsc_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 int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
extern void audit_signal_info(int sig, struct task_struct *t);
extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
extern int audit_filter_type(int type);
extern int audit_set_macxattr(const char *name);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
Expand All @@ -306,12 +307,13 @@ extern int audit_filter_type(int type);
#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#define audit_ipc_perms(q,u,g,m,i) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 0; })
#define audit_signal_info(s,t) do { ; } while (0)
#define audit_filter_user(cb,t) ({ 1; })
#define audit_set_macxattr(n) do { ; } while (0)
#endif

#ifdef CONFIG_AUDIT
Expand Down Expand Up @@ -340,6 +342,7 @@ extern void audit_send_reply(int pid, int seq, int type,
int done, int multi,
void *payload, int size);
extern void audit_log_lost(const char *message);
extern void audit_panic(const char *message);
extern struct semaphore audit_netlink_sem;
#else
#define audit_log(c,g,t,f,...) do { ; } while (0)
Expand All @@ -350,6 +353,7 @@ extern struct semaphore audit_netlink_sem;
#define audit_log_hex(a,b,l) do { ; } while (0)
#define audit_log_untrustedstring(a,s) do { ; } while (0)
#define audit_log_d_path(b,p,d,v) do { ; } while (0)
#define audit_panic(m) do { ; } while (0)
#endif
#endif
#endif
27 changes: 27 additions & 0 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,11 @@ struct swap_info_struct;
* @ipcp contains the kernel IPC permission structure
* @flag contains the desired (requested) permission set
* Return 0 if permission is granted.
* @ipc_getsecurity:
* Copy the security label associated with the ipc object into
* @buffer. @buffer may be NULL to request the size of the buffer
* required. @size indicates the size of @buffer in bytes. Return
* number of bytes used/required on success.
*
* Security hooks for individual messages held in System V IPC message queues
* @msg_msg_alloc_security:
Expand Down Expand Up @@ -1168,6 +1173,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
char *(*inode_xattr_getsuffix) (void);
int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
Expand Down Expand Up @@ -1217,6 +1223,7 @@ struct security_operations {
void (*task_to_inode)(struct task_struct *p, struct inode *inode);

int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);

int (*msg_msg_alloc_security) (struct msg_msg * msg);
void (*msg_msg_free_security) (struct msg_msg * msg);
Expand Down Expand Up @@ -1674,6 +1681,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}

static inline const char *security_inode_xattr_getsuffix(void)
{
return security_ops->inode_xattr_getsuffix();
}

static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
Expand Down Expand Up @@ -1869,6 +1881,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
return security_ops->ipc_permission (ipcp, flag);
}

static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
return security_ops->ipc_getsecurity(ipcp, buffer, size);
}

static inline int security_msg_msg_alloc (struct msg_msg * msg)
{
return security_ops->msg_msg_alloc_security (msg);
Expand Down Expand Up @@ -2316,6 +2333,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}

static inline const char *security_inode_xattr_getsuffix (void)
{
return NULL ;
}

static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
Expand Down Expand Up @@ -2499,6 +2521,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
return 0;
}

static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
{
return -EOPNOTSUPP;
}

static inline int security_msg_msg_alloc (struct msg_msg * msg)
{
return 0;
Expand Down
5 changes: 3 additions & 2 deletions ipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
return -EFAULT;
if (copy_msqid_from_user (&setbuf, buf, version))
return -EFAULT;
if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
break;
case IPC_RMID:
break;
Expand Down Expand Up @@ -461,6 +459,9 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
switch (cmd) {
case IPC_SET:
{
if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
goto out_unlock_up;

err = -EPERM;
if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
goto out_unlock_up;
Expand Down
5 changes: 2 additions & 3 deletions ipc/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,8 +809,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
if(cmd == IPC_SET) {
if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT;
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
}
sma = sem_lock(semid);
if(sma==NULL)
Expand All @@ -821,7 +819,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
goto out_unlock;
}
ipcp = &sma->sem_perm;

if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
err=-EPERM;
Expand All @@ -838,6 +835,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
err = 0;
break;
case IPC_SET:
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
goto out_unlock;
ipcp->uid = setbuf.uid;
ipcp->gid = setbuf.gid;
ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
Expand Down
4 changes: 2 additions & 2 deletions ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,13 +620,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = -EFAULT;
goto out;
}
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
return err;
down(&shm_ids.sem);
shp = shm_lock(shmid);
err=-EINVAL;
if(shp==NULL)
goto out_up;
if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm))))
goto out_unlock_up;
err = shm_checkid(shp,shmid);
if(err)
goto out_unlock_up;
Expand Down
2 changes: 1 addition & 1 deletion kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
nlh->nlmsg_pid = pid;
}

static void audit_panic(const char *message)
void audit_panic(const char *message)
{
switch (audit_failure)
{
Expand Down
Loading

0 comments on commit 8c8570f

Please sign in to comment.