Skip to content

Commit fe0bdec

Browse files
committed
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()
2 parents 099e657 + 5af75d8 commit fe0bdec

File tree

13 files changed

+579
-766
lines changed

13 files changed

+579
-766
lines changed

fs/pipe.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,19 +1016,14 @@ int do_pipe_flags(int *fd, int flags)
10161016
goto err_fdr;
10171017
fdw = error;
10181018

1019-
error = audit_fd_pair(fdr, fdw);
1020-
if (error < 0)
1021-
goto err_fdw;
1022-
1019+
audit_fd_pair(fdr, fdw);
10231020
fd_install(fdr, fr);
10241021
fd_install(fdw, fw);
10251022
fd[0] = fdr;
10261023
fd[1] = fdw;
10271024

10281025
return 0;
10291026

1030-
err_fdw:
1031-
put_unused_fd(fdw);
10321027
err_fdr:
10331028
put_unused_fd(fdr);
10341029
err_read_pipe:

include/linux/audit.h

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,18 @@
247247
#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
248248
#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
249249

250+
enum {
251+
Audit_equal,
252+
Audit_not_equal,
253+
Audit_bitmask,
254+
Audit_bittest,
255+
Audit_lt,
256+
Audit_gt,
257+
Audit_le,
258+
Audit_ge,
259+
Audit_bad
260+
};
261+
250262
/* Status symbols */
251263
/* Mask values */
252264
#define AUDIT_STATUS_ENABLED 0x0001
@@ -373,6 +385,8 @@ struct audit_krule {
373385
struct audit_watch *watch; /* associated watch */
374386
struct audit_tree *tree; /* associated watched tree */
375387
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
388+
struct list_head list; /* for AUDIT_LIST* purposes only */
389+
u64 prio;
376390
};
377391

378392
struct audit_field {
@@ -443,70 +457,56 @@ extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
443457
#define audit_get_loginuid(t) ((t)->loginuid)
444458
#define audit_get_sessionid(t) ((t)->sessionid)
445459
extern void audit_log_task_context(struct audit_buffer *ab);
446-
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
447-
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
460+
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
461+
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
448462
extern int audit_bprm(struct linux_binprm *bprm);
449-
extern int audit_socketcall(int nargs, unsigned long *args);
463+
extern void audit_socketcall(int nargs, unsigned long *args);
450464
extern int audit_sockaddr(int len, void *addr);
451-
extern int __audit_fd_pair(int fd1, int fd2);
465+
extern void __audit_fd_pair(int fd1, int fd2);
452466
extern int audit_set_macxattr(const char *name);
453-
extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
454-
extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout);
455-
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);
456-
extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
457-
extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
467+
extern void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr);
468+
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
469+
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
470+
extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
458471
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
459472
const struct cred *new,
460473
const struct cred *old);
461-
extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
474+
extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
462475

463-
static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
476+
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
464477
{
465478
if (unlikely(!audit_dummy_context()))
466-
return __audit_ipc_obj(ipcp);
467-
return 0;
468-
}
469-
static inline int audit_fd_pair(int fd1, int fd2)
470-
{
471-
if (unlikely(!audit_dummy_context()))
472-
return __audit_fd_pair(fd1, fd2);
473-
return 0;
479+
__audit_ipc_obj(ipcp);
474480
}
475-
static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
481+
static inline void audit_fd_pair(int fd1, int fd2)
476482
{
477483
if (unlikely(!audit_dummy_context()))
478-
return __audit_ipc_set_perm(qbytes, uid, gid, mode);
479-
return 0;
484+
__audit_fd_pair(fd1, fd2);
480485
}
481-
static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
486+
static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
482487
{
483488
if (unlikely(!audit_dummy_context()))
484-
return __audit_mq_open(oflag, mode, u_attr);
485-
return 0;
489+
__audit_ipc_set_perm(qbytes, uid, gid, mode);
486490
}
487-
static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout)
491+
static inline void audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
488492
{
489493
if (unlikely(!audit_dummy_context()))
490-
return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
491-
return 0;
494+
__audit_mq_open(oflag, mode, attr);
492495
}
493-
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)
496+
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
494497
{
495498
if (unlikely(!audit_dummy_context()))
496-
return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
497-
return 0;
499+
__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
498500
}
499-
static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
501+
static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
500502
{
501503
if (unlikely(!audit_dummy_context()))
502-
return __audit_mq_notify(mqdes, u_notification);
503-
return 0;
504+
__audit_mq_notify(mqdes, notification);
504505
}
505-
static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
506+
static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
506507
{
507508
if (unlikely(!audit_dummy_context()))
508-
return __audit_mq_getsetattr(mqdes, mqstat);
509-
return 0;
509+
__audit_mq_getsetattr(mqdes, mqstat);
510510
}
511511

