From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark Workman Subject: [PATCH 2.6.19-rc6] audit: support for descriptor pairs Date: Fri, 17 Nov 2006 17:42:24 -0500 (EST) Message-ID: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Return-path: Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id kAHMgYRb006818 for ; Fri, 17 Nov 2006 17:42:34 -0500 Received: from smtp-bedford.mitre.org (smtpproxy1.mitre.org [192.160.51.76]) by mx3.redhat.com (8.13.1/8.13.1) with ESMTP id kAHMgPXJ032369 for ; Fri, 17 Nov 2006 17:42:25 -0500 Received: from smtp-bedford.mitre.org (localhost.localdomain [127.0.0.1]) by smtp-bedford.mitre.org (8.12.11.20060308/8.12.11) with SMTP id kAHMgPXC015169 for ; Fri, 17 Nov 2006 17:42:25 -0500 Received: from smtp-bedford.mitre.org (localhost.localdomain [127.0.0.1]) by smtp-bedford.mitre.org (Postfix) with ESMTP id 25F02BF00 for ; Fri, 17 Nov 2006 17:42:25 -0500 (EST) Received: from linus.mitre.org (linus.mitre.org [129.83.10.1]) by smtp-bedford.mitre.org (8.12.11.20060308/8.12.11) with ESMTP id kAHMgOQL015163 for ; Fri, 17 Nov 2006 17:42:24 -0500 Received: from linus.mitre.org (linus.mitre.org [129.83.10.1]) by linus.mitre.org (8.12.11/8.12.10) with ESMTP id kAHMgOs5029180 for ; Fri, 17 Nov 2006 17:42:24 -0500 (EST) List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com To: linux-audit@redhat.com List-Id: linux-audit@redhat.com provide an audit record of the descriptor pair returned by pipe() and socketpair(). Signed-off-by: Jeremy Latt Signed-off-by: Steven Trieber Signed-off-by: Mark Workman --- fs/pipe.c | 7 +++++++ include/linux/audit.h | 9 +++++++++ kernel/auditsc.c | 40 ++++++++++++++++++++++++++++++++++++++++ net/socket.c | 34 ++++++++++++++++++++++++++-------- 4 files changed, 82 insertions(+), 8 deletions(-) --- diff -uprN -X a/Documentation/dontdiff a/fs/pipe.c b/fs/pipe.c --- a/fs/pipe.c 2006-11-17 16:39:33.000000000 -0500 +++ b/fs/pipe.c 2006-11-17 17:34:24.000000000 -0500 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -972,6 +973,10 @@ int do_pipe(int *fd) goto err_fdr; fdw = error; + error = audit_fd_pair(fdr, fdw); + if (error < 0) + goto err_fdw; + fd_install(fdr, fr); fd_install(fdw, fw); fd[0] = fdr; @@ -979,6 +984,8 @@ int do_pipe(int *fd) return 0; + err_fdw: + put_unused_fd(fdw); err_fdr: put_unused_fd(fdr); err_read_pipe: diff -uprN -X a/Documentation/dontdiff a/include/linux/audit.h b/include/linux/audit.h --- a/include/linux/audit.h 2006-11-17 16:39:38.000000000 -0500 +++ b/include/linux/audit.h 2006-11-17 17:34:24.000000000 -0500 @@ -89,6 +89,7 @@ #define AUDIT_MQ_NOTIFY 1314 /* POSIX MQ notify record type */ #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ +#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ @@ -382,6 +383,7 @@ extern int __audit_ipc_set_perm(unsigned extern int audit_bprm(struct linux_binprm *bprm); extern int audit_socketcall(int nargs, unsigned long *args); extern int audit_sockaddr(int len, void *addr); +extern int __audit_fd_pair(int fd1, int fd2); extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); extern int audit_set_macxattr(const char *name); extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); @@ -396,6 +398,12 @@ static inline int audit_ipc_obj(struct k return __audit_ipc_obj(ipcp); return 0; } +static inline int audit_fd_pair(int fd1, int fd2) +{ + if (unlikely(!audit_dummy_context())) + return __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) { if (unlikely(!audit_dummy_context())) @@ -453,6 +461,7 @@ extern int audit_n_rules; #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) #define audit_bprm(p) ({ 0; }) #define audit_socketcall(n,a) ({ 0; }) +#define audit_fd_pair(n,a) ({ 0; }) #define audit_sockaddr(len, addr) ({ 0; }) #define audit_avc_path(dentry, mnt) ({ 0; }) #define audit_set_macxattr(n) do { ; } while (0) diff -uprN -X a/Documentation/dontdiff a/kernel/auditsc.c b/kernel/auditsc.c --- a/kernel/auditsc.c 2006-11-17 16:39:43.000000000 -0500 +++ b/kernel/auditsc.c 2006-11-17 17:34:24.000000000 -0500 @@ -169,6 +169,11 @@ struct audit_aux_data_sockaddr { char a[0]; }; +struct audit_aux_data_fd_pair { + struct audit_aux_data d; + int fd[2]; +}; + struct audit_aux_data_path { struct audit_aux_data d; struct dentry *dentry; @@ -956,6 +961,11 @@ static void audit_log_exit(struct audit_ audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); break; } + case AUDIT_FD_PAIR: { + struct audit_aux_data_fd_pair *axs = (void *)aux; + audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); + break; } + } audit_log_end(ab); } @@ -1808,6 +1818,36 @@ int audit_socketcall(int nargs, unsigned } /** + * __audit_fd_pair - record audit data for pipe and socketpair + * @fd1: the first file descriptor + * @fd2: the second file descriptor + * + * Returns 0 for success or NULL context or < 0 on error. + */ +int __audit_fd_pair(int fd1, int fd2) +{ + struct audit_context *context = current->audit_context; + struct audit_aux_data_fd_pair *ax; + + if (likely(!context)) { + return 0; + } + + ax = kmalloc(sizeof(*ax), GFP_KERNEL); + if (!ax) { + return -ENOMEM; + } + + ax->fd[0] = fd1; + ax->fd[1] = fd2; + + ax->d.type = AUDIT_FD_PAIR; + ax->d.next = context->aux; + context->aux = (void *)ax; + return 0; +} + +/** * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto * @len: data length in user space * @a: data address in kernel space diff -uprN -X a/Documentation/dontdiff a/net/socket.c b/net/socket.c --- a/net/socket.c 2006-11-17 16:39:45.000000000 -0500 +++ b/net/socket.c 2006-11-17 17:34:24.000000000 -0500 @@ -1200,6 +1200,7 @@ asmlinkage long sys_socketpair(int famil { struct socket *sock1, *sock2; int fd1, fd2, err; + struct file *newfile1, *newfile2; /* * Obtain the first socket and check if the underlying protocol @@ -1218,18 +1219,34 @@ asmlinkage long sys_socketpair(int famil if (err < 0) goto out_release_both; - fd1 = fd2 = -1; + fd1 = sock_alloc_fd(&newfile1); + if (likely(fd1 >= 0)) { + err = sock_attach_fd(sock1, newfile1); + + if (unlikely(err < 0)) { + put_filp(newfile1); + put_unused_fd(fd1); + goto out_release_both; + } + } - err = sock_map_fd(sock1); - if (err < 0) - goto out_release_both; - fd1 = err; + fd2 = sock_alloc_fd(&newfile2); + if (likely(fd2 >= 0)) { + err = sock_attach_fd(sock2, newfile2); + + if (unlikely(err < 0)) { + put_filp(newfile2); + put_unused_fd(fd2); + goto out_close_1; + } + } - err = sock_map_fd(sock2); + err = audit_fd_pair(fd1, fd2); if (err < 0) - goto out_close_1; - fd2 = err; + goto out_close_2; + fd_install(fd1, newfile1); + fd_install(fd2, newfile2); /* fd1 and fd2 may be already another descriptors. * Not kernel problem. */ @@ -1240,6 +1257,7 @@ asmlinkage long sys_socketpair(int famil if (!err) return 0; +out_close_2: sys_close(fd2); sys_close(fd1); return err;