From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark Workman Subject: [PATCH 2.6.19-rc4] audit: support for descriptor pairs (fwd) Date: Tue, 7 Nov 2006 08:18:42 -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 kA7DIvdA002488 for ; Tue, 7 Nov 2006 08:18:57 -0500 Received: from smtp-mclean.mitre.org (smtpproxy2.mitre.org [192.80.55.71]) by mx3.redhat.com (8.13.1/8.13.1) with ESMTP id kA7DIm5w011843 for ; Tue, 7 Nov 2006 08:18:49 -0500 Received: from smtp-mclean.mitre.org (localhost.localdomain [127.0.0.1]) by smtp-mclean.mitre.org (8.12.11.20060308/8.12.11) with SMTP id kA7DIhbv006586 for ; Tue, 7 Nov 2006 08:18:43 -0500 Received: from smtp-mclean.mitre.org (localhost.localdomain [127.0.0.1]) by smtp-mclean.mitre.org (Postfix) with ESMTP id 1851F1BDA5 for ; Tue, 7 Nov 2006 08:18:43 -0500 (EST) Received: from linus.mitre.org (rcf-smtp.mitre.org [129.83.10.1]) by smtp-mclean.mitre.org (8.12.11.20060308/8.12.11) with ESMTP id kA7DIg2j006577 for ; Tue, 7 Nov 2006 08:18:42 -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 kA7DIgeb020918 for ; Tue, 7 Nov 2006 08:18:42 -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 ---------- Forwarded message ---------- Date: Fri, 3 Nov 2006 14:22:39 -0500 (EST) From: Mark Workman To: sgrubb@redhat.com Cc: linux-kernel@vger.kernel.org Subject: [PATCH 2.6.19-rc4] audit: support for descriptor pairs 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 | 55 +++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 99 insertions(+), 12 deletions(-) --- diff -uprN -X a/Documentation/dontdiff a/fs/pipe.c b/fs/pipe.c --- a/fs/pipe.c 2006-10-31 16:03:48.000000000 -0500 +++ b/fs/pipe.c 2006-10-31 16:10:50.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-10-31 16:03:48.000000000 -0500 +++ b/include/linux/audit.h 2006-10-31 16:10:50.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-10-31 16:03:48.000000000 -0500 +++ b/kernel/auditsc.c 2006-10-31 16:10:50.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-10-31 16:03:49.000000000 -0500 +++ b/net/socket.c 2006-11-03 14:19:46.000000000 -0500 @@ -393,6 +393,47 @@ int sock_map_fd(struct socket *sock) return fd; } +int sock_map_fd_pair(struct socket *sock1, struct socket *sock2, int *fd1, int *fd2) +{ + int err; + struct file *newfile1; + struct file *newfile2; + + *fd1 = err = sock_alloc_fd(&newfile1); + if (unlikely(*fd1 < 0)) + return err; + + err = sock_attach_fd(sock1, newfile1); + if (unlikely(err < 0)) + goto err_f1; + + *fd2 = err = sock_alloc_fd(&newfile2); + if (unlikely(*fd2 < 0)) + goto err_f1; + + err = sock_attach_fd(sock2, newfile2); + if (unlikely(err < 0)) + goto err_f2; + + err = audit_fd_pair(*fd1, *fd2); + if (err < 0) + goto err_f2; + + fd_install(*fd1, newfile1); + fd_install(*fd2, newfile2); + + return 0; + +err_f2: + fput(newfile2); + put_unused_fd(*fd2); + +err_f1: + fput(newfile1); + put_unused_fd(*fd1); + return (err); +} + static struct socket *sock_from_file(struct file *file, int *err) { struct inode *inode; @@ -1220,15 +1261,9 @@ asmlinkage long sys_socketpair(int famil fd1 = fd2 = -1; - err = sock_map_fd(sock1); + err = sock_map_fd_pair(sock1, sock2, &fd1, &fd2); if (err < 0) goto out_release_both; - fd1 = err; - - err = sock_map_fd(sock2); - if (err < 0) - goto out_close_1; - fd2 = err; /* fd1 and fd2 may be already another descriptors. * Not kernel problem. @@ -1244,11 +1279,6 @@ asmlinkage long sys_socketpair(int famil sys_close(fd1); return err; -out_close_1: - sock_release(sock2); - sys_close(fd1); - return err; - out_release_both: sock_release(sock2); out_release_1: @@ -2259,6 +2289,7 @@ EXPORT_SYMBOL(sock_create); EXPORT_SYMBOL(sock_create_kern); EXPORT_SYMBOL(sock_create_lite); EXPORT_SYMBOL(sock_map_fd); +EXPORT_SYMBOL(sock_map_fd_pair); EXPORT_SYMBOL(sock_recvmsg); EXPORT_SYMBOL(sock_register); EXPORT_SYMBOL(sock_release);