512512
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,
518518
return 0;
519519
}
520520

521-
static inline int audit_log_capset(pid_t pid, const struct cred *new,
521+
static inline void audit_log_capset(pid_t pid, const struct cred *new,
522522
const struct cred *old)
523523
{
524524
if (unlikely(!audit_dummy_context()))
525-
return __audit_log_capset(pid, new, old);
526-
return 0;
525+
__audit_log_capset(pid, new, old);
527526
}
528527

529528
extern int audit_n_rules;
@@ -546,20 +545,19 @@ extern int audit_signals;
546545
#define audit_get_loginuid(t) (-1)
547546
#define audit_get_sessionid(t) (-1)
548547
#define audit_log_task_context(b) do { ; } while (0)
549-
#define audit_ipc_obj(i) ({ 0; })
550-
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
548+
#define audit_ipc_obj(i) ((void)0)
549+
#define audit_ipc_set_perm(q,u,g,m) ((void)0)
551550
#define audit_bprm(p) ({ 0; })
552-
#define audit_socketcall(n,a) ({ 0; })
553-
#define audit_fd_pair(n,a) ({ 0; })
551+
#define audit_socketcall(n,a) ((void)0)
552+
#define audit_fd_pair(n,a) ((void)0)
554553
#define audit_sockaddr(len, addr) ({ 0; })
555554
#define audit_set_macxattr(n) do { ; } while (0)
556-
#define audit_mq_open(o,m,a) ({ 0; })
557-
#define audit_mq_timedsend(d,l,p,t) ({ 0; })
558-
#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
559-
#define audit_mq_notify(d,n) ({ 0; })
560-
#define audit_mq_getsetattr(d,s) ({ 0; })
555+
#define audit_mq_open(o,m,a) ((void)0)
556+
#define audit_mq_sendrecv(d,l,p,t) ((void)0)
557+
#define audit_mq_notify(d,n) ((void)0)
558+
#define audit_mq_getsetattr(d,s) ((void)0)
561559
#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
562-
#define audit_log_capset(pid, ncr, ocr) ({ 0; })
560+
#define audit_log_capset(pid, ncr, ocr) ((void)0)
563561
#define audit_ptrace(t) ((void)0)
564562
#define audit_n_rules 0
565563
#define audit_signals 0

ipc/mqueue.c

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -524,31 +524,27 @@ static void __do_notify(struct mqueue_inode_info *info)
524524
wake_up(&info->wait_q);
525525
}
526526

527-
static long prepare_timeout(const struct timespec __user *u_arg)
527+
static long prepare_timeout(struct timespec *p)
528528
{
529-
struct timespec ts, nowts;
529+
struct timespec nowts;
530530
long timeout;
531531

532-
if (u_arg) {
533-
if (unlikely(copy_from_user(&ts, u_arg,
534-
sizeof(struct timespec))))
535-
return -EFAULT;
536-
537-
if (unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0
538-
|| ts.tv_nsec >= NSEC_PER_SEC))
532+
if (p) {
533+
if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
534+
|| p->tv_nsec >= NSEC_PER_SEC))
539535
return -EINVAL;
540536
nowts = CURRENT_TIME;
541537
/* first subtract as jiffies can't be too big */
542-
ts.tv_sec -= nowts.tv_sec;
543-
if (ts.tv_nsec < nowts.tv_nsec) {
544-
ts.tv_nsec += NSEC_PER_SEC;
545-
ts.tv_sec--;
538+
p->tv_sec -= nowts.tv_sec;
539+
if (p->tv_nsec < nowts.tv_nsec) {
540+
p->tv_nsec += NSEC_PER_SEC;
541+
p->tv_sec--;
546542
}
547-
ts.tv_nsec -= nowts.tv_nsec;
548-
if (ts.tv_sec < 0)
543+
p->tv_nsec -= nowts.tv_nsec;
544+
if (p->tv_sec < 0)
549545
return 0;
550546

551-
timeout = timespec_to_jiffies(&ts) + 1;
547+
timeout = timespec_to_jiffies(p) + 1;
552548
} else
553549
return MAX_SCHEDULE_TIMEOUT;
554550

@@ -592,22 +588,18 @@ static int mq_attr_ok(struct mq_attr *attr)
592588
* Invoked when creating a new queue via sys_mq_open
593589
*/
594590
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
595-
int oflag, mode_t mode, struct mq_attr __user *u_attr)
591+
int oflag, mode_t mode, struct mq_attr *attr)
596592
{
597593
const struct cred *cred = current_cred();
598-
struct mq_attr attr;
599594
struct file *result;
600595
int ret;
601596

602-
if (u_attr) {
603-
ret = -EFAULT;
604-
if (copy_from_user(&attr, u_attr, sizeof(attr)))
605-
goto out;
597+
if (attr) {
606598
ret = -EINVAL;
607-
if (!mq_attr_ok(&attr))
599+
if (!mq_attr_ok(attr))
608600
goto out;
609601
/* store for use during create */
610-
dentry->d_fsdata = &attr;
602+
dentry->d_fsdata = attr;
611603
}
612604

613605
mode &= ~current->fs->umask;
@@ -664,11 +656,13 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
664656
struct dentry *dentry;
665657
struct file *filp;
666658
char *name;
659+
struct mq_attr attr;
667660
int fd, error;
668661

669-
error = audit_mq_open(oflag, mode, u_attr);
670-
if (error != 0)
671-
return error;
662+
if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
663+
return -EFAULT;
664+
665+
audit_mq_open(oflag, mode, u_attr ? &attr : NULL);
672666

673667
if (IS_ERR(name = getname(u_name)))
674668
return PTR_ERR(name);
@@ -694,7 +688,8 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
694688
filp = do_open(dentry, oflag);
695689
} else {
696690
filp = do_create(mqueue_mnt->mnt_root, dentry,
697-
oflag, mode, u_attr);
691+
oflag, mode,
692+
u_attr ? &attr : NULL);
698693
}
699694
} else {
700695
error = -ENOENT;
@@ -829,17 +824,22 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
829824
struct ext_wait_queue *receiver;
830825
struct msg_msg *msg_ptr;
831826
struct mqueue_inode_info *info;
827+
struct timespec ts, *p = NULL;
832828
long timeout;
833829
int ret;
834830

835-
ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
836-
if (ret != 0)
837-
return ret;
831+
if (u_abs_timeout) {
832+
if (copy_from_user(&ts, u_abs_timeout,
833+
sizeof(struct timespec)))
834+
return -EFAULT;
835+
p = &ts;
836+
}
838837

839838
if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
840839
return -EINVAL;
841840

842-
timeout = prepare_timeout(u_abs_timeout);
841+
audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
842+
timeout = prepare_timeout(p);
843843

844844
ret = -EBADF;
845845
filp = fget(mqdes);
@@ -918,12 +918,17 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
918918
struct inode *inode;
919919
struct mqueue_inode_info *info;
920920
struct ext_wait_queue wait;
921+
struct timespec ts, *p = NULL;
921922

922-
ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
923-
if (ret != 0)
924-
return ret;
923+
if (u_abs_timeout) {
924+
if (copy_from_user(&ts, u_abs_timeout,
925+
sizeof(struct timespec)))
926+
return -EFAULT;
927+
p = &ts;
928+
}
925929

926-
timeout = prepare_timeout(u_abs_timeout);
930+
audit_mq_sendrecv(mqdes, msg_len, 0, p);
931+
timeout = prepare_timeout(p);
927932

928933
ret = -EBADF;
929934
filp = fget(mqdes);
@@ -1003,17 +1008,17 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
10031008
struct mqueue_inode_info *info;
10041009
struct sk_buff *nc;
10051010

1006-
ret = audit_mq_notify(mqdes, u_notification);
1007-
if (ret != 0)
1008-
return ret;
1009-
1010-
nc = NULL;
1011-
sock = NULL;
1012-
if (u_notification != NULL) {
1011+
if (u_notification) {
10131012
if (copy_from_user(&notification, u_notification,
10141013
sizeof(struct sigevent)))
10151014
return -EFAULT;
1015+
}
10161016

1017+
audit_mq_notify(mqdes, u_notification ? &notification : NULL);
1018+
1019+
nc = NULL;
1020+
sock = NULL;
1021+
if (u_notification != NULL) {
10171022
if (unlikely(notification.sigev_notify != SIGEV_NONE &&
10181023
notification.sigev_notify != SIGEV_SIGNAL &&
10191024
notification.sigev_notify != SIGEV_THREAD))
@@ -1150,11 +1155,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
11501155
omqstat = info->attr;
11511156
omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
11521157
if (u_mqstat) {
1153-
ret = audit_mq_getsetattr(mqdes, &mqstat);
1154-
if (ret != 0) {
1155-
spin_unlock(&info->lock);
1156-
goto out_fput;
1157-
}
1158+
audit_mq_getsetattr(mqdes, &mqstat);
11581159
if (mqstat.mq_flags & O_NONBLOCK)
11591160
filp->f_flags |= O_NONBLOCK;
11601161
else

ipc/shm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
747747
goto out;
748748
}
749749

750-
err = audit_ipc_obj(&(shp->shm_perm));
751-
if (err)
752-
goto out_unlock;
750+
audit_ipc_obj(&(shp->shm_perm));
753751

754752
if (!capable(CAP_IPC_LOCK)) {
755753
uid_t euid = current_euid();

0 commit comments

Comments
 (0)