Linux-audit Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "George C. Wilson" <ltcgcw@us.ibm.com>
To: linux-audit@redhat.com
Subject: [PATCH] POSIX MQ audit memleak fixes and helper inlines
Date: Thu, 25 May 2006 14:02:35 -0500	[thread overview]
Message-ID: <20060525190235.GA7169@us.ibm.com> (raw)

This is an incremental patch that addresses two issues with the previous patch
to audit POSIX message queue syscalls.  It should apply cleanly to Al Viro's
current lspp.b15 git branch.

There were memory leaks introduced in several audit_posix_mq* functions.  They
are triggered by bad data from userspace.  Fixed.

Inlined aux record helper functions.

Tested with audit enabled, disabled, and audit compiled out of kernel.

Please apply.

 include/linux/audit.h |   41 +++++++++++++++++++++++++++++++++++------
 kernel/auditsc.c      |   36 ++++++++++++++++++++++--------------
 2 files changed, 57 insertions(+), 20 deletions(-)

Signed-off-by: George Wilson <ltcgcw@us.ibm.com>

--

diff --git a/include/linux/audit.h b/include/linux/audit.h
index aa93091..c783275 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -343,6 +343,11 @@ extern int audit_socketcall(int nargs, u
 extern int audit_sockaddr(int len, void *addr);
 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);
+extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_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 int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
+extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
 
 static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
 {
@@ -356,12 +361,36 @@ static inline int audit_ipc_set_perm(uns
 		return __audit_ipc_set_perm(qbytes, uid, gid, mode);
 	return 0;
 }
-
-extern int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_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 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 int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
-extern int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
+static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
+{
+	if (unlikely(current->audit_context))
+		return __audit_mq_open(oflag, mode, u_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)
+{
+	if (unlikely(current->audit_context))
+		return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_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)
+{
+	if (unlikely(current->audit_context))
+		return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
+	return 0;
+}
+static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
+{
+	if (unlikely(current->audit_context))
+		return __audit_mq_notify(mqdes, u_notification);
+	return 0;
+}
+static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
+{
+	if (unlikely(current->audit_context))
+		return __audit_mq_getsetattr(mqdes, mqstat);
+	return 0;
+}
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 52da1eb..f4b09a3 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1298,14 +1298,14 @@ uid_t audit_get_loginuid(struct audit_co
 }
 
 /**
- * audit_mq_open - record audit data for a POSIX MQ open
+ * __audit_mq_open - record audit data for a POSIX MQ open
  * @oflag: open flag
  * @mode: mode bits
  * @u_attr: queue attributes
  *
  * Returns 0 for success or NULL context or < 0 on error.
  */
-int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
+int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
 {
 	struct audit_aux_data_mq_open *ax;
 	struct audit_context *context = current->audit_context;
@@ -1321,8 +1321,10 @@ int audit_mq_open(int oflag, mode_t mode
 		return -ENOMEM;
 
 	if (u_attr != NULL) {
-		if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr)))
+		if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
+			kfree(ax);
 			return -EFAULT;
+		}
 	} else
 		memset(&ax->attr, 0, sizeof(ax->attr));
 
@@ -1336,7 +1338,7 @@ int audit_mq_open(int oflag, mode_t mode
 }
 
 /**
- * audit_mq_timedsend - record audit data for a POSIX MQ timed send
+ * __audit_mq_timedsend - record audit data for a POSIX MQ timed send
  * @mqdes: MQ descriptor
  * @msg_len: Message length
  * @msg_prio: Message priority
@@ -1344,7 +1346,7 @@ int audit_mq_open(int oflag, mode_t mode
  *
  * Returns 0 for success or NULL context or < 0 on error.
  */
-int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
+int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
 			const struct timespec __user *u_abs_timeout)
 {
 	struct audit_aux_data_mq_sendrecv *ax;
@@ -1361,8 +1363,10 @@ int audit_mq_timedsend(mqd_t mqdes, size
 		return -ENOMEM;
 
 	if (u_abs_timeout != NULL) {
-		if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout)))
+		if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
+			kfree(ax);
 			return -EFAULT;
+		}
 	} else
 		memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
 
@@ -1377,7 +1381,7 @@ int audit_mq_timedsend(mqd_t mqdes, size
 }
 
 /**
- * audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
+ * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
  * @mqdes: MQ descriptor
  * @msg_len: Message length
  * @msg_prio: Message priority
@@ -1385,7 +1389,7 @@ int audit_mq_timedsend(mqd_t mqdes, size
  *
  * Returns 0 for success or NULL context or < 0 on error.
  */
-int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len,
+int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len,
 				unsigned int __user *u_msg_prio,
 				const struct timespec __user *u_abs_timeout)
 {
@@ -1409,8 +1413,10 @@ int audit_mq_timedreceive(mqd_t mqdes, s
 		ax->msg_prio = 0;
 
 	if (u_abs_timeout != NULL) {
-		if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout)))
+		if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
+			kfree(ax);
 			return -EFAULT;
+		}
 	} else
 		memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
 
@@ -1424,14 +1430,14 @@ int audit_mq_timedreceive(mqd_t mqdes, s
 }
 
 /**
- * audit_mq_notify - record audit data for a POSIX MQ notify
+ * __audit_mq_notify - record audit data for a POSIX MQ notify
  * @mqdes: MQ descriptor
  * @u_notification: Notification event
  *
  * Returns 0 for success or NULL context or < 0 on error.
  */
 
-int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
+int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
 {
 	struct audit_aux_data_mq_notify *ax;
 	struct audit_context *context = current->audit_context;
@@ -1447,8 +1453,10 @@ int audit_mq_notify(mqd_t mqdes, const s
 		return -ENOMEM;
 
 	if (u_notification != NULL) {
-		if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification)))
+		if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) {
+			kfree(ax);
 			return -EFAULT;
+		}
 	} else
 		memset(&ax->notification, 0, sizeof(ax->notification));
 
@@ -1461,13 +1469,13 @@ int audit_mq_notify(mqd_t mqdes, const s
 }
 
 /**
- * audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
+ * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
  * @mqdes: MQ descriptor
  * @mqstat: MQ flags
  *
  * Returns 0 for success or NULL context or < 0 on error.
  */
-int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
+int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
 {
 	struct audit_aux_data_mq_getsetattr *ax;
 	struct audit_context *context = current->audit_context;
-- 
George Wilson <ltcgcw@us.ibm.com>
IBM Linux Technology Center

                 reply	other threads:[~2006-05-25 19:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060525190235.GA7169@us.ibm.com \
    --to=ltcgcw@us.ibm.com \
    --cc=linux-audit@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox