Blame SOURCES/audit-2.8.2-fix-reset-lost-return.patch

ad8605
Subject: [PATCH 2/2] lost_reset: return value rather than sequence number when zero
ad8605
Date: Wed, 22 Nov 2017 19:00:57 -0500
ad8605
ad8605
The kernel always returns negative values on error, so zero and anything
ad8605
positive is valid success.  Lost_reset returned a positive value at the
ad8605
time of reset, including zero that got interpreted as success and
ad8605
replaced with the packet sequence number "2".
ad8605
ad8605
Rename audit_send() to __audit_send() and pass the sequence number back
ad8605
via a parameter rather than return value.
ad8605
ad8605
Have a new stub audit_send() call __audit_send() and mimic the previous
ad8605
behaviour of audit_send().
ad8605
ad8605
There are legacy functions that actually use a sequence number:
ad8605
	audit_request_rules_list_data()
ad8605
		delete_all_rules()
ad8605
	audit_request_signal_info()
ad8605
		src/auditd.c:get_reply()
ad8605
A number of others don't appear to need it, but expose it in libaudit:
ad8605
	audit_send_user_message()
ad8605
       		audit_log_user_comm_message()
ad8605
		audit_log_acct_message()
ad8605
		audit_log_user_avc_message()
ad8605
		audit_log_semanage_message()
ad8605
		audit_log_user_command()
ad8605
	audit_request_status()
ad8605
	audit_set_enabled()
ad8605
	audit_set_failure()
ad8605
	audit_set_rate_limit()
ad8605
	audit_set_backlog_limit()
ad8605
	audit_set_backlog_wait_time()
ad8605
	audit_add_rule_data()
ad8605
	audit_delete_rule_data()
ad8605
ad8605
Passes all audit-testsuite tests.
ad8605
ad8605
See: https://github.com/linux-audit/audit-userspace/issues/31
ad8605
ad8605
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
ad8605
---
ad8605
 lib/libaudit.c |  3 ++-
ad8605
 lib/netlink.c  | 28 ++++++++++++++++++++--------
ad8605
 lib/private.h  |  1 +
ad8605
 3 files changed, 23 insertions(+), 9 deletions(-)
ad8605
ad8605
diff --git a/lib/libaudit.c b/lib/libaudit.c
ad8605
index a9ba575..aa8258c 100644
ad8605
--- a/lib/libaudit.c
ad8605
+++ b/lib/libaudit.c
ad8605
@@ -519,6 +519,7 @@ int audit_set_backlog_wait_time(int fd, uint32_t bwt)
ad8605
 int audit_reset_lost(int fd)
ad8605
 {
ad8605
 	int rc;
ad8605
+	int seq;
ad8605
 	struct audit_status s;
ad8605
 
ad8605
 	if ((audit_get_features() & AUDIT_FEATURE_BITMAP_LOST_RESET) == 0)
ad8605
@@ -527,7 +528,7 @@ int audit_reset_lost(int fd)
ad8605
 	memset(&s, 0, sizeof(s));
ad8605
 	s.mask = AUDIT_STATUS_LOST;
ad8605
 	s.lost = 0;
ad8605
-	rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
ad8605
+	rc = __audit_send(fd, AUDIT_SET, &s, sizeof(s), &seq;;
ad8605
 	if (rc < 0)
ad8605
 		audit_msg(audit_priority(errno),
ad8605
 			"Error sending lost reset request (%s)", 
ad8605
diff --git a/lib/netlink.c b/lib/netlink.c
ad8605
index 6e23883..5b2028f 100644
ad8605
--- a/lib/netlink.c
ad8605
+++ b/lib/netlink.c
ad8605
@@ -203,7 +203,7 @@ static int adjust_reply(struct audit_reply *rep, int len)
ad8605
  *                   error:   -errno
ad8605
  *                   short:   0
ad8605
  */
ad8605
-int audit_send(int fd, int type, const void *data, unsigned int size)
ad8605
+int __audit_send(int fd, int type, const void *data, unsigned int size, int *seq)
ad8605
 {
ad8605
 	static int sequence = 0;
ad8605
 	struct audit_message req;
ad8605
@@ -224,6 +224,7 @@ int audit_send(int fd, int type, const void *data, unsigned int size)
ad8605
 
ad8605
 	if (++sequence < 0) 
ad8605
 		sequence = 1;
ad8605
+	*seq = sequence;
ad8605
 
ad8605
 	memset(&req, 0, sizeof(req));
ad8605
 	req.nlh.nlmsg_len = NLMSG_SPACE(size);
ad8605
@@ -241,18 +242,29 @@ int audit_send(int fd, int type, const void *data, unsigned int size)
ad8605
 		retval = sendto(fd, &req, req.nlh.nlmsg_len, 0,
ad8605
 			(struct sockaddr*)&addr, sizeof(addr));
ad8605
 	} while (retval < 0 && errno == EINTR);
ad8605
-	if (retval == (int)req.nlh.nlmsg_len) {
ad8605
-		if ((retval = check_ack(fd)) == 0)
ad8605
-			return sequence;
ad8605
-		else
ad8605
-			return retval; 
ad8605
-	}
ad8605
-	if (retval < 0) 
ad8605
+	if (retval == (int)req.nlh.nlmsg_len)
ad8605
+		return check_ack(fd);
ad8605
+	if (retval < 0) {
ad8605
 		return -errno;
ad8605
+	} else if (retval > 0) {
ad8605
+		errno = EINVAL;
ad8605
+		return -errno;
ad8605
+	}
ad8605
 
ad8605
 	return 0;
ad8605
 }
ad8605
 
ad8605
+int audit_send(int fd, int type, const void *data, unsigned int size)
ad8605
+{
ad8605
+	int rc;
ad8605
+	int seq;
ad8605
+
ad8605
+	rc = __audit_send(fd, type, data, size, &seq;;
ad8605
+	if (rc == 0)
ad8605
+		rc = seq;
ad8605
+	return rc;
ad8605
+}
ad8605
+
ad8605
 /*
ad8605
  * This function will take a peek into the next packet and see if there's
ad8605
  * an error. If so, the error is returned and its non-zero. Otherwise a 
ad8605
diff --git a/lib/private.h b/lib/private.h
ad8605
index dbe0f74..560740f 100644
ad8605
--- a/lib/private.h
ad8605
+++ b/lib/private.h
ad8605
@@ -121,6 +121,7 @@ void audit_msg(int priority, const char *fmt, ...)
ad8605
 #endif
ad8605
 
ad8605
 extern int audit_send(int fd, int type, const void *data, unsigned int size);
ad8605
+extern int __audit_send(int fd, int type, const void *data, unsigned int size, int *seq);
ad8605
 
ad8605
 AUDIT_HIDDEN_START
ad8605
 
ad8605
-- 
ad8605
1.8.3.1
ad8605
ad8605