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