Merge branch 'audit.b61' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b61' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current: audit: validate comparison operations, store them in sane form clean up audit_rule_{add,del} a bit make sure that filterkey of task,always rules is reported audit rules ordering, part 2 fixing audit rule ordering mess, part 1 audit_update_lsm_rules() misses the audit_inode_hash[] ones sanitize audit_log_capset() sanitize audit_fd_pair() sanitize audit_mq_open() sanitize AUDIT_MQ_SENDRECV sanitize audit_mq_notify() sanitize audit_mq_getsetattr() sanitize audit_ipc_set_perm() sanitize audit_ipc_obj() sanitize audit_socketcall don't reallocate buffer in every audit_sockaddr()
This commit is contained in:
commit
fe0bdec68b
@ -1016,10 +1016,7 @@ int do_pipe_flags(int *fd, int flags)
|
|||||||
goto err_fdr;
|
goto err_fdr;
|
||||||
fdw = error;
|
fdw = error;
|
||||||
|
|
||||||
error = audit_fd_pair(fdr, fdw);
|
audit_fd_pair(fdr, fdw);
|
||||||
if (error < 0)
|
|
||||||
goto err_fdw;
|
|
||||||
|
|
||||||
fd_install(fdr, fr);
|
fd_install(fdr, fr);
|
||||||
fd_install(fdw, fw);
|
fd_install(fdw, fw);
|
||||||
fd[0] = fdr;
|
fd[0] = fdr;
|
||||||
@ -1027,8 +1024,6 @@ int do_pipe_flags(int *fd, int flags)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_fdw:
|
|
||||||
put_unused_fd(fdw);
|
|
||||||
err_fdr:
|
err_fdr:
|
||||||
put_unused_fd(fdr);
|
put_unused_fd(fdr);
|
||||||
err_read_pipe:
|
err_read_pipe:
|
||||||
|
@ -247,6 +247,18 @@
|
|||||||
#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
|
#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
|
||||||
#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
|
#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Audit_equal,
|
||||||
|
Audit_not_equal,
|
||||||
|
Audit_bitmask,
|
||||||
|
Audit_bittest,
|
||||||
|
Audit_lt,
|
||||||
|
Audit_gt,
|
||||||
|
Audit_le,
|
||||||
|
Audit_ge,
|
||||||
|
Audit_bad
|
||||||
|
};
|
||||||
|
|
||||||
/* Status symbols */
|
/* Status symbols */
|
||||||
/* Mask values */
|
/* Mask values */
|
||||||
#define AUDIT_STATUS_ENABLED 0x0001
|
#define AUDIT_STATUS_ENABLED 0x0001
|
||||||
@ -373,6 +385,8 @@ struct audit_krule {
|
|||||||
struct audit_watch *watch; /* associated watch */
|
struct audit_watch *watch; /* associated watch */
|
||||||
struct audit_tree *tree; /* associated watched tree */
|
struct audit_tree *tree; /* associated watched tree */
|
||||||
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
|
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
|
||||||
|
struct list_head list; /* for AUDIT_LIST* purposes only */
|
||||||
|
u64 prio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct audit_field {
|
struct audit_field {
|
||||||
@ -443,70 +457,56 @@ extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
|
|||||||
#define audit_get_loginuid(t) ((t)->loginuid)
|
#define audit_get_loginuid(t) ((t)->loginuid)
|
||||||
#define audit_get_sessionid(t) ((t)->sessionid)
|
#define audit_get_sessionid(t) ((t)->sessionid)
|
||||||
extern void audit_log_task_context(struct audit_buffer *ab);
|
extern void audit_log_task_context(struct audit_buffer *ab);
|
||||||
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
||||||
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
|
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
|
||||||
extern int audit_bprm(struct linux_binprm *bprm);
|
extern int audit_bprm(struct linux_binprm *bprm);
|
||||||
extern int audit_socketcall(int nargs, unsigned long *args);
|
extern void audit_socketcall(int nargs, unsigned long *args);
|
||||||
extern int audit_sockaddr(int len, void *addr);
|
extern int audit_sockaddr(int len, void *addr);
|
||||||
extern int __audit_fd_pair(int fd1, int fd2);
|
extern void __audit_fd_pair(int fd1, int fd2);
|
||||||
extern int audit_set_macxattr(const char *name);
|
extern int audit_set_macxattr(const char *name);
|
||||||
extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
|
extern void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr);
|
||||||
extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout);
|
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
|
||||||
extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout);
|
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
|
||||||
extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
|
extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
|
||||||
extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
|
|
||||||
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
||||||
const struct cred *new,
|
const struct cred *new,
|
||||||
const struct cred *old);
|
const struct cred *old);
|
||||||
extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
|
extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
|
||||||
|
|
||||||
static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
|
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_ipc_obj(ipcp);
|
__audit_ipc_obj(ipcp);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_fd_pair(int fd1, int fd2)
|
static inline void audit_fd_pair(int fd1, int fd2)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_fd_pair(fd1, fd2);
|
__audit_fd_pair(fd1, fd2);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
|
static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_ipc_set_perm(qbytes, uid, gid, mode);
|
__audit_ipc_set_perm(qbytes, uid, gid, mode);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
|
static inline void audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_mq_open(oflag, mode, u_attr);
|
__audit_mq_open(oflag, mode, attr);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout)
|
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
|
__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout)
|
static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
|
__audit_mq_notify(mqdes, notification);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
|
static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_mq_notify(mqdes, u_notification);
|
__audit_mq_getsetattr(mqdes, mqstat);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
|
|
||||||
{
|
|
||||||
if (unlikely(!audit_dummy_context()))
|
|
||||||
return __audit_mq_getsetattr(mqdes, mqstat);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
||||||
@ -518,12 +518,11 @@ static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int audit_log_capset(pid_t pid, const struct cred *new,
|
static inline void audit_log_capset(pid_t pid, const struct cred *new,
|
||||||
const struct cred *old)
|
const struct cred *old)
|
||||||
{
|
{
|
||||||
if (unlikely(!audit_dummy_context()))
|
if (unlikely(!audit_dummy_context()))
|
||||||
return __audit_log_capset(pid, new, old);
|
__audit_log_capset(pid, new, old);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int audit_n_rules;
|
extern int audit_n_rules;
|
||||||
@ -546,20 +545,19 @@ extern int audit_signals;
|
|||||||
#define audit_get_loginuid(t) (-1)
|
#define audit_get_loginuid(t) (-1)
|
||||||
#define audit_get_sessionid(t) (-1)
|
#define audit_get_sessionid(t) (-1)
|
||||||
#define audit_log_task_context(b) do { ; } while (0)
|
#define audit_log_task_context(b) do { ; } while (0)
|
||||||
#define audit_ipc_obj(i) ({ 0; })
|
#define audit_ipc_obj(i) ((void)0)
|
||||||
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
|
#define audit_ipc_set_perm(q,u,g,m) ((void)0)
|
||||||
#define audit_bprm(p) ({ 0; })
|
#define audit_bprm(p) ({ 0; })
|
||||||
#define audit_socketcall(n,a) ({ 0; })
|
#define audit_socketcall(n,a) ((void)0)
|
||||||
#define audit_fd_pair(n,a) ({ 0; })
|
#define audit_fd_pair(n,a) ((void)0)
|
||||||
#define audit_sockaddr(len, addr) ({ 0; })
|
#define audit_sockaddr(len, addr) ({ 0; })
|
||||||
#define audit_set_macxattr(n) do { ; } while (0)
|
#define audit_set_macxattr(n) do { ; } while (0)
|
||||||
#define audit_mq_open(o,m,a) ({ 0; })
|
#define audit_mq_open(o,m,a) ((void)0)
|
||||||
#define audit_mq_timedsend(d,l,p,t) ({ 0; })
|
#define audit_mq_sendrecv(d,l,p,t) ((void)0)
|
||||||
#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
|
#define audit_mq_notify(d,n) ((void)0)
|
||||||
#define audit_mq_notify(d,n) ({ 0; })
|
#define audit_mq_getsetattr(d,s) ((void)0)
|
||||||
#define audit_mq_getsetattr(d,s) ({ 0; })
|
|
||||||
#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
|
#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
|
||||||
#define audit_log_capset(pid, ncr, ocr) ({ 0; })
|
#define audit_log_capset(pid, ncr, ocr) ((void)0)
|
||||||
#define audit_ptrace(t) ((void)0)
|
#define audit_ptrace(t) ((void)0)
|
||||||
#define audit_n_rules 0
|
#define audit_n_rules 0
|
||||||
#define audit_signals 0
|
#define audit_signals 0
|
||||||
|
97
ipc/mqueue.c
97
ipc/mqueue.c
@ -524,31 +524,27 @@ static void __do_notify(struct mqueue_inode_info *info)
|
|||||||
wake_up(&info->wait_q);
|
wake_up(&info->wait_q);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long prepare_timeout(const struct timespec __user *u_arg)
|
static long prepare_timeout(struct timespec *p)
|
||||||
{
|
{
|
||||||
struct timespec ts, nowts;
|
struct timespec nowts;
|
||||||
long timeout;
|
long timeout;
|
||||||
|
|
||||||
if (u_arg) {
|
if (p) {
|
||||||
if (unlikely(copy_from_user(&ts, u_arg,
|
if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
|
||||||
sizeof(struct timespec))))
|
|| p->tv_nsec >= NSEC_PER_SEC))
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0
|
|
||||||
|| ts.tv_nsec >= NSEC_PER_SEC))
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
nowts = CURRENT_TIME;
|
nowts = CURRENT_TIME;
|
||||||
/* first subtract as jiffies can't be too big */
|
/* first subtract as jiffies can't be too big */
|
||||||
ts.tv_sec -= nowts.tv_sec;
|
p->tv_sec -= nowts.tv_sec;
|
||||||
if (ts.tv_nsec < nowts.tv_nsec) {
|
if (p->tv_nsec < nowts.tv_nsec) {
|
||||||
ts.tv_nsec += NSEC_PER_SEC;
|
p->tv_nsec += NSEC_PER_SEC;
|
||||||
ts.tv_sec--;
|
p->tv_sec--;
|
||||||
}
|
}
|
||||||
ts.tv_nsec -= nowts.tv_nsec;
|
p->tv_nsec -= nowts.tv_nsec;
|
||||||
if (ts.tv_sec < 0)
|
if (p->tv_sec < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
timeout = timespec_to_jiffies(&ts) + 1;
|
timeout = timespec_to_jiffies(p) + 1;
|
||||||
} else
|
} else
|
||||||
return MAX_SCHEDULE_TIMEOUT;
|
return MAX_SCHEDULE_TIMEOUT;
|
||||||
|
|
||||||
@ -592,22 +588,18 @@ static int mq_attr_ok(struct mq_attr *attr)
|
|||||||
* Invoked when creating a new queue via sys_mq_open
|
* Invoked when creating a new queue via sys_mq_open
|
||||||
*/
|
*/
|
||||||
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
|
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
|
||||||
int oflag, mode_t mode, struct mq_attr __user *u_attr)
|
int oflag, mode_t mode, struct mq_attr *attr)
|
||||||
{
|
{
|
||||||
const struct cred *cred = current_cred();
|
const struct cred *cred = current_cred();
|
||||||
struct mq_attr attr;
|
|
||||||
struct file *result;
|
struct file *result;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (u_attr) {
|
if (attr) {
|
||||||
ret = -EFAULT;
|
|
||||||
if (copy_from_user(&attr, u_attr, sizeof(attr)))
|
|
||||||
goto out;
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
if (!mq_attr_ok(&attr))
|
if (!mq_attr_ok(attr))
|
||||||
goto out;
|
goto out;
|
||||||
/* store for use during create */
|
/* store for use during create */
|
||||||
dentry->d_fsdata = &attr;
|
dentry->d_fsdata = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode &= ~current->fs->umask;
|
mode &= ~current->fs->umask;
|
||||||
@ -664,11 +656,13 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
|
|||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
char *name;
|
char *name;
|
||||||
|
struct mq_attr attr;
|
||||||
int fd, error;
|
int fd, error;
|
||||||
|
|
||||||
error = audit_mq_open(oflag, mode, u_attr);
|
if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
|
||||||
if (error != 0)
|
return -EFAULT;
|
||||||
return error;
|
|
||||||
|
audit_mq_open(oflag, mode, u_attr ? &attr : NULL);
|
||||||
|
|
||||||
if (IS_ERR(name = getname(u_name)))
|
if (IS_ERR(name = getname(u_name)))
|
||||||
return PTR_ERR(name);
|
return PTR_ERR(name);
|
||||||
@ -694,7 +688,8 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
|
|||||||
filp = do_open(dentry, oflag);
|
filp = do_open(dentry, oflag);
|
||||||
} else {
|
} else {
|
||||||
filp = do_create(mqueue_mnt->mnt_root, dentry,
|
filp = do_create(mqueue_mnt->mnt_root, dentry,
|
||||||
oflag, mode, u_attr);
|
oflag, mode,
|
||||||
|
u_attr ? &attr : NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error = -ENOENT;
|
error = -ENOENT;
|
||||||
@ -829,17 +824,22 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
|
|||||||
struct ext_wait_queue *receiver;
|
struct ext_wait_queue *receiver;
|
||||||
struct msg_msg *msg_ptr;
|
struct msg_msg *msg_ptr;
|
||||||
struct mqueue_inode_info *info;
|
struct mqueue_inode_info *info;
|
||||||
|
struct timespec ts, *p = NULL;
|
||||||
long timeout;
|
long timeout;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
|
if (u_abs_timeout) {
|
||||||
if (ret != 0)
|
if (copy_from_user(&ts, u_abs_timeout,
|
||||||
return ret;
|
sizeof(struct timespec)))
|
||||||
|
return -EFAULT;
|
||||||
|
p = &ts;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
|
if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
timeout = prepare_timeout(u_abs_timeout);
|
audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
|
||||||
|
timeout = prepare_timeout(p);
|
||||||
|
|
||||||
ret = -EBADF;
|
ret = -EBADF;
|
||||||
filp = fget(mqdes);
|
filp = fget(mqdes);
|
||||||
@ -918,12 +918,17 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
|
|||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct mqueue_inode_info *info;
|
struct mqueue_inode_info *info;
|
||||||
struct ext_wait_queue wait;
|
struct ext_wait_queue wait;
|
||||||
|
struct timespec ts, *p = NULL;
|
||||||
|
|
||||||
ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
|
if (u_abs_timeout) {
|
||||||
if (ret != 0)
|
if (copy_from_user(&ts, u_abs_timeout,
|
||||||
return ret;
|
sizeof(struct timespec)))
|
||||||
|
return -EFAULT;
|
||||||
|
p = &ts;
|
||||||
|
}
|
||||||
|
|
||||||
timeout = prepare_timeout(u_abs_timeout);
|
audit_mq_sendrecv(mqdes, msg_len, 0, p);
|
||||||
|
timeout = prepare_timeout(p);
|
||||||
|
|
||||||
ret = -EBADF;
|
ret = -EBADF;
|
||||||
filp = fget(mqdes);
|
filp = fget(mqdes);
|
||||||
@ -1003,17 +1008,17 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
|
|||||||
struct mqueue_inode_info *info;
|
struct mqueue_inode_info *info;
|
||||||
struct sk_buff *nc;
|
struct sk_buff *nc;
|
||||||
|
|
||||||
ret = audit_mq_notify(mqdes, u_notification);
|
if (u_notification) {
|
||||||
if (ret != 0)
|
if (copy_from_user(¬ification, u_notification,
|
||||||
return ret;
|
sizeof(struct sigevent)))
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
audit_mq_notify(mqdes, u_notification ? ¬ification : NULL);
|
||||||
|
|
||||||
nc = NULL;
|
nc = NULL;
|
||||||
sock = NULL;
|
sock = NULL;
|
||||||
if (u_notification != NULL) {
|
if (u_notification != NULL) {
|
||||||
if (copy_from_user(¬ification, u_notification,
|
|
||||||
sizeof(struct sigevent)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (unlikely(notification.sigev_notify != SIGEV_NONE &&
|
if (unlikely(notification.sigev_notify != SIGEV_NONE &&
|
||||||
notification.sigev_notify != SIGEV_SIGNAL &&
|
notification.sigev_notify != SIGEV_SIGNAL &&
|
||||||
notification.sigev_notify != SIGEV_THREAD))
|
notification.sigev_notify != SIGEV_THREAD))
|
||||||
@ -1150,11 +1155,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
|
|||||||
omqstat = info->attr;
|
omqstat = info->attr;
|
||||||
omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
|
omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
|
||||||
if (u_mqstat) {
|
if (u_mqstat) {
|
||||||
ret = audit_mq_getsetattr(mqdes, &mqstat);
|
audit_mq_getsetattr(mqdes, &mqstat);
|
||||||
if (ret != 0) {
|
|
||||||
spin_unlock(&info->lock);
|
|
||||||
goto out_fput;
|
|
||||||
}
|
|
||||||
if (mqstat.mq_flags & O_NONBLOCK)
|
if (mqstat.mq_flags & O_NONBLOCK)
|
||||||
filp->f_flags |= O_NONBLOCK;
|
filp->f_flags |= O_NONBLOCK;
|
||||||
else
|
else
|
||||||
|
@ -747,9 +747,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = audit_ipc_obj(&(shp->shm_perm));
|
audit_ipc_obj(&(shp->shm_perm));
|
||||||
if (err)
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
if (!capable(CAP_IPC_LOCK)) {
|
if (!capable(CAP_IPC_LOCK)) {
|
||||||
uid_t euid = current_euid();
|
uid_t euid = current_euid();
|
||||||
|
18
ipc/util.c
18
ipc/util.c
@ -624,10 +624,9 @@ void ipc_rcu_putref(void *ptr)
|
|||||||
int ipcperms (struct kern_ipc_perm *ipcp, short flag)
|
int ipcperms (struct kern_ipc_perm *ipcp, short flag)
|
||||||
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
|
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
|
||||||
uid_t euid = current_euid();
|
uid_t euid = current_euid();
|
||||||
int requested_mode, granted_mode, err;
|
int requested_mode, granted_mode;
|
||||||
|
|
||||||
if (unlikely((err = audit_ipc_obj(ipcp))))
|
audit_ipc_obj(ipcp);
|
||||||
return err;
|
|
||||||
requested_mode = (flag >> 6) | (flag >> 3) | flag;
|
requested_mode = (flag >> 6) | (flag >> 3) | flag;
|
||||||
granted_mode = ipcp->mode;
|
granted_mode = ipcp->mode;
|
||||||
if (euid == ipcp->cuid ||
|
if (euid == ipcp->cuid ||
|
||||||
@ -803,16 +802,10 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
|
|||||||
goto out_up;
|
goto out_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = audit_ipc_obj(ipcp);
|
audit_ipc_obj(ipcp);
|
||||||
if (err)
|
if (cmd == IPC_SET)
|
||||||
goto out_unlock;
|
audit_ipc_set_perm(extra_perm, perm->uid,
|
||||||
|
|
||||||
if (cmd == IPC_SET) {
|
|
||||||
err = audit_ipc_set_perm(extra_perm, perm->uid,
|
|
||||||
perm->gid, perm->mode);
|
perm->gid, perm->mode);
|
||||||
if (err)
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
euid = current_euid();
|
euid = current_euid();
|
||||||
if (euid == ipcp->cuid ||
|
if (euid == ipcp->cuid ||
|
||||||
@ -820,7 +813,6 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
|
|||||||
return ipcp;
|
return ipcp;
|
||||||
|
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
out_unlock:
|
|
||||||
ipc_unlock(ipcp);
|
ipc_unlock(ipcp);
|
||||||
out_up:
|
out_up:
|
||||||
up_write(&ids->rw_mutex);
|
up_write(&ids->rw_mutex);
|
||||||
|
@ -159,11 +159,8 @@ static inline int audit_signal_info(int sig, struct task_struct *t)
|
|||||||
return __audit_signal_info(sig, t);
|
return __audit_signal_info(sig, t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
extern enum audit_state audit_filter_inodes(struct task_struct *,
|
extern void audit_filter_inodes(struct task_struct *, struct audit_context *);
|
||||||
struct audit_context *);
|
|
||||||
extern void audit_set_auditable(struct audit_context *);
|
|
||||||
#else
|
#else
|
||||||
#define audit_signal_info(s,t) AUDIT_DISABLED
|
#define audit_signal_info(s,t) AUDIT_DISABLED
|
||||||
#define audit_filter_inodes(t,c) AUDIT_DISABLED
|
#define audit_filter_inodes(t,c) AUDIT_DISABLED
|
||||||
#define audit_set_auditable(c)
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -450,6 +450,7 @@ static void kill_rules(struct audit_tree *tree)
|
|||||||
audit_log_end(ab);
|
audit_log_end(ab);
|
||||||
rule->tree = NULL;
|
rule->tree = NULL;
|
||||||
list_del_rcu(&entry->list);
|
list_del_rcu(&entry->list);
|
||||||
|
list_del(&entry->rule.list);
|
||||||
call_rcu(&entry->rcu, audit_free_rule_rcu);
|
call_rcu(&entry->rcu, audit_free_rule_rcu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,7 +618,7 @@ int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
|
|||||||
|
|
||||||
if (pathname[0] != '/' ||
|
if (pathname[0] != '/' ||
|
||||||
rule->listnr != AUDIT_FILTER_EXIT ||
|
rule->listnr != AUDIT_FILTER_EXIT ||
|
||||||
op & ~AUDIT_EQUAL ||
|
op != Audit_equal ||
|
||||||
rule->inode_f || rule->watch || rule->tree)
|
rule->inode_f || rule->watch || rule->tree)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
rule->tree = alloc_tree(pathname);
|
rule->tree = alloc_tree(pathname);
|
||||||
|
@ -86,6 +86,14 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
|
|||||||
#error Fix audit_filter_list initialiser
|
#error Fix audit_filter_list initialiser
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[0]),
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[1]),
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[2]),
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[3]),
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[4]),
|
||||||
|
LIST_HEAD_INIT(audit_rules_list[5]),
|
||||||
|
};
|
||||||
|
|
||||||
DEFINE_MUTEX(audit_filter_mutex);
|
DEFINE_MUTEX(audit_filter_mutex);
|
||||||
|
|
||||||
@ -244,7 +252,8 @@ static inline int audit_to_inode(struct audit_krule *krule,
|
|||||||
struct audit_field *f)
|
struct audit_field *f)
|
||||||
{
|
{
|
||||||
if (krule->listnr != AUDIT_FILTER_EXIT ||
|
if (krule->listnr != AUDIT_FILTER_EXIT ||
|
||||||
krule->watch || krule->inode_f || krule->tree)
|
krule->watch || krule->inode_f || krule->tree ||
|
||||||
|
(f->op != Audit_equal && f->op != Audit_not_equal))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
krule->inode_f = f;
|
krule->inode_f = f;
|
||||||
@ -262,7 +271,7 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len,
|
|||||||
|
|
||||||
if (path[0] != '/' || path[len-1] == '/' ||
|
if (path[0] != '/' || path[len-1] == '/' ||
|
||||||
krule->listnr != AUDIT_FILTER_EXIT ||
|
krule->listnr != AUDIT_FILTER_EXIT ||
|
||||||
op & ~AUDIT_EQUAL ||
|
op != Audit_equal ||
|
||||||
krule->inode_f || krule->watch || krule->tree)
|
krule->inode_f || krule->watch || krule->tree)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -412,12 +421,32 @@ exit_err:
|
|||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 audit_ops[] =
|
||||||
|
{
|
||||||
|
[Audit_equal] = AUDIT_EQUAL,
|
||||||
|
[Audit_not_equal] = AUDIT_NOT_EQUAL,
|
||||||
|
[Audit_bitmask] = AUDIT_BIT_MASK,
|
||||||
|
[Audit_bittest] = AUDIT_BIT_TEST,
|
||||||
|
[Audit_lt] = AUDIT_LESS_THAN,
|
||||||
|
[Audit_gt] = AUDIT_GREATER_THAN,
|
||||||
|
[Audit_le] = AUDIT_LESS_THAN_OR_EQUAL,
|
||||||
|
[Audit_ge] = AUDIT_GREATER_THAN_OR_EQUAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 audit_to_op(u32 op)
|
||||||
|
{
|
||||||
|
u32 n;
|
||||||
|
for (n = Audit_equal; n < Audit_bad && audit_ops[n] != op; n++)
|
||||||
|
;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Translate struct audit_rule to kernel's rule respresentation.
|
/* Translate struct audit_rule to kernel's rule respresentation.
|
||||||
* Exists for backward compatibility with userspace. */
|
* Exists for backward compatibility with userspace. */
|
||||||
static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
||||||
{
|
{
|
||||||
struct audit_entry *entry;
|
struct audit_entry *entry;
|
||||||
struct audit_field *ino_f;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -427,12 +456,28 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
|||||||
|
|
||||||
for (i = 0; i < rule->field_count; i++) {
|
for (i = 0; i < rule->field_count; i++) {
|
||||||
struct audit_field *f = &entry->rule.fields[i];
|
struct audit_field *f = &entry->rule.fields[i];
|
||||||
|
u32 n;
|
||||||
|
|
||||||
|
n = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);
|
||||||
|
|
||||||
|
/* Support for legacy operators where
|
||||||
|
* AUDIT_NEGATE bit signifies != and otherwise assumes == */
|
||||||
|
if (n & AUDIT_NEGATE)
|
||||||
|
f->op = Audit_not_equal;
|
||||||
|
else if (!n)
|
||||||
|
f->op = Audit_equal;
|
||||||
|
else
|
||||||
|
f->op = audit_to_op(n);
|
||||||
|
|
||||||
|
entry->rule.vers_ops = (n & AUDIT_OPERATORS) ? 2 : 1;
|
||||||
|
|
||||||
f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);
|
|
||||||
f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
|
f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
|
||||||
f->val = rule->values[i];
|
f->val = rule->values[i];
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
if (f->op == Audit_bad)
|
||||||
|
goto exit_free;
|
||||||
|
|
||||||
switch(f->type) {
|
switch(f->type) {
|
||||||
default:
|
default:
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
@ -454,11 +499,8 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
|||||||
case AUDIT_EXIT:
|
case AUDIT_EXIT:
|
||||||
case AUDIT_SUCCESS:
|
case AUDIT_SUCCESS:
|
||||||
/* bit ops are only useful on syscall args */
|
/* bit ops are only useful on syscall args */
|
||||||
if (f->op == AUDIT_BIT_MASK ||
|
if (f->op == Audit_bitmask || f->op == Audit_bittest)
|
||||||
f->op == AUDIT_BIT_TEST) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AUDIT_ARG0:
|
case AUDIT_ARG0:
|
||||||
case AUDIT_ARG1:
|
case AUDIT_ARG1:
|
||||||
@ -467,11 +509,8 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
|||||||
break;
|
break;
|
||||||
/* arch is only allowed to be = or != */
|
/* arch is only allowed to be = or != */
|
||||||
case AUDIT_ARCH:
|
case AUDIT_ARCH:
|
||||||
if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL)
|
if (f->op != Audit_not_equal && f->op != Audit_equal)
|
||||||
&& (f->op != AUDIT_NEGATE) && (f->op)) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
}
|
|
||||||
entry->rule.arch_f = f;
|
entry->rule.arch_f = f;
|
||||||
break;
|
break;
|
||||||
case AUDIT_PERM:
|
case AUDIT_PERM:
|
||||||
@ -488,33 +527,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
|||||||
goto exit_free;
|
goto exit_free;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;
|
|
||||||
|
|
||||||
/* Support for legacy operators where
|
|
||||||
* AUDIT_NEGATE bit signifies != and otherwise assumes == */
|
|
||||||
if (f->op & AUDIT_NEGATE)
|
|
||||||
f->op = AUDIT_NOT_EQUAL;
|
|
||||||
else if (!f->op)
|
|
||||||
f->op = AUDIT_EQUAL;
|
|
||||||
else if (f->op == AUDIT_OPERATORS) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ino_f = entry->rule.inode_f;
|
if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal)
|
||||||
if (ino_f) {
|
|
||||||
switch(ino_f->op) {
|
|
||||||
case AUDIT_NOT_EQUAL:
|
|
||||||
entry->rule.inode_f = NULL;
|
entry->rule.inode_f = NULL;
|
||||||
case AUDIT_EQUAL:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_nofree:
|
exit_nofree:
|
||||||
return entry;
|
return entry;
|
||||||
@ -530,7 +546,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct audit_entry *entry;
|
struct audit_entry *entry;
|
||||||
struct audit_field *ino_f;
|
|
||||||
void *bufp;
|
void *bufp;
|
||||||
size_t remain = datasz - sizeof(struct audit_rule_data);
|
size_t remain = datasz - sizeof(struct audit_rule_data);
|
||||||
int i;
|
int i;
|
||||||
@ -546,11 +561,11 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||||||
struct audit_field *f = &entry->rule.fields[i];
|
struct audit_field *f = &entry->rule.fields[i];
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (!(data->fieldflags[i] & AUDIT_OPERATORS) ||
|
|
||||||
data->fieldflags[i] & ~AUDIT_OPERATORS)
|
f->op = audit_to_op(data->fieldflags[i]);
|
||||||
|
if (f->op == Audit_bad)
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
|
||||||
f->op = data->fieldflags[i] & AUDIT_OPERATORS;
|
|
||||||
f->type = data->fields[i];
|
f->type = data->fields[i];
|
||||||
f->val = data->values[i];
|
f->val = data->values[i];
|
||||||
f->lsm_str = NULL;
|
f->lsm_str = NULL;
|
||||||
@ -662,18 +677,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ino_f = entry->rule.inode_f;
|
if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal)
|
||||||
if (ino_f) {
|
|
||||||
switch(ino_f->op) {
|
|
||||||
case AUDIT_NOT_EQUAL:
|
|
||||||
entry->rule.inode_f = NULL;
|
entry->rule.inode_f = NULL;
|
||||||
case AUDIT_EQUAL:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = -EINVAL;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_nofree:
|
exit_nofree:
|
||||||
return entry;
|
return entry;
|
||||||
@ -713,10 +718,10 @@ static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule)
|
|||||||
rule->fields[i] = krule->fields[i].type;
|
rule->fields[i] = krule->fields[i].type;
|
||||||
|
|
||||||
if (krule->vers_ops == 1) {
|
if (krule->vers_ops == 1) {
|
||||||
if (krule->fields[i].op & AUDIT_NOT_EQUAL)
|
if (krule->fields[i].op == Audit_not_equal)
|
||||||
rule->fields[i] |= AUDIT_NEGATE;
|
rule->fields[i] |= AUDIT_NEGATE;
|
||||||
} else {
|
} else {
|
||||||
rule->fields[i] |= krule->fields[i].op;
|
rule->fields[i] |= audit_ops[krule->fields[i].op];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];
|
for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];
|
||||||
@ -744,7 +749,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
|
|||||||
struct audit_field *f = &krule->fields[i];
|
struct audit_field *f = &krule->fields[i];
|
||||||
|
|
||||||
data->fields[i] = f->type;
|
data->fields[i] = f->type;
|
||||||
data->fieldflags[i] = f->op;
|
data->fieldflags[i] = audit_ops[f->op];
|
||||||
switch(f->type) {
|
switch(f->type) {
|
||||||
case AUDIT_SUBJ_USER:
|
case AUDIT_SUBJ_USER:
|
||||||
case AUDIT_SUBJ_ROLE:
|
case AUDIT_SUBJ_ROLE:
|
||||||
@ -919,6 +924,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
|
|||||||
new->action = old->action;
|
new->action = old->action;
|
||||||
for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
|
for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
|
||||||
new->mask[i] = old->mask[i];
|
new->mask[i] = old->mask[i];
|
||||||
|
new->prio = old->prio;
|
||||||
new->buflen = old->buflen;
|
new->buflen = old->buflen;
|
||||||
new->inode_f = old->inode_f;
|
new->inode_f = old->inode_f;
|
||||||
new->watch = NULL;
|
new->watch = NULL;
|
||||||
@ -987,9 +993,8 @@ static void audit_update_watch(struct audit_parent *parent,
|
|||||||
|
|
||||||
/* If the update involves invalidating rules, do the inode-based
|
/* If the update involves invalidating rules, do the inode-based
|
||||||
* filtering now, so we don't omit records. */
|
* filtering now, so we don't omit records. */
|
||||||
if (invalidating && current->audit_context &&
|
if (invalidating && current->audit_context)
|
||||||
audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT)
|
audit_filter_inodes(current, current->audit_context);
|
||||||
audit_set_auditable(current->audit_context);
|
|
||||||
|
|
||||||
nwatch = audit_dupe_watch(owatch);
|
nwatch = audit_dupe_watch(owatch);
|
||||||
if (IS_ERR(nwatch)) {
|
if (IS_ERR(nwatch)) {
|
||||||
@ -1007,12 +1012,15 @@ static void audit_update_watch(struct audit_parent *parent,
|
|||||||
list_del_rcu(&oentry->list);
|
list_del_rcu(&oentry->list);
|
||||||
|
|
||||||
nentry = audit_dupe_rule(&oentry->rule, nwatch);
|
nentry = audit_dupe_rule(&oentry->rule, nwatch);
|
||||||
if (IS_ERR(nentry))
|
if (IS_ERR(nentry)) {
|
||||||
|
list_del(&oentry->rule.list);
|
||||||
audit_panic("error updating watch, removing");
|
audit_panic("error updating watch, removing");
|
||||||
else {
|
} else {
|
||||||
int h = audit_hash_ino((u32)ino);
|
int h = audit_hash_ino((u32)ino);
|
||||||
list_add(&nentry->rule.rlist, &nwatch->rules);
|
list_add(&nentry->rule.rlist, &nwatch->rules);
|
||||||
list_add_rcu(&nentry->list, &audit_inode_hash[h]);
|
list_add_rcu(&nentry->list, &audit_inode_hash[h]);
|
||||||
|
list_replace(&oentry->rule.list,
|
||||||
|
&nentry->rule.list);
|
||||||
}
|
}
|
||||||
|
|
||||||
call_rcu(&oentry->rcu, audit_free_rule_rcu);
|
call_rcu(&oentry->rcu, audit_free_rule_rcu);
|
||||||
@ -1077,6 +1085,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
|
|||||||
audit_log_end(ab);
|
audit_log_end(ab);
|
||||||
}
|
}
|
||||||
list_del(&r->rlist);
|
list_del(&r->rlist);
|
||||||
|
list_del(&r->list);
|
||||||
list_del_rcu(&e->list);
|
list_del_rcu(&e->list);
|
||||||
call_rcu(&e->rcu, audit_free_rule_rcu);
|
call_rcu(&e->rcu, audit_free_rule_rcu);
|
||||||
}
|
}
|
||||||
@ -1102,12 +1111,16 @@ static void audit_inotify_unregister(struct list_head *in_list)
|
|||||||
/* Find an existing audit rule.
|
/* Find an existing audit rule.
|
||||||
* Caller must hold audit_filter_mutex to prevent stale rule data. */
|
* Caller must hold audit_filter_mutex to prevent stale rule data. */
|
||||||
static struct audit_entry *audit_find_rule(struct audit_entry *entry,
|
static struct audit_entry *audit_find_rule(struct audit_entry *entry,
|
||||||
struct list_head *list)
|
struct list_head **p)
|
||||||
{
|
{
|
||||||
struct audit_entry *e, *found = NULL;
|
struct audit_entry *e, *found = NULL;
|
||||||
|
struct list_head *list;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
if (entry->rule.watch) {
|
if (entry->rule.inode_f) {
|
||||||
|
h = audit_hash_ino(entry->rule.inode_f->val);
|
||||||
|
*p = list = &audit_inode_hash[h];
|
||||||
|
} else if (entry->rule.watch) {
|
||||||
/* we don't know the inode number, so must walk entire hash */
|
/* we don't know the inode number, so must walk entire hash */
|
||||||
for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
|
for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
|
||||||
list = &audit_inode_hash[h];
|
list = &audit_inode_hash[h];
|
||||||
@ -1118,6 +1131,8 @@ static struct audit_entry *audit_find_rule(struct audit_entry *entry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
|
} else {
|
||||||
|
*p = list = &audit_filter_list[entry->rule.listnr];
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(e, list, list)
|
list_for_each_entry(e, list, list)
|
||||||
@ -1258,15 +1273,17 @@ static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 prio_low = ~0ULL/2;
|
||||||
|
static u64 prio_high = ~0ULL/2 - 1;
|
||||||
|
|
||||||
/* Add rule to given filterlist if not a duplicate. */
|
/* Add rule to given filterlist if not a duplicate. */
|
||||||
static inline int audit_add_rule(struct audit_entry *entry,
|
static inline int audit_add_rule(struct audit_entry *entry)
|
||||||
struct list_head *list)
|
|
||||||
{
|
{
|
||||||
struct audit_entry *e;
|
struct audit_entry *e;
|
||||||
struct audit_field *inode_f = entry->rule.inode_f;
|
|
||||||
struct audit_watch *watch = entry->rule.watch;
|
struct audit_watch *watch = entry->rule.watch;
|
||||||
struct audit_tree *tree = entry->rule.tree;
|
struct audit_tree *tree = entry->rule.tree;
|
||||||
struct nameidata *ndp = NULL, *ndw = NULL;
|
struct nameidata *ndp = NULL, *ndw = NULL;
|
||||||
|
struct list_head *list;
|
||||||
int h, err;
|
int h, err;
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
int dont_count = 0;
|
int dont_count = 0;
|
||||||
@ -1277,13 +1294,8 @@ static inline int audit_add_rule(struct audit_entry *entry,
|
|||||||
dont_count = 1;
|
dont_count = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (inode_f) {
|
|
||||||
h = audit_hash_ino(inode_f->val);
|
|
||||||
list = &audit_inode_hash[h];
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&audit_filter_mutex);
|
mutex_lock(&audit_filter_mutex);
|
||||||
e = audit_find_rule(entry, list);
|
e = audit_find_rule(entry, &list);
|
||||||
mutex_unlock(&audit_filter_mutex);
|
mutex_unlock(&audit_filter_mutex);
|
||||||
if (e) {
|
if (e) {
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
@ -1319,10 +1331,22 @@ static inline int audit_add_rule(struct audit_entry *entry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry->rule.prio = ~0ULL;
|
||||||
|
if (entry->rule.listnr == AUDIT_FILTER_EXIT) {
|
||||||
|
if (entry->rule.flags & AUDIT_FILTER_PREPEND)
|
||||||
|
entry->rule.prio = ++prio_high;
|
||||||
|
else
|
||||||
|
entry->rule.prio = --prio_low;
|
||||||
|
}
|
||||||
|
|
||||||
if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
|
if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
|
||||||
|
list_add(&entry->rule.list,
|
||||||
|
&audit_rules_list[entry->rule.listnr]);
|
||||||
list_add_rcu(&entry->list, list);
|
list_add_rcu(&entry->list, list);
|
||||||
entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
|
entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
|
||||||
} else {
|
} else {
|
||||||
|
list_add_tail(&entry->rule.list,
|
||||||
|
&audit_rules_list[entry->rule.listnr]);
|
||||||
list_add_tail_rcu(&entry->list, list);
|
list_add_tail_rcu(&entry->list, list);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
@ -1345,15 +1369,14 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove an existing rule from filterlist. */
|
/* Remove an existing rule from filterlist. */
|
||||||
static inline int audit_del_rule(struct audit_entry *entry,
|
static inline int audit_del_rule(struct audit_entry *entry)
|
||||||
struct list_head *list)
|
|
||||||
{
|
{
|
||||||
struct audit_entry *e;
|
struct audit_entry *e;
|
||||||
struct audit_field *inode_f = entry->rule.inode_f;
|
|
||||||
struct audit_watch *watch, *tmp_watch = entry->rule.watch;
|
struct audit_watch *watch, *tmp_watch = entry->rule.watch;
|
||||||
struct audit_tree *tree = entry->rule.tree;
|
struct audit_tree *tree = entry->rule.tree;
|
||||||
|
struct list_head *list;
|
||||||
LIST_HEAD(inotify_list);
|
LIST_HEAD(inotify_list);
|
||||||
int h, ret = 0;
|
int ret = 0;
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
int dont_count = 0;
|
int dont_count = 0;
|
||||||
|
|
||||||
@ -1363,13 +1386,8 @@ static inline int audit_del_rule(struct audit_entry *entry,
|
|||||||
dont_count = 1;
|
dont_count = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (inode_f) {
|
|
||||||
h = audit_hash_ino(inode_f->val);
|
|
||||||
list = &audit_inode_hash[h];
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&audit_filter_mutex);
|
mutex_lock(&audit_filter_mutex);
|
||||||
e = audit_find_rule(entry, list);
|
e = audit_find_rule(entry, &list);
|
||||||
if (!e) {
|
if (!e) {
|
||||||
mutex_unlock(&audit_filter_mutex);
|
mutex_unlock(&audit_filter_mutex);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
@ -1404,6 +1422,7 @@ static inline int audit_del_rule(struct audit_entry *entry,
|
|||||||
audit_remove_tree_rule(&e->rule);
|
audit_remove_tree_rule(&e->rule);
|
||||||
|
|
||||||
list_del_rcu(&e->list);
|
list_del_rcu(&e->list);
|
||||||
|
list_del(&e->rule.list);
|
||||||
call_rcu(&e->rcu, audit_free_rule_rcu);
|
call_rcu(&e->rcu, audit_free_rule_rcu);
|
||||||
|
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
@ -1432,30 +1451,16 @@ out:
|
|||||||
static void audit_list(int pid, int seq, struct sk_buff_head *q)
|
static void audit_list(int pid, int seq, struct sk_buff_head *q)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct audit_entry *entry;
|
struct audit_krule *r;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* This is a blocking read, so use audit_filter_mutex instead of rcu
|
/* This is a blocking read, so use audit_filter_mutex instead of rcu
|
||||||
* iterator to sync with list writers. */
|
* iterator to sync with list writers. */
|
||||||
for (i=0; i<AUDIT_NR_FILTERS; i++) {
|
for (i=0; i<AUDIT_NR_FILTERS; i++) {
|
||||||
list_for_each_entry(entry, &audit_filter_list[i], list) {
|
list_for_each_entry(r, &audit_rules_list[i], list) {
|
||||||
struct audit_rule *rule;
|
struct audit_rule *rule;
|
||||||
|
|
||||||
rule = audit_krule_to_rule(&entry->rule);
|
rule = audit_krule_to_rule(r);
|
||||||
if (unlikely(!rule))
|
|
||||||
break;
|
|
||||||
skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
|
|
||||||
rule, sizeof(*rule));
|
|
||||||
if (skb)
|
|
||||||
skb_queue_tail(q, skb);
|
|
||||||
kfree(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < AUDIT_INODE_BUCKETS; i++) {
|
|
||||||
list_for_each_entry(entry, &audit_inode_hash[i], list) {
|
|
||||||
struct audit_rule *rule;
|
|
||||||
|
|
||||||
rule = audit_krule_to_rule(&entry->rule);
|
|
||||||
if (unlikely(!rule))
|
if (unlikely(!rule))
|
||||||
break;
|
break;
|
||||||
skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
|
skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
|
||||||
@ -1474,30 +1479,16 @@ static void audit_list(int pid, int seq, struct sk_buff_head *q)
|
|||||||
static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
|
static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct audit_entry *e;
|
struct audit_krule *r;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* This is a blocking read, so use audit_filter_mutex instead of rcu
|
/* This is a blocking read, so use audit_filter_mutex instead of rcu
|
||||||
* iterator to sync with list writers. */
|
* iterator to sync with list writers. */
|
||||||
for (i=0; i<AUDIT_NR_FILTERS; i++) {
|
for (i=0; i<AUDIT_NR_FILTERS; i++) {
|
||||||
list_for_each_entry(e, &audit_filter_list[i], list) {
|
list_for_each_entry(r, &audit_rules_list[i], list) {
|
||||||
struct audit_rule_data *data;
|
struct audit_rule_data *data;
|
||||||
|
|
||||||
data = audit_krule_to_data(&e->rule);
|
data = audit_krule_to_data(r);
|
||||||
if (unlikely(!data))
|
|
||||||
break;
|
|
||||||
skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
|
|
||||||
data, sizeof(*data) + data->buflen);
|
|
||||||
if (skb)
|
|
||||||
skb_queue_tail(q, skb);
|
|
||||||
kfree(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i=0; i< AUDIT_INODE_BUCKETS; i++) {
|
|
||||||
list_for_each_entry(e, &audit_inode_hash[i], list) {
|
|
||||||
struct audit_rule_data *data;
|
|
||||||
|
|
||||||
data = audit_krule_to_data(&e->rule);
|
|
||||||
if (unlikely(!data))
|
if (unlikely(!data))
|
||||||
break;
|
break;
|
||||||
skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
|
skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
|
||||||
@ -1603,8 +1594,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
|
|||||||
if (IS_ERR(entry))
|
if (IS_ERR(entry))
|
||||||
return PTR_ERR(entry);
|
return PTR_ERR(entry);
|
||||||
|
|
||||||
err = audit_add_rule(entry,
|
err = audit_add_rule(entry);
|
||||||
&audit_filter_list[entry->rule.listnr]);
|
|
||||||
audit_log_rule_change(loginuid, sessionid, sid, "add",
|
audit_log_rule_change(loginuid, sessionid, sid, "add",
|
||||||
&entry->rule, !err);
|
&entry->rule, !err);
|
||||||
|
|
||||||
@ -1620,8 +1610,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
|
|||||||
if (IS_ERR(entry))
|
if (IS_ERR(entry))
|
||||||
return PTR_ERR(entry);
|
return PTR_ERR(entry);
|
||||||
|
|
||||||
err = audit_del_rule(entry,
|
err = audit_del_rule(entry);
|
||||||
&audit_filter_list[entry->rule.listnr]);
|
|
||||||
audit_log_rule_change(loginuid, sessionid, sid, "remove",
|
audit_log_rule_change(loginuid, sessionid, sid, "remove",
|
||||||
&entry->rule, !err);
|
&entry->rule, !err);
|
||||||
|
|
||||||
@ -1634,28 +1623,29 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audit_comparator(const u32 left, const u32 op, const u32 right)
|
int audit_comparator(u32 left, u32 op, u32 right)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AUDIT_EQUAL:
|
case Audit_equal:
|
||||||
return (left == right);
|
return (left == right);
|
||||||
case AUDIT_NOT_EQUAL:
|
case Audit_not_equal:
|
||||||
return (left != right);
|
return (left != right);
|
||||||
case AUDIT_LESS_THAN:
|
case Audit_lt:
|
||||||
return (left < right);
|
return (left < right);
|
||||||
case AUDIT_LESS_THAN_OR_EQUAL:
|
case Audit_le:
|
||||||
return (left <= right);
|
return (left <= right);
|
||||||
case AUDIT_GREATER_THAN:
|
case Audit_gt:
|
||||||
return (left > right);
|
return (left > right);
|
||||||
case AUDIT_GREATER_THAN_OR_EQUAL:
|
case Audit_ge:
|
||||||
return (left >= right);
|
return (left >= right);
|
||||||
case AUDIT_BIT_MASK:
|
case Audit_bitmask:
|
||||||
return (left & right);
|
return (left & right);
|
||||||
case AUDIT_BIT_TEST:
|
case Audit_bittest:
|
||||||
return ((left & right) == right);
|
return ((left & right) == right);
|
||||||
}
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare given dentry name with last component in given path,
|
/* Compare given dentry name with last component in given path,
|
||||||
@ -1778,6 +1768,43 @@ unlock_and_return:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int update_lsm_rule(struct audit_krule *r)
|
||||||
|
{
|
||||||
|
struct audit_entry *entry = container_of(r, struct audit_entry, rule);
|
||||||
|
struct audit_entry *nentry;
|
||||||
|
struct audit_watch *watch;
|
||||||
|
struct audit_tree *tree;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!security_audit_rule_known(r))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
watch = r->watch;
|
||||||
|
tree = r->tree;
|
||||||
|
nentry = audit_dupe_rule(r, watch);
|
||||||
|
if (IS_ERR(nentry)) {
|
||||||
|
/* save the first error encountered for the
|
||||||
|
* return value */
|
||||||
|
err = PTR_ERR(nentry);
|
||||||
|
audit_panic("error updating LSM filters");
|
||||||
|
if (watch)
|
||||||
|
list_del(&r->rlist);
|
||||||
|
list_del_rcu(&entry->list);
|
||||||
|
list_del(&r->list);
|
||||||
|
} else {
|
||||||
|
if (watch) {
|
||||||
|
list_add(&nentry->rule.rlist, &watch->rules);
|
||||||
|
list_del(&r->rlist);
|
||||||
|
} else if (tree)
|
||||||
|
list_replace_init(&r->rlist, &nentry->rule.rlist);
|
||||||
|
list_replace_rcu(&entry->list, &nentry->list);
|
||||||
|
list_replace(&r->list, &nentry->rule.list);
|
||||||
|
}
|
||||||
|
call_rcu(&entry->rcu, audit_free_rule_rcu);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function will re-initialize the lsm_rule field of all applicable rules.
|
/* This function will re-initialize the lsm_rule field of all applicable rules.
|
||||||
* It will traverse the filter lists serarching for rules that contain LSM
|
* It will traverse the filter lists serarching for rules that contain LSM
|
||||||
* specific filter fields. When such a rule is found, it is copied, the
|
* specific filter fields. When such a rule is found, it is copied, the
|
||||||
@ -1785,45 +1812,19 @@ unlock_and_return:
|
|||||||
* updated rule. */
|
* updated rule. */
|
||||||
int audit_update_lsm_rules(void)
|
int audit_update_lsm_rules(void)
|
||||||
{
|
{
|
||||||
struct audit_entry *entry, *n, *nentry;
|
struct audit_krule *r, *n;
|
||||||
struct audit_watch *watch;
|
|
||||||
struct audit_tree *tree;
|
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
/* audit_filter_mutex synchronizes the writers */
|
/* audit_filter_mutex synchronizes the writers */
|
||||||
mutex_lock(&audit_filter_mutex);
|
mutex_lock(&audit_filter_mutex);
|
||||||
|
|
||||||
for (i = 0; i < AUDIT_NR_FILTERS; i++) {
|
for (i = 0; i < AUDIT_NR_FILTERS; i++) {
|
||||||
list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
|
list_for_each_entry_safe(r, n, &audit_rules_list[i], list) {
|
||||||
if (!security_audit_rule_known(&entry->rule))
|
int res = update_lsm_rule(r);
|
||||||
continue;
|
|
||||||
|
|
||||||
watch = entry->rule.watch;
|
|
||||||
tree = entry->rule.tree;
|
|
||||||
nentry = audit_dupe_rule(&entry->rule, watch);
|
|
||||||
if (IS_ERR(nentry)) {
|
|
||||||
/* save the first error encountered for the
|
|
||||||
* return value */
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = PTR_ERR(nentry);
|
err = res;
|
||||||
audit_panic("error updating LSM filters");
|
|
||||||
if (watch)
|
|
||||||
list_del(&entry->rule.rlist);
|
|
||||||
list_del_rcu(&entry->list);
|
|
||||||
} else {
|
|
||||||
if (watch) {
|
|
||||||
list_add(&nentry->rule.rlist,
|
|
||||||
&watch->rules);
|
|
||||||
list_del(&entry->rule.rlist);
|
|
||||||
} else if (tree)
|
|
||||||
list_replace_init(&entry->rule.rlist,
|
|
||||||
&nentry->rule.rlist);
|
|
||||||
list_replace_rcu(&entry->list, &nentry->list);
|
|
||||||
}
|
|
||||||
call_rcu(&entry->rcu, audit_free_rule_rcu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&audit_filter_mutex);
|
mutex_unlock(&audit_filter_mutex);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
729
kernel/auditsc.c
729
kernel/auditsc.c
File diff suppressed because it is too large
Load Diff
@ -280,9 +280,7 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret = audit_log_capset(pid, new, current_cred());
|
audit_log_capset(pid, new, current_cred());
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return commit_creds(new);
|
return commit_creds(new);
|
||||||
|
|
||||||
|
13
net/socket.c
13
net/socket.c
@ -1313,13 +1313,7 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
|
|||||||
goto out_fd1;
|
goto out_fd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = audit_fd_pair(fd1, fd2);
|
audit_fd_pair(fd1, fd2);
|
||||||
if (err < 0) {
|
|
||||||
fput(newfile1);
|
|
||||||
fput(newfile2);
|
|
||||||
goto out_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd_install(fd1, newfile1);
|
fd_install(fd1, newfile1);
|
||||||
fd_install(fd2, newfile2);
|
fd_install(fd2, newfile2);
|
||||||
/* fd1 and fd2 may be already another descriptors.
|
/* fd1 and fd2 may be already another descriptors.
|
||||||
@ -1349,7 +1343,6 @@ out_fd2:
|
|||||||
out_fd1:
|
out_fd1:
|
||||||
put_filp(newfile2);
|
put_filp(newfile2);
|
||||||
sock_release(sock2);
|
sock_release(sock2);
|
||||||
out_fd:
|
|
||||||
put_unused_fd(fd1);
|
put_unused_fd(fd1);
|
||||||
put_unused_fd(fd2);
|
put_unused_fd(fd2);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2065,9 +2058,7 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
|
|||||||
if (copy_from_user(a, args, nargs[call]))
|
if (copy_from_user(a, args, nargs[call]))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
|
audit_socketcall(nargs[call] / sizeof(unsigned long), a);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
a0 = a[0];
|
a0 = a[0];
|
||||||
a1 = a[1];
|
a1 = a[1];
|
||||||
|
@ -2602,7 +2602,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
|||||||
case AUDIT_OBJ_ROLE:
|
case AUDIT_OBJ_ROLE:
|
||||||
case AUDIT_OBJ_TYPE:
|
case AUDIT_OBJ_TYPE:
|
||||||
/* only 'equals' and 'not equals' fit user, role, and type */
|
/* only 'equals' and 'not equals' fit user, role, and type */
|
||||||
if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
|
if (op != Audit_equal && op != Audit_not_equal)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
case AUDIT_SUBJ_SEN:
|
case AUDIT_SUBJ_SEN:
|
||||||
@ -2736,10 +2736,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
|
|||||||
case AUDIT_SUBJ_USER:
|
case AUDIT_SUBJ_USER:
|
||||||
case AUDIT_OBJ_USER:
|
case AUDIT_OBJ_USER:
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AUDIT_EQUAL:
|
case Audit_equal:
|
||||||
match = (ctxt->user == rule->au_ctxt.user);
|
match = (ctxt->user == rule->au_ctxt.user);
|
||||||
break;
|
break;
|
||||||
case AUDIT_NOT_EQUAL:
|
case Audit_not_equal:
|
||||||
match = (ctxt->user != rule->au_ctxt.user);
|
match = (ctxt->user != rule->au_ctxt.user);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2747,10 +2747,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
|
|||||||
case AUDIT_SUBJ_ROLE:
|
case AUDIT_SUBJ_ROLE:
|
||||||
case AUDIT_OBJ_ROLE:
|
case AUDIT_OBJ_ROLE:
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AUDIT_EQUAL:
|
case Audit_equal:
|
||||||
match = (ctxt->role == rule->au_ctxt.role);
|
match = (ctxt->role == rule->au_ctxt.role);
|
||||||
break;
|
break;
|
||||||
case AUDIT_NOT_EQUAL:
|
case Audit_not_equal:
|
||||||
match = (ctxt->role != rule->au_ctxt.role);
|
match = (ctxt->role != rule->au_ctxt.role);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2758,10 +2758,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
|
|||||||
case AUDIT_SUBJ_TYPE:
|
case AUDIT_SUBJ_TYPE:
|
||||||
case AUDIT_OBJ_TYPE:
|
case AUDIT_OBJ_TYPE:
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AUDIT_EQUAL:
|
case Audit_equal:
|
||||||
match = (ctxt->type == rule->au_ctxt.type);
|
match = (ctxt->type == rule->au_ctxt.type);
|
||||||
break;
|
break;
|
||||||
case AUDIT_NOT_EQUAL:
|
case Audit_not_equal:
|
||||||
match = (ctxt->type != rule->au_ctxt.type);
|
match = (ctxt->type != rule->au_ctxt.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2774,31 +2774,31 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
|
|||||||
field == AUDIT_OBJ_LEV_LOW) ?
|
field == AUDIT_OBJ_LEV_LOW) ?
|
||||||
&ctxt->range.level[0] : &ctxt->range.level[1]);
|
&ctxt->range.level[0] : &ctxt->range.level[1]);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AUDIT_EQUAL:
|
case Audit_equal:
|
||||||
match = mls_level_eq(&rule->au_ctxt.range.level[0],
|
match = mls_level_eq(&rule->au_ctxt.range.level[0],
|
||||||
level);
|
level);
|
||||||
break;
|
break;
|
||||||
case AUDIT_NOT_EQUAL:
|
case Audit_not_equal:
|
||||||
match = !mls_level_eq(&rule->au_ctxt.range.level[0],
|
match = !mls_level_eq(&rule->au_ctxt.range.level[0],
|
||||||
level);
|
level);
|
||||||
break;
|
break;
|
||||||
case AUDIT_LESS_THAN:
|
case Audit_lt:
|
||||||
match = (mls_level_dom(&rule->au_ctxt.range.level[0],
|
match = (mls_level_dom(&rule->au_ctxt.range.level[0],
|
||||||
level) &&
|
level) &&
|
||||||
!mls_level_eq(&rule->au_ctxt.range.level[0],
|
!mls_level_eq(&rule->au_ctxt.range.level[0],
|
||||||
level));
|
level));
|
||||||
break;
|
break;
|
||||||
case AUDIT_LESS_THAN_OR_EQUAL:
|
case Audit_le:
|
||||||
match = mls_level_dom(&rule->au_ctxt.range.level[0],
|
match = mls_level_dom(&rule->au_ctxt.range.level[0],
|
||||||
level);
|
level);
|
||||||
break;
|
break;
|
||||||
case AUDIT_GREATER_THAN:
|
case Audit_gt:
|
||||||
match = (mls_level_dom(level,
|
match = (mls_level_dom(level,
|
||||||
&rule->au_ctxt.range.level[0]) &&
|
&rule->au_ctxt.range.level[0]) &&
|
||||||
!mls_level_eq(level,
|
!mls_level_eq(level,
|
||||||
&rule->au_ctxt.range.level[0]));
|
&rule->au_ctxt.range.level[0]));
|
||||||
break;
|
break;
|
||||||
case AUDIT_GREATER_THAN_OR_EQUAL:
|
case Audit_ge:
|
||||||
match = mls_level_dom(level,
|
match = mls_level_dom(level,
|
||||||
&rule->au_ctxt.range.level[0]);
|
&rule->au_ctxt.range.level[0]);
|
||||||
break;
|
break;
|
||||||
|
@ -2492,7 +2492,7 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
|||||||
if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
|
if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
|
if (op != Audit_equal && op != Audit_not_equal)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*rule = smk_import(rulestr, 0);
|
*rule = smk_import(rulestr, 0);
|
||||||
@ -2556,9 +2556,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
|
|||||||
* both pointers will point to the same smack_known
|
* both pointers will point to the same smack_known
|
||||||
* label.
|
* label.
|
||||||
*/
|
*/
|
||||||
if (op == AUDIT_EQUAL)
|
if (op == Audit_equal)
|
||||||
return (rule == smack);
|
return (rule == smack);
|
||||||
if (op == AUDIT_NOT_EQUAL)
|
if (op == Audit_not_equal)
|
||||||
return (rule != smack);
|
return (rule != smack);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user