user message limits
by LC Bruzenak
I know I can go look at the code, however I figured I'd ask here first
about the limits on the user message in both audit_log_user_message and
ausearch.
With audit_log_user_message the maximum length allowed appears to be
around MAX_AUDIT_MESSAGE_LENGTH-100. I think it may depend on the
executable name length (and other stuff auto-pushed into the string)
which is why I say "around".
Even when I get a successful return value (from audit_log_user_message),
I don't get my string back out in "ausearch" unless it is WAY smaller -
~1K or less I think.
Any ideas/thoughts?
This is the latest (1.7.11-2) audit package.
Thx,
LCB.
--
LC (Lenny) Bruzenak
lenny(a)magitekltd.com
11 years, 3 months
AUDIT_SIGNAL_INFO
by Matthew Booth
Under what circumstances will the RHEL 4 kernel generate a message of
type AUDIT_SIGNAL_INFO? My understanding is that it should be sent when
a process sends a signal to the audit daemon, however I have not
observed that. Any ideas?
Thanks,
Matt
--
Matthew Booth, RHCA, RHCSS
Red Hat, Global Professional Services
M: +44 (0)7977 267231
GPG ID: D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
12 years, 6 months
Near Term Audit Road Map
by Steve Grubb
Hi,
With the proposals sent to the list, I wanted to talk about how this might
play out code-wise. With regard to the current code base, I am working on a
1.8 release. This would represent finishing the remote logging app and
nothing more. The 1.8 series would become just an update series just like the
1.0.x series did.
In parallel with finishing remote logging, I would release a 2.0 version.
Patches applied to 1.8 would also be applied to 2.0. A 2.1 release would
signify the completion of remote logging that branch. I would recommend this
branch for all distributions pulling new code in.
The 2.0 branch will also have a couple more changes. I want to split up the
audit source code a little bit. I want to drop the system-config-audit code
and let it become standalone package updated and distributed separately.
I also want to drop all audispd-plugins in the 2.0 branch and have them
released separately. They cause unnecessary build dependencies for the audit
package.
During the work for a 2.2 release, I would also like to pull the audispd
program inside auditd. In the past, I tried to keep auditd lean and single
purpose, but with adding remote logging and kerberos support, we already have
something that is hard to analyze. So, to improve performance and decrease
system load, the audit daemon will also do event dispatching.
Would this proposal impact anyone in a Bad Way?
Thanks,
-Steve
12 years, 6 months
[PATCH] Add auditd listener and remote audit protocol
by DJ Delorie
Second in a series, a bit bigger than the first one.
(http://www.redhat.com/archives/linux-audit/2008-August/msg00070.html)
The goal of this patch is to add the server side of the remote logging
feature. To this end, a new auditd-listener.c is added which listens
on a TCP port for connections from other systems' audisp-remote
plugins. A new (private) protocol is added which prepends each
message with a header, giving length, status, version, and sequence
information. Each message begets a reply from the server, so we can
pass along status like "disk full" or "ok". Currently, these call a
set of stub functions, as the details of performing appropriate
actions from the plugin are yet to be decided.
The remote plugin has a new option "format" for "ascii" or "managed"
to choose between the old protocol (ascii strings) and the new one
(the header with ACK, default).
The listener will accept either format. It has new options for the
listen port, accept queue size, and acceptable client-side ports.
Comments?
DJ
Proposed ChangeLog entry:
- Add TCP listener and managed remote protocol features.
diff -N -U 3 -x .svn -r pristine/audisp/plugins/remote/audisp-remote.c trunk/audisp/plugins/remote/audisp-remote.c
--- pristine/audisp/plugins/remote/audisp-remote.c 2008-08-04 12:47:28.000000000 -0400
+++ trunk/audisp/plugins/remote/audisp-remote.c 2008-08-14 14:10:48.000000000 -0400
@@ -30,7 +30,11 @@
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
#include "libaudit.h"
+#include "private.h"
#include "remote-config.h"
#define CONFIG_FILE "/etc/audisp/audisp-remote.conf"
@@ -68,6 +72,56 @@
hup = 0;
}
+/*
+ * Handlers for various events coming back from the remote server.
+ * Return -1 if the remote dispatcher should exit.
+ */
+
+/* Loss of sync - got an invalid response. */
+static int sync_error_handler (const char *why)
+{
+ /* "why" has human-readable details on why we've lost (or will
+ be losing) sync. */
+ syslog (LOG_ERR, "lost/losing sync, %s", why);
+ return -1;
+}
+
+static int remote_disk_low_handler (const char *message)
+{
+ syslog (LOG_WARNING, "remote disk low, %s", message);
+ return 0;
+}
+
+static int remote_disk_full_handler (const char *message)
+{
+ syslog (LOG_ERR, "remote disk full, %s", message);
+ return -1;
+}
+
+static int remote_disk_error_handler (const char *message)
+{
+ syslog (LOG_ERR, "remote disk error, %s", message);
+ return -1;
+}
+
+static int remote_server_ending_handler (const char *message)
+{
+ syslog (LOG_INFO, "remote server ending, %s", message);
+ return -1;
+}
+
+static int generic_remote_error_handler (const char *message)
+{
+ stop = 1;
+ syslog(LOG_INFO, "audisp-remote: remote error: %s", message);
+ return -1;
+}
+static int generic_remote_warning_handler (const char *message)
+{
+ syslog(LOG_INFO, "audisp-remote: remote warning: %s", message);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
@@ -122,6 +176,7 @@
struct addrinfo *ai;
struct addrinfo hints;
char remote[BUF_SIZE];
+ int one=1;
memset(&hints, '\0', sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG|AI_NUMERICSERV;
@@ -140,12 +195,35 @@
freeaddrinfo(ai);
return -1;
}
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
+
+ if (config.local_port != 0) {
+ struct sockaddr_in address;
+
+ memset (&address, 0, sizeof(address));
+ address.sin_family = htons(AF_INET);
+ address.sin_port = htons(config.local_port);
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if ( bind ( sock, (struct sockaddr *)&address, sizeof(address)) ) {
+ syslog(LOG_ERR, "Cannot bind local socket to port %d - exiting",
+ config.local_port);
+ close(sock);
+ return -1;
+ }
+
+ }
if (connect(sock, ai->ai_addr, ai->ai_addrlen)) {
syslog(LOG_ERR, "Error connecting to %s: %s - exiting",
config.remote_server, strerror(errno));
freeaddrinfo(ai);
return -1;
}
+
+ setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof (int));
+ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof (int));
+
freeaddrinfo(ai);
return 0;
}
@@ -166,16 +244,143 @@
return rc;
}
-static int relay_sock(const char *s, size_t len)
+static int ar_write (int sock, const void *buf, int len)
{
int rc;
-
do {
- rc = write(sock, s, len);
+ rc = write(sock, buf, len);
} while (rc < 0 && errno == EINTR);
- if (rc > 0)
- return 0;
- return -1;
+ return rc;
+}
+
+static int ar_read (int sock, void *buf, int len)
+{
+ unsigned char *obuf = buf;
+ int rc = 0, r;
+ while (len > 0) {
+ do {
+ r = read(sock, buf, len);
+ } while (r < 0 && errno == EINTR);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+ rc += r;
+ buf = (void *)((char *)buf + r);
+ len -= r;
+ }
+ return rc;
+}
+
+static int relay_sock_ascii(const char *s, size_t len)
+{
+ int rc;
+
+ rc = ar_write(sock, s, len);
+ if (rc <= 0) {
+ stop = 1;
+ syslog(LOG_ERR, "connection to %s closed unexpectedly - exiting",
+ config.remote_server);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int relay_sock_managed(const char *s, size_t len)
+{
+ static int sequence_id = 1;
+ int rc;
+ unsigned char header[AUDIT_RMW_HEADER_SIZE];
+ int hver, mver;
+ uint32_t magic, type, rlen, seq;
+ char msg[MAX_AUDIT_MESSAGE_LENGTH+1];
+
+ sequence_id ++;
+ AUDIT_RMW_PACK_HEADER (header, 0, 0, len, sequence_id);
+ rc = ar_write(sock, header, AUDIT_RMW_HEADER_SIZE);
+ if (rc <= 0) {
+ stop = 1;
+ syslog(LOG_ERR, "connection to %s closed unexpectedly - exiting",
+ config.remote_server);
+ return -1;
+ }
+
+ rc = ar_write(sock, s, len);
+ if (rc <= 0) {
+ stop = 1;
+ syslog(LOG_ERR, "connection to %s closed unexpectedly - exiting",
+ config.remote_server);
+ return -1;
+ }
+
+ rc = ar_read (sock, header, AUDIT_RMW_HEADER_SIZE);
+ if (rc < 16) {
+ stop = 1;
+ syslog(LOG_ERR, "connection to %s closed unexpectedly - exiting",
+ config.remote_server);
+ return -1;
+ }
+
+
+ if (! AUDIT_RMW_IS_MAGIC (header, AUDIT_RMW_HEADER_SIZE))
+ /* FIXME: the right thing to do here is close the socket and start a new one. */
+ return sync_error_handler ("bad magic number");
+
+ AUDIT_RMW_UNPACK_HEADER (header, hver, mver, type, rlen, seq);
+
+ if (rlen > MAX_AUDIT_MESSAGE_LENGTH)
+ return sync_error_handler ("message too long");
+
+ if (rlen > 0
+ && ar_read (sock, msg, rlen) < rlen)
+ return sync_error_handler ("ran out of data reading reply");
+ msg[rlen] = 0;
+
+ if (seq != sequence_id)
+ /* FIXME: should we read another header and
+ see if it matches? If so, we need to deal
+ with timeouts. */
+ return sync_error_handler ("mismatched response");
+
+ /* Specific errors we know how to deal with. */
+
+ if (type == AUDIT_RMW_TYPE_ENDING)
+ return remote_server_ending_handler (msg);
+ if (type == AUDIT_RMW_TYPE_DISKLOW)
+ return remote_disk_low_handler (msg);
+ if (type == AUDIT_RMW_TYPE_DISKFULL)
+ return remote_disk_full_handler (msg);
+ if (type == AUDIT_RMW_TYPE_DISKERROR)
+ return remote_disk_error_handler (msg);
+
+ /* Generic errors. */
+ if (type & AUDIT_RMW_TYPE_FATALMASK)
+ return generic_remote_error_handler (msg);
+ if (type & AUDIT_RMW_TYPE_WARNMASK)
+ return generic_remote_warning_handler (msg);
+
+ return 0;
+}
+
+static int relay_sock(const char *s, size_t len)
+{
+ int rc;
+
+ switch (config.format)
+ {
+ case F_MANAGED:
+ rc = relay_sock_managed (s, len);
+ break;
+ case F_ASCII:
+ rc = relay_sock_ascii (s, len);
+ break;
+ default:
+ rc = -1;
+ break;
+ }
+
+ return rc;
}
static int relay_event(const char *s, size_t len)
diff -N -U 3 -x .svn -r pristine/audisp/plugins/remote/audisp-remote.conf trunk/audisp/plugins/remote/audisp-remote.conf
--- pristine/audisp/plugins/remote/audisp-remote.conf 2008-08-04 12:47:28.000000000 -0400
+++ trunk/audisp/plugins/remote/audisp-remote.conf 2008-08-14 15:11:23.000000000 -0400
@@ -5,8 +5,9 @@
remote_server =
port = 60
+#local_port =
transport = tcp
mode = immediate
queue_depth = 20
fail_action = SYSLOG
-
+format = managed
diff -N -U 3 -x .svn -r pristine/audisp/plugins/remote/audisp-remote.conf.5 trunk/audisp/plugins/remote/audisp-remote.conf.5
--- pristine/audisp/plugins/remote/audisp-remote.conf.5 2008-08-04 12:47:28.000000000 -0400
+++ trunk/audisp/plugins/remote/audisp-remote.conf.5 2008-08-14 15:36:53.000000000 -0400
@@ -11,6 +11,13 @@
.I port
This option is an unsigned integer that indicates what port to connect to on the remote machine.
.TP
+.I local_port
+This option is an unsigned integer that indicates what local port to
+connect from on the local machine. If unspecified (the default) or
+set to the word
+.I any
+then any available unpriviledged port is used.
+.TP
.I transport
This parameter tells the remote logging app how to send events to the remote system. Valid values are
.IR tcp ", and " ssl ".
@@ -55,7 +62,22 @@
option will cause the remote logging app to put the computer system in single user mode.
.I halt
option will cause the remote logging app to shutdown the computer system.
+.TP
+.I format
+This parameter tells the remote logging app what data format will be
+used for the messages sent over the network. The default is
+.I managed
+which adds some overhead to ensure each message is properly handled on
+the remote end, and to receive status messages from the remote server.
+If
+.I ascii
+is given instead, each message is a simple ASCII text line with no
+overhead at all.
+.SH "NOTES"
+Specifying a local port may make it difficult to restart the audit
+subsystem due to the previous connection being in a TIME_WAIT state,
+if you're reconnecting to and from the same hosts and ports as before.
.SH "SEE ALSO"
.BR audispd (8),
.BR audisp-remote(8).
diff -N -U 3 -x .svn -r pristine/audisp/plugins/remote/remote-config.c trunk/audisp/plugins/remote/remote-config.c
--- pristine/audisp/plugins/remote/remote-config.c 2008-08-04 12:47:28.000000000 -0400
+++ trunk/audisp/plugins/remote/remote-config.c 2008-08-13 22:19:31.000000000 -0400
@@ -62,6 +62,8 @@
remote_conf_t *config);
static int port_parser(struct nv_pair *nv, int line,
remote_conf_t *config);
+static int local_port_parser(struct nv_pair *nv, int line,
+ remote_conf_t *config);
static int transport_parser(struct nv_pair *nv, int line,
remote_conf_t *config);
static int mode_parser(struct nv_pair *nv, int line,
@@ -70,16 +72,20 @@
remote_conf_t *config);
static int fail_action_parser(struct nv_pair *nv, int line,
remote_conf_t *config);
+static int format_parser(struct nv_pair *nv, int line,
+ remote_conf_t *config);
static int sanity_check(remote_conf_t *config, const char *file);
static const struct kw_pair keywords[] =
{
{"remote_server", server_parser, 0 },
{"port", port_parser, 0 },
+ {"local_port", local_port_parser, 0 },
{"transport", transport_parser, 0 },
{"mode", mode_parser, 0 },
{"queue_depth", depth_parser, 0 },
{"fail_action", fail_action_parser, 0 },
+ {"format", format_parser, 0 },
{ NULL, NULL }
};
@@ -107,6 +113,13 @@
{ NULL, 0 }
};
+static const struct nv_list format_words[] =
+{
+ {"ascii", F_ASCII },
+ {"managed", F_MANAGED },
+ { NULL, 0 }
+};
+
/*
* Set everything to its default value
*/
@@ -114,11 +127,13 @@
{
config->remote_server = NULL;
config->port = 60;
+ config->local_port = 0;
config->port = T_TCP;
config->mode = M_IMMEDIATE;
config->queue_depth = 20;
config->fail_action = F_SYSLOG;
config->fail_exe = NULL;
+ config->format = F_MANAGED;
}
int load_config(remote_conf_t *config, const char *file)
@@ -392,6 +407,46 @@
return 0;
}
+static int local_port_parser(struct nv_pair *nv, int line, remote_conf_t *config)
+{
+ const char *ptr = nv->value;
+ int i;
+
+ if (strcasecmp (ptr, "any") == 0) {
+ config->local_port = 0;
+ return 0;
+ }
+
+ /* check that all chars are numbers */
+ for (i=0; ptr[i]; i++) {
+ if (!isdigit(ptr[i])) {
+ syslog(LOG_ERR,
+ "Value %s should only be numbers - line %d",
+ nv->value, line);
+ return 1;
+ }
+ }
+
+ /* convert to unsigned int */
+ errno = 0;
+ i = strtoul(nv->value, NULL, 10);
+ if (errno) {
+ syslog(LOG_ERR,
+ "Error converting string to a number (%s) - line %d",
+ strerror(errno), line);
+ return 1;
+ }
+ /* Check its range */
+ if (i > INT_MAX) {
+ syslog(LOG_ERR,
+ "Error - converted number (%s) is too large - line %d",
+ nv->value, line);
+ return 1;
+ }
+ config->local_port = (unsigned int)i;
+ return 0;
+}
+
static int transport_parser(struct nv_pair *nv, int line, remote_conf_t *config)
{
int i;
@@ -477,6 +532,20 @@
return 1;
}
+static int format_parser(struct nv_pair *nv, int line,
+ remote_conf_t *config)
+{
+ int i;
+ for (i=0; format_words[i].name != NULL; i++) {
+ if (strcasecmp(nv->value, format_words[i].name) == 0) {
+ config->format = format_words[i].option;
+ return 0;
+ }
+ }
+ syslog(LOG_ERR, "Option %s not found - line %d", nv->value, line);
+ return 1;
+}
+
/*
* This function is where we do the integrated check of the audispd config
* options. At this point, all fields have been read. Returns 0 if no
diff -N -U 3 -x .svn -r pristine/audisp/plugins/remote/remote-config.h trunk/audisp/plugins/remote/remote-config.h
--- pristine/audisp/plugins/remote/remote-config.h 2008-08-04 12:47:28.000000000 -0400
+++ trunk/audisp/plugins/remote/remote-config.h 2008-08-13 22:17:19.000000000 -0400
@@ -27,16 +27,19 @@
typedef enum { M_IMMEDIATE, M_STORE_AND_FORWARD } mode_t;
typedef enum { T_TCP, T_SSL, T_GSSAPI, T_LABELED } transport_t;
typedef enum { F_IGNORE, F_SYSLOG, F_EXEC, F_SUSPEND, F_SINGLE, F_HALT } fail_t;
+typedef enum { F_ASCII, F_MANAGED } format_t;
typedef struct remote_conf
{
const char *remote_server;
unsigned int port;
+ unsigned int local_port;
transport_t transport;
mode_t mode;
unsigned int queue_depth;
fail_t fail_action;
const char *fail_exe;
+ format_t format;
} remote_conf_t;
void clear_config(remote_conf_t *config);
diff -N -U 3 -x .svn -r pristine/docs/auditd.conf.5 trunk/docs/auditd.conf.5
--- pristine/docs/auditd.conf.5 2008-08-04 12:47:31.000000000 -0400
+++ trunk/docs/auditd.conf.5 2008-08-14 15:35:29.000000000 -0400
@@ -212,6 +212,26 @@
option will cause the audit daemon to put the computer system in single user mode.
.I halt
option will cause the audit daemon to shutdown the computer system.
+.TP
+.I tcp_listen_port
+This is a numeric value in the range 1..65535 which, if specified,
+causes auditd to listen on the corresponding TCP port for audit
+records from remote systems.
+.TP
+.I tcp_listen_queue
+This is a numeric value which indicates how many pending (requested
+but unaccepted) connections are allowed. The default is 5. Setting
+this too small may cause connections to be rejected if too many hosts
+start up at exactly the same time, such as after a power failure.
+.TP
+.I tcp_client_ports
+This parameter may be a single numeric value or two values separated
+by a dash (no spaces allowed). It indicates which client ports are
+allowed for incoming connections. If not specified, any port is
+allowed. Allowed values are 1..65535. For example, to require the
+client use a priviledged port, specify
+.I 1-1023
+for this parameter.
.SH NOTES
In a CAPP environment, the audit trail is considered so important that access to system resources must be denied if an audit trail cannot be created. In this environment, it would be suggested that /var/log/audit be on its own partition. This is to ensure that space detection is accurate and that no other process comes along and consumes part of it.
@@ -227,6 +247,11 @@
The disk_full_action is triggered when no more room exists on the partition. All access should be terminated since no more audit capability exists. This can be set to either single or halt.
.PP
The disk_error_action should be set to syslog, single, or halt depending on your local policies regarding handling of hardware malfunctions.
+.PP
+Specifying a single allowed client port may make it difficult for the
+client to restart their audit subsystem, as it will be unable to
+recreate a connection with the same host addresses and ports until the
+connection closure TIME_WAIT state times out.
.SH FILES
.TP
diff -N -U 3 -x .svn -r pristine/init.d/auditd.conf trunk/init.d/auditd.conf
--- pristine/init.d/auditd.conf 2008-08-04 12:47:28.000000000 -0400
+++ trunk/init.d/auditd.conf 2008-08-14 15:22:08.000000000 -0400
@@ -22,4 +22,6 @@
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SUSPEND
-
+#tcp_listen_port =
+#tcp_listen_queue = 5
+#tcp_client_ports = 1024-65535
diff -N -U 3 -x .svn -r pristine/lib/libaudit.h trunk/lib/libaudit.h
--- pristine/lib/libaudit.h 2008-08-04 12:47:34.000000000 -0400
+++ trunk/lib/libaudit.h 2008-08-14 10:58:46.000000000 -0400
@@ -413,10 +413,6 @@
};
};
-struct auditd_reply_list {
- struct audit_reply reply;
- struct auditd_reply_list *next;
-};
//
// End of ABI control
//////////////////////////////////////////////////////
diff -N -U 3 -x .svn -r pristine/lib/private.h trunk/lib/private.h
--- pristine/lib/private.h 2008-08-04 12:47:34.000000000 -0400
+++ trunk/lib/private.h 2008-08-14 10:58:46.000000000 -0400
@@ -55,6 +55,83 @@
;
#endif
+/* This structure is for protocol reference only. All fields are
+ packed and in network order (LSB first). */
+struct auditd_remote_message_wrapper {
+ /* The magic number shall never have LF (0x0a) as one of its bytes. */
+ uint32_t magic;
+ /* Bumped when the layout of this structure changes. */
+ uint8_t header_version;
+ /* The minimum support needed to understand this message type.
+ * Normally zero. */
+ uint8_t message_version;
+ /* Upper 8 bits are generic type, see below. */
+ uint32_t type;
+ /* Number of bytes that follow this header Must be 0..MAX_AUDIT_MESSAGE_LENGTH. */
+ uint16_t length;
+ /* Copied from message to its reply. */
+ uint32_t sequence_id;
+ /* The message follows for LENGTH bytes. */
+};
+
+#define AUDIT_RMW_HEADER_SIZE 16
+/* The magic number shall never have LF (0x0a) as one of its bytes. */
+#define AUDIT_RMW_MAGIC 0xff0000feUL
+
+#define AUDIT_RMW_HEADER_VERSION 0
+
+/* If set, this is a reply. */
+#define AUDIT_RMW_TYPE_REPLYMASK 0x40000000
+/* If set, this reply indicates a fatal error of some sort. */
+#define AUDIT_RMW_TYPE_FATALMASK 0x20000000
+/* If set, this reply indicates success but with some warnings. */
+#define AUDIT_RMW_TYPE_WARNMASK 0x10000000
+/* This part of the message type is the details for the above. */
+#define AUDIT_RMW_TYPE_DETAILMASK 0x0fffffff
+
+/* Version 0 messages. */
+#define AUDIT_RMW_TYPE_MESSAGE 0x00000000
+#define AUDIT_RMW_TYPE_ACK 0x40000000
+#define AUDIT_RMW_TYPE_ENDING 0x40000001
+#define AUDIT_RMW_TYPE_DISKLOW 0x50000001
+#define AUDIT_RMW_TYPE_DISKFULL 0x60000001
+#define AUDIT_RMW_TYPE_DISKERROR 0x60000002
+
+/* These next four should not be called directly. */
+#define _AUDIT_RMW_PUTN32(header,i,v) \
+ header[i] = v & 0xff; \
+ header[i+1] = (v>>8) & 0xff; \
+ header[i+2] = (v>>16) & 0xff; \
+ header[i+3] = (v>>24) & 0xff;
+#define _AUDIT_RMW_PUTN16(header,i,v) \
+ header[i] = v & 0xff; \
+ header[i+1] = (v>>8) & 0xff;
+#define _AUDIT_RMW_GETN32(header,i) \
+ (header[i] | (header[i+1]<<8) | (header[i+2]<<16) | (header[i+3]<<24))
+#define _AUDIT_RMW_GETN16(header,i) \
+ (header[i] | (header[i+1]<<8))
+
+/* For these, HEADER must by of type "unsigned char *" or "unsigned
+ char []" */
+
+#define AUDIT_RMW_PACK_HEADER(header,mver,type,len,seq) \
+ _AUDIT_RMW_PUTN32 (header,0, AUDIT_RMW_MAGIC); \
+ header[4] = AUDIT_RMW_HEADER_VERSION; \
+ header[5] = mver; \
+ _AUDIT_RMW_PUTN32 (header,6, type); \
+ _AUDIT_RMW_PUTN16 (header,10, len); \
+ _AUDIT_RMW_PUTN32 (header,12, seq);
+
+#define AUDIT_RMW_IS_MAGIC(header,length) \
+ (length >= 4 && _AUDIT_RMW_GETN32 (header,0) == AUDIT_RMW_MAGIC)
+
+#define AUDIT_RMW_UNPACK_HEADER(header,hver,mver,type,len,seq) \
+ hver = header[4]; \
+ mver = header[5]; \
+ type = _AUDIT_RMW_GETN32 (header,6); \
+ len = _AUDIT_RMW_GETN16 (header,10); \
+ seq = _AUDIT_RMW_GETN32 (header,12);
+
/* General */
extern int audit_send(int fd, int type, const void *data, unsigned int size)
hidden;
diff -N -U 3 -x .svn -r pristine/src/Makefile.am trunk/src/Makefile.am
--- pristine/src/Makefile.am 2008-08-07 21:18:16.000000000 -0400
+++ trunk/src/Makefile.am 2008-08-08 16:41:07.000000000 -0400
@@ -27,9 +27,9 @@
LIBS = -Lmt -lauditmt -Llibev -lev -lrt -lm
LDADD = -lpthread
AM_CFLAGS = -D_REENTRANT -D_GNU_SOURCE
-noinst_HEADERS = auditd-config.h auditd-event.h ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h ausearch-avc.h ausearch-time.h
+noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h ausearch-avc.h ausearch-time.h
-auditd_SOURCES = auditd.c auditd-event.c auditd-config.c auditd-reconfig.c auditd-sendmail.c auditd-dispatch.c
+auditd_SOURCES = auditd.c auditd-event.c auditd-config.c auditd-reconfig.c auditd-sendmail.c auditd-dispatch.c auditd-listen.c
auditd_CFLAGS = -fPIE -DPIE -g -D_REENTRANT -D_GNU_SOURCE
auditd_LDFLAGS = -pie -Wl,-z,relro
auditd_DEPENDENCIES = mt/libauditmt.a libev/libev.a
diff -N -U 3 -x .svn -r pristine/src/auditd-config.c trunk/src/auditd-config.c
--- pristine/src/auditd-config.c 2008-08-07 17:32:20.000000000 -0400
+++ trunk/src/auditd-config.c 2008-08-08 15:56:13.000000000 -0400
@@ -39,6 +39,8 @@
#include "libaudit.h"
#include "private.h"
+#define TCP_PORT_MAX 65535
+
/* Local prototypes */
struct nv_pair
{
@@ -103,6 +105,12 @@
struct daemon_conf *config);
static int priority_boost_parser(struct nv_pair *nv, int line,
struct daemon_conf *config);
+static int tcp_listen_port_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config);
+static int tcp_listen_queue_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config);
+static int tcp_client_ports_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config);
static int sanity_check(struct daemon_conf *config);
static const struct kw_pair keywords[] =
@@ -127,6 +135,9 @@
{"disk_full_action", disk_full_action_parser, 1 },
{"disk_error_action", disk_error_action_parser, 1 },
{"priority_boost", priority_boost_parser, 0 },
+ {"tcp_listen_port", tcp_listen_port_parser, 0 },
+ {"tcp_listen_queue", tcp_listen_queue_parser, 0 },
+ {"tcp_client_ports", tcp_client_ports_parser, 0 },
{ NULL, NULL }
};
@@ -227,6 +238,10 @@
config->disk_full_exe = NULL;
config->disk_error_action = FA_SYSLOG;
config->disk_error_exe = NULL;
+ config->tcp_listen_port = 0;
+ config->tcp_listen_queue = 5;
+ config->tcp_client_min_port = 0;
+ config->tcp_client_max_port = TCP_PORT_MAX;
}
static log_test_t log_test = TEST_AUDITD;
@@ -1109,6 +1124,172 @@
return 0;
}
+static int tcp_listen_port_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config)
+{
+ const char *ptr = nv->value;
+ unsigned long i;
+
+ audit_msg(LOG_DEBUG, "tcp_listen_port_parser called with: %s",
+ nv->value);
+
+ /* check that all chars are numbers */
+ for (i=0; ptr[i]; i++) {
+ if (!isdigit(ptr[i])) {
+ audit_msg(LOG_ERR,
+ "Value %s should only be numbers - line %d",
+ nv->value, line);
+ return 1;
+ }
+ }
+
+ /* convert to unsigned int */
+ errno = 0;
+ i = strtoul(nv->value, NULL, 10);
+ if (errno) {
+ audit_msg(LOG_ERR,
+ "Error converting string to a number (%s) - line %d",
+ strerror(errno), line);
+ return 1;
+ }
+ /* Check its range */
+ if (i > TCP_PORT_MAX) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%s) is too large - line %d",
+ nv->value, line);
+ return 1;
+ }
+ if (i < 1) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%s) is too small - line %d",
+ nv->value, line);
+ return 1;
+ }
+ config->tcp_listen_port = (unsigned int)i;
+ return 0;
+}
+
+static int tcp_listen_queue_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config)
+{
+ const char *ptr = nv->value;
+ unsigned long i;
+
+ audit_msg(LOG_DEBUG, "tcp_listen_queue_parser called with: %s",
+ nv->value);
+
+ /* check that all chars are numbers */
+ for (i=0; ptr[i]; i++) {
+ if (!isdigit(ptr[i])) {
+ audit_msg(LOG_ERR,
+ "Value %s should only be numbers - line %d",
+ nv->value, line);
+ return 1;
+ }
+ }
+
+ /* convert to unsigned int */
+ errno = 0;
+ i = strtoul(nv->value, NULL, 10);
+ if (errno) {
+ audit_msg(LOG_ERR,
+ "Error converting string to a number (%s) - line %d",
+ strerror(errno), line);
+ return 1;
+ }
+ /* Check its range. While this value is technically
+ unlimited, it's limited by the kernel, and we limit it here
+ for sanity. */
+ if (i > TCP_PORT_MAX) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%s) is too large - line %d",
+ nv->value, line);
+ return 1;
+ }
+ if (i < 1) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%s) is too small - line %d",
+ nv->value, line);
+ return 1;
+ }
+ config->tcp_listen_queue = (unsigned int)i;
+ return 0;
+}
+
+static int tcp_client_ports_parser(struct nv_pair *nv, int line,
+ struct daemon_conf *config)
+{
+ const char *ptr = nv->value;
+ unsigned long i, minv, maxv;
+ const char *saw_dash = NULL;
+
+ audit_msg(LOG_DEBUG, "tcp_listen_queue_parser called with: %s",
+ nv->value);
+
+ /* check that all chars are numbers, with an optional inclusive '-'. */
+ for (i=0; ptr[i]; i++) {
+ if (i > 0 && ptr[i] == '-' && ptr[i+1] != '\0') {
+ saw_dash = ptr + i;
+ continue;
+ }
+ if (!isdigit(ptr[i])) {
+ audit_msg(LOG_ERR,
+ "Value %s should only be numbers, or two numbers separated by a dash - line %d",
+ nv->value, line);
+ return 1;
+ }
+ }
+ for (; ptr[i]; i++) {
+ if (!isdigit(ptr[i])) {
+ audit_msg(LOG_ERR,
+ "Value %s should only be numbers, or two numbers separated by a dash - line %d",
+ nv->value, line);
+ return 1;
+ }
+ }
+
+ /* convert to unsigned int */
+ errno = 0;
+ maxv = minv = strtoul(nv->value, NULL, 10);
+ if (errno) {
+ audit_msg(LOG_ERR,
+ "Error converting string to a number (%s) - line %d",
+ strerror(errno), line);
+ return 1;
+ }
+ if (saw_dash) {
+ maxv = strtoul(saw_dash + 1, NULL, 10);
+ if (errno) {
+ audit_msg(LOG_ERR,
+ "Error converting string to a number (%s) - line %d",
+ strerror(errno), line);
+ return 1;
+ }
+ }
+ /* Check their ranges. */
+ if (minv > TCP_PORT_MAX) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%d) is too large - line %d",
+ minv, line);
+ return 1;
+ }
+ if (maxv > TCP_PORT_MAX) {
+ audit_msg(LOG_ERR,
+ "Error - converted number (%d) is too large - line %d",
+ maxv, line);
+ return 1;
+ }
+ if (minv > maxv) {
+ audit_msg(LOG_ERR,
+ "Error - converted range (%d-%d) is reversed - line %d",
+ minv, maxv, line);
+ return 1;
+ }
+ config->tcp_client_min_port = (unsigned int)minv;
+ config->tcp_client_max_port = (unsigned int)maxv;
+ return 0;
+}
+
/*
* This function is where we do the integrated check of the audit config
* options. At this point, all fields have been read. Returns 0 if no
diff -N -U 3 -x .svn -r pristine/src/auditd-config.h trunk/src/auditd-config.h
--- pristine/src/auditd-config.h 2008-08-04 12:47:30.000000000 -0400
+++ trunk/src/auditd-config.h 2008-08-14 15:33:28.000000000 -0400
@@ -70,6 +70,10 @@
const char *disk_full_exe;
failure_action_t disk_error_action;
const char *disk_error_exe;
+ unsigned long tcp_listen_port;
+ unsigned long tcp_listen_queue;
+ unsigned long tcp_client_min_port;
+ unsigned long tcp_client_max_port;
};
void set_allow_links(int allow);
@@ -80,7 +84,9 @@
int resolve_node(struct daemon_conf *config);
void init_config_manager(void);
+#ifdef AUDITD_EVENT_H
int start_config_manager(struct auditd_reply_list *rep);
+#endif
void shutdown_config(void);
void free_config(struct daemon_conf *config);
diff -N -U 3 -x .svn -r pristine/src/auditd-event.c trunk/src/auditd-event.c
--- pristine/src/auditd-event.c 2008-08-04 12:47:30.000000000 -0400
+++ trunk/src/auditd-event.c 2008-08-13 21:56:24.000000000 -0400
@@ -148,6 +148,36 @@
dequeue'r is responsible for freeing the memory. */
void enqueue_event(struct auditd_reply_list *rep)
{
+ char *buf;
+ int len;
+
+ rep->ack_socket = 0;
+ rep->sequence_id = 0;
+
+ switch (consumer_data.config->log_format)
+ {
+ case LF_RAW:
+ buf = format_raw(&rep->reply, consumer_data.config);
+ break;
+ case LF_NOLOG:
+ return;
+ default:
+ audit_msg(LOG_ERR,
+ "Illegal log format detected %d",
+ consumer_data.config->log_format);
+ return;
+ }
+
+ len = strlen (buf);
+ if (len < MAX_AUDIT_MESSAGE_LENGTH - 1)
+ memcpy (rep->reply.msg.data, buf, len+1);
+ else
+ {
+ /* FIXME: is truncation the right thing to do? */
+ memcpy (rep->reply.msg.data, buf, MAX_AUDIT_MESSAGE_LENGTH-1);
+ rep->reply.msg.data[MAX_AUDIT_MESSAGE_LENGTH-1] = 0;
+ }
+
rep->next = NULL; /* new packet goes at end - so zero this */
pthread_mutex_lock(&consumer_data.queue_lock);
@@ -164,6 +194,45 @@
pthread_mutex_unlock(&consumer_data.queue_lock);
}
+/* This function takes a preformatted message and places it on the
+ queue. The dequeue'r is responsible for freeing the memory. */
+void enqueue_formatted_event(char *msg, int ack_socket, uint32_t sequence_id)
+{
+ int len;
+ struct auditd_reply_list *rep;
+
+ rep = (struct auditd_reply_list *) calloc (1, sizeof (*rep));
+ if (rep == NULL) {
+ audit_msg(LOG_ERR, "Cannot allocate audit reply");
+ return;
+ }
+
+ rep->ack_socket = ack_socket;
+ rep->sequence_id = sequence_id;
+
+ len = strlen (msg);
+ if (len < MAX_AUDIT_MESSAGE_LENGTH - 1)
+ memcpy (rep->reply.msg.data, msg, len+1);
+ else {
+ /* FIXME: is truncation the right thing to do? */
+ memcpy (rep->reply.msg.data, msg, MAX_AUDIT_MESSAGE_LENGTH-1);
+ rep->reply.msg.data[MAX_AUDIT_MESSAGE_LENGTH-1] = 0;
+ }
+
+ pthread_mutex_lock(&consumer_data.queue_lock);
+ if (consumer_data.head == NULL) {
+ consumer_data.head = consumer_data.tail = rep;
+ pthread_cond_signal(&consumer_data.queue_nonempty);
+ } else {
+ /* FIXME: wait for room on the queue */
+
+ /* OK there's room...add it in */
+ consumer_data.tail->next = rep; /* link in at end */
+ consumer_data.tail = rep; /* move end to newest */
+ }
+ pthread_mutex_unlock(&consumer_data.queue_lock);
+}
+
void resume_logging(void)
{
logging_suspended = 0;
@@ -233,30 +302,8 @@
rotate_logs_now(data);
}
if (!logging_suspended) {
- char *buf = NULL;
-
- switch (data->config->log_format)
- {
- case LF_RAW:
- buf = format_raw(&data->head->reply,
- data->config);
- break;
- case LF_NOLOG:
- return;
- default:
- audit_msg(LOG_ERR,
- "Illegal log format detected %d",
- data->config->log_format);
- break;
- }
- /* The only way buf is NULL is if there is an
- * unidentified format...which is impossible since
- * start up would have failed. */
- if (buf) {
- write_to_log(buf, data);
- buf[0] = 0;
- }
+ write_to_log(data->head->reply.msg.data, data);
/* See if we need to flush to disk manually */
if (data->config->flush == FT_INCREMENTAL) {
@@ -289,12 +336,32 @@
}
}
+static int ar_write (int sock, const void *buf, int len)
+{
+ int rc = 0, w;
+ while (len > 0) {
+ do {
+ w = write(sock, buf, len);
+ } while (w < 0 && errno == EINTR);
+ if (w < 0)
+ return w;
+ if (w == 0)
+ break;
+ rc += w;
+ len -= w;
+ buf = (const void *)((const char *)buf + w);
+ }
+ return rc;
+}
+
/* This function writes the given buf to the current log file */
static void write_to_log(const char *buf, struct auditd_consumer_data *data)
{
int rc;
FILE *f = data->log_file;
struct daemon_conf *config = data->config;
+ int ack_type = AUDIT_RMW_TYPE_ACK;
+ const char *msg = "";
/* write it to disk */
rc = fprintf(f, "%s\n", buf);
@@ -307,20 +374,35 @@
if (saved_errno == ENOSPC && fs_space_left == 1) {
fs_space_left = 0;
do_disk_full_action(config);
- } else
+ ack_type = AUDIT_RMW_TYPE_DISKFULL;
+ msg = "disk full";
+ } else {
do_disk_error_action("write", config);
+ ack_type = AUDIT_RMW_TYPE_DISKERROR;
+ msg = "disk write error";
+ }
+
+ } else {
- return;
+ /* check log file size & space left on partition */
+ if (config->daemonize == D_BACKGROUND) {
+ // If either of these fail, I consider it an inconvenience
+ // as opposed to something that is actionable. There may be
+ // some temporary condition that the system recovers from.
+ // The real error occurs on write.
+ check_log_file_size(data->log_fd, data);
+ check_space_left(data->log_fd, config);
+ }
}
- /* check log file size & space left on partition */
- if (config->daemonize == D_BACKGROUND) {
- // If either of these fail, I consider it an inconvenience
- // as opposed to something that is actionable. There may be
- // some temporary condition that the system recovers from.
- // The real error occurs on write.
- check_log_file_size(data->log_fd, data);
- check_space_left(data->log_fd, config);
+ if (data->head->ack_socket) {
+ unsigned char header[AUDIT_RMW_HEADER_SIZE];
+
+ AUDIT_RMW_PACK_HEADER (header, 0, ack_type, strlen(msg), data->head->sequence_id);
+
+ ar_write (data->head->ack_socket, header, AUDIT_RMW_HEADER_SIZE);
+ if (msg[0])
+ ar_write (data->head->ack_socket, msg, strlen(msg));
}
}
diff -N -U 3 -x .svn -r pristine/src/auditd-event.h trunk/src/auditd-event.h
--- pristine/src/auditd-event.h 2008-08-04 12:47:30.000000000 -0400
+++ trunk/src/auditd-event.h 2008-08-13 20:41:41.000000000 -0400
@@ -25,12 +25,21 @@
#define AUDITD_EVENT_H
#include "libaudit.h"
+
+struct auditd_reply_list {
+ struct audit_reply reply;
+ struct auditd_reply_list *next;
+ int ack_socket;
+ unsigned long sequence_id;
+};
+
#include "auditd-config.h"
void shutdown_events(void);
int init_event(struct daemon_conf *config);
void resume_logging(void);
void enqueue_event(struct auditd_reply_list *rep);
+void enqueue_formatted_event(char *msg, int ack_socket, uint32_t sequence_id);
void *consumer_thread_main(void *arg);
#endif
diff -N -U 3 -x .svn -r pristine/src/auditd-listen.c trunk/src/auditd-listen.c
--- pristine/src/auditd-listen.c 1969-12-31 19:00:00.000000000 -0500
+++ trunk/src/auditd-listen.c 2008-08-13 22:29:22.000000000 -0400
@@ -0,0 +1,335 @@
+/* auditd-listen.c --
+ * Copyright 2008 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * DJ Delorie <dj(a)redhat.com>
+ *
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <fcntl.h> /* O_NOFOLLOW needs gnu defined */
+#include <libgen.h>
+#include <arpa/inet.h>
+#include <limits.h> /* INT_MAX */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include "libaudit.h"
+#include "auditd-event.h"
+#include "auditd-config.h"
+#include "private.h"
+
+#include "ev.h"
+
+extern volatile int stop;
+
+typedef struct ev_tcp {
+ struct ev_io io;
+ struct sockaddr_in addr;
+ struct ev_tcp *next, *prev;
+ int bufptr;
+ unsigned char buffer [MAX_AUDIT_MESSAGE_LENGTH + 17];
+} ev_tcp;
+
+static int listen_socket;
+static struct ev_io tcp_listen_watcher;
+static int min_port, max_port;
+
+static struct ev_tcp *client_chain = 0;
+
+static char *sockaddr_to_ip (struct sockaddr_in *addr)
+{
+ unsigned char *uaddr = (unsigned char *)&(addr->sin_addr);
+ static char buf[40];
+
+ sprintf (buf, "%d.%d.%d.%d:%d",
+ uaddr[0], uaddr[1], uaddr[2], uaddr[3], ntohs (addr->sin_port));
+ return buf;
+}
+
+static void set_close_on_exec (int fd)
+{
+ int flags = fcntl (fd, F_GETFD);
+ if (flags == -1)
+ flags = 0;
+ flags |= FD_CLOEXEC;
+ fcntl (fd, F_SETFD, flags);
+}
+
+static void close_client (struct ev_tcp *client)
+{
+ close (client->io.fd);
+ if (client_chain == client)
+ client_chain = client->next;
+ if (client->next)
+ client->next->prev = client->prev;
+ if (client->prev)
+ client->prev->next = client->next;
+ free (client);
+}
+
+static void client_message (struct ev_tcp *io, unsigned int length, unsigned char *header)
+{
+ unsigned char ch;
+ uint32_t magic, type, mlen, seq;
+ int hver, mver;
+ int i;
+
+ if (AUDIT_RMW_IS_MAGIC (header, length)) {
+ AUDIT_RMW_UNPACK_HEADER (header, hver, mver, type, mlen, seq)
+
+ ch = header[length];
+ header[length] = 0;
+ if (length > 1 && header[length-1] == '\n')
+ header[length-1] = 0;
+ enqueue_formatted_event (header+AUDIT_RMW_HEADER_SIZE, io->io.fd, seq);
+ header[length] = ch;
+ } else {
+ header[length] = 0;
+ if (length > 1 && header[length-1] == '\n')
+ header[length-1] = 0;
+ enqueue_formatted_event (header, 0, 0);
+ }
+}
+
+static void auditd_tcp_client_handler( struct ev_loop *loop, struct ev_io *_io, int revents )
+{
+ struct ev_tcp *io = (struct ev_tcp *) _io;
+ int i, r;
+ int total_this_call = 0;
+
+ /* The socket is non-blocking, but we have a limited buffer
+ size. In the event that we get a packet that's bigger than
+ our buffer, we need to read it in multiple parts. Thus, we
+ keep reading/parsing/processing until we run out of ready
+ data. */
+read_more:
+ r = read (io->io.fd,
+ io->buffer + io->bufptr,
+ MAX_AUDIT_MESSAGE_LENGTH - io->bufptr);
+
+ if (r < 0 && errno == EAGAIN)
+ r = 0;
+
+ /* We need to keep track of the difference between "no data
+ * because it's closed" and "no data because we've read it
+ * all". */
+ if (r == 0 && total_this_call > 0) {
+ return;
+ }
+
+ /* If the connection is gracefully closed, the first read we
+ try will return zero. If the connection times out or
+ otherwise fails, the read will return -1. */
+ if (r <= 0) {
+ if (r < 0)
+ audit_msg (LOG_WARNING, "client %s socket closed unexpectedly",
+ sockaddr_to_ip (&io->addr));
+
+ /* There may have been a final message without a LF. */
+ if (io->bufptr) {
+ client_message (io, io->bufptr, io->buffer);
+
+ }
+
+ ev_io_stop (loop, _io);
+ close_client (io);
+ return;
+ }
+
+ total_this_call += r;
+
+more_messages:
+ if (AUDIT_RMW_IS_MAGIC (io->buffer, io->bufptr+r)) {
+ uint32_t type, len, seq;
+ int hver, mver;
+ unsigned char *header = (unsigned char *)io->buffer;
+
+ io->bufptr += r;
+
+ if (io->bufptr < AUDIT_RMW_HEADER_SIZE)
+ return;
+
+ AUDIT_RMW_UNPACK_HEADER (header, hver, mver, type, len, seq);
+
+ i = len;
+ i += AUDIT_RMW_HEADER_SIZE;
+
+ /* See if we have enough bytes to extract the whole message. */
+ if (io->bufptr < i)
+ return;
+
+ } else {
+ /* At this point, the buffer has IO->BUFPTR+R bytes in it.
+ The first IO->BUFPTR bytes do not have a LF in them (we've
+ already checked), we must check the R new bytes. */
+
+ for (i = io->bufptr; i < io->bufptr + r; i ++)
+ if (io->buffer [i] == '\n')
+ break;
+
+ io->bufptr += r;
+
+ /* Check for a partial message, with no LF yet. */
+ if (i == io->bufptr)
+ return;
+
+ i ++;
+ }
+
+ /* We have an I-byte message in buffer. */
+ client_message (io, i, io->buffer);
+
+ /* Now copy any remaining bytes to the beginning of the
+ buffer. */
+ memmove (io->buffer, io->buffer + i, io->bufptr);
+ io->bufptr -= i;
+
+ /* See if this packet had more than one message in it. */
+ if (io->bufptr > 0) {
+ r = io->bufptr;
+ io->bufptr = 0;
+ goto more_messages;
+ }
+
+ /* Go back and see if there's more data to read. */
+ goto read_more;
+}
+
+static void auditd_tcp_listen_handler( struct ev_loop *loop, struct ev_io *_io, int revents )
+{
+ int one=1;
+ int afd;
+ socklen_t aaddrlen;
+ struct sockaddr_in aaddr;
+ struct linger li;
+ struct ev_tcp *client;
+ unsigned char *uaddr;
+
+ /* Accept the connection and see where it's coming from. */
+ aaddrlen = sizeof(aaddr);
+ afd = accept (listen_socket, (struct sockaddr *)&aaddr, &aaddrlen);
+ if (afd == -1) {
+ audit_msg(LOG_ERR, "Unable to accept TCP connection");
+ return;
+ }
+
+ uaddr = (unsigned char *)&aaddr.sin_addr;
+
+ /* Verify it's coming from an authorized port. We assume the firewall will
+ block attempts from unauthorized machines. */
+ if (min_port > ntohs (aaddr.sin_port) || ntohs (aaddr.sin_port) > max_port) {
+ audit_msg(LOG_ERR, "TCP connection from %s rejected", sockaddr_to_ip (&aaddr));
+ close (afd);
+ return;
+ }
+
+ setsockopt(afd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
+ setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof (int));
+ setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof (int));
+ fcntl(afd, F_SETFL, O_NONBLOCK | O_NDELAY);
+ set_close_on_exec (afd);
+
+ client = (struct ev_tcp *) malloc (sizeof (struct ev_tcp));
+ if (client == NULL) {
+ audit_msg(LOG_CRIT, "Unable to allocate TCP client data");
+ close (afd);
+ return;
+ }
+
+ memset (client, 0, sizeof (struct ev_tcp));
+
+ ev_io_init (&(client->io), auditd_tcp_client_handler, afd, EV_READ | EV_ERROR);
+ ev_io_start (loop, &(client->io));
+
+ memcpy (&client->addr, &aaddr, sizeof (struct sockaddr_in));
+
+ /* Keep a linked list of active clients. */
+ client->next = client_chain;
+ if (client->next)
+ client->next->prev = client;
+ client_chain = client;
+}
+
+int auditd_tcp_listen_init ( struct ev_loop *loop, struct daemon_conf *config )
+{
+ struct sockaddr_in address;
+ int one = 1;
+ int flags;
+
+ /* If the port is not set, that means we aren't going to
+ listen for connections. */
+ if (config->tcp_listen_port == 0)
+ return;
+
+ listen_socket = socket (AF_INET, SOCK_STREAM, 0);
+ if (listen_socket == 0) {
+ audit_msg(LOG_ERR, "Cannot create tcp listener socket");
+ return 1;
+ }
+
+ set_close_on_exec (listen_socket);
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
+
+ memset (&address, 0, sizeof(address));
+ address.sin_family = htons(AF_INET);
+ address.sin_port = htons(config->tcp_listen_port);
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ /* This avoids problems if auditd needs to be restarted. */
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
+
+ if ( bind ( listen_socket, (struct sockaddr *)&address, sizeof(address)) ) {
+ audit_msg(LOG_ERR, "Cannot bind tcp listener socket to port %d",
+ config->tcp_listen_port);
+ close(listen_socket);
+ return 1;
+ }
+
+ listen(listen_socket, config->tcp_listen_queue);
+
+ audit_msg(LOG_DEBUG, "Listening on TCP port %d", config->tcp_listen_port);
+
+ ev_io_init (&tcp_listen_watcher, auditd_tcp_listen_handler, listen_socket, EV_READ);
+ ev_io_start (loop, &tcp_listen_watcher);
+
+ min_port = config->tcp_client_min_port;
+ max_port = config->tcp_client_max_port;
+
+ return 0;
+}
+
+void auditd_tcp_listen_uninit ( struct ev_loop *loop )
+{
+ ev_io_stop ( loop, &tcp_listen_watcher );
+ close ( listen_socket );
+
+ while (client_chain) {
+ close_client (client_chain);
+ }
+}
diff -N -U 3 -x .svn -r pristine/src/auditd-listen.h trunk/src/auditd-listen.h
--- pristine/src/auditd-listen.h 1969-12-31 19:00:00.000000000 -0500
+++ trunk/src/auditd-listen.h 2008-08-08 17:01:37.000000000 -0400
@@ -0,0 +1,30 @@
+/* auditd-config.h --
+ * Copyright 2004-2007 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * DJ Delorie <dj(a)redhat.com>
+ *
+ */
+
+#ifndef AUDITD_LISTEN_H
+#define AUDITD_LISTEN_H
+
+int auditd_tcp_listen_init ( struct ev_loop *loop, struct daemon_conf *config );
+void auditd_tcp_listen_uninit ( struct ev_loop *loop );
+
+#endif
diff -N -U 3 -x .svn -r pristine/src/auditd-reconfig.c trunk/src/auditd-reconfig.c
--- pristine/src/auditd-reconfig.c 2008-08-04 12:47:30.000000000 -0400
+++ trunk/src/auditd-reconfig.c 2008-08-12 18:54:20.000000000 -0400
@@ -28,9 +28,9 @@
#include <unistd.h>
#include <string.h>
#include <stdio.h>
-#include "auditd-config.h"
-#include "auditd-event.h"
#include "libaudit.h"
+#include "auditd-event.h"
+#include "auditd-config.h"
#include "private.h"
/* This is the configuration manager code */
diff -N -U 3 -x .svn -r pristine/src/auditd.c trunk/src/auditd.c
--- pristine/src/auditd.c 2008-08-08 14:36:19.000000000 -0400
+++ trunk/src/auditd.c 2008-08-13 20:51:35.000000000 -0400
@@ -40,8 +40,8 @@
#include <getopt.h>
#include "libaudit.h"
-#include "auditd-config.h"
#include "auditd-event.h"
+#include "auditd-config.h"
#include "auditd-dispatch.h"
#include "private.h"
@@ -670,7 +670,15 @@
ev_signal_init (&sigchld_watcher, child_handler, SIGCHLD);
ev_signal_start (loop, &sigchld_watcher);
- ev_loop (loop, 0);
+ if (auditd_tcp_listen_init (loop, &config)) {
+ tell_parent (FAILURE);
+ stop = 1;
+ }
+
+ if (!stop)
+ ev_loop (loop, 0);
+
+ auditd_tcp_listen_uninit (loop);
/* Write message to log that we are going down */
15 years, 2 months
buffer space
by David Flatley
Red Hat 5.3 running audit 1.7.7-6
Rotating logs at 20 megs and allowing 8 logs
Rules have watches and syscalls from the SECSCAN recommendations, and have
added some of Steve Grubb's recommendations.
When we extract and archive the audit logs we get "Error receiving audit
netlink packet (No buffer space available) an "error sending signal info
request"
Our extract is: stop auditd then create a file and run ausearch -i > file
then run an aureport -i > file then once that is done we delete all the
logs and restart auditd.
If I run this manually it works fine but if I have it running it in a cron
we get Kernel panics, lockups and log data loss plus the buffer messages.
I added "-r 0" to the audit.rules but it does not seem to work. We run a
very similar configuration on Red Hat ES and AS 4 with no problems.
We are testing the subject systems and running a looping regression test
that can fill the audit logs in a little over an hour at the present
settings.
Thoughts or ideas??
Thanks.
David Flatley CISSP
I.T. Specialist, Managing Consultant
Member: ISC2, ISACA, Center for Internet Security
15 years, 4 months
Reactive rules (from juro.fit@gmail.com)
by Miloslav Trmac
I planned to create a plugin which would extend the current audit
capabilities adding a new type of rule - a reactive rule. This
type of rule is different in the way that it watches for an event
like an ordinary rule, however, when the event happens, it reacts
to that adding or deleting other rules. For example, there is
a reactive rule that watches for a certain user to login and as
the reaction to the event, it adds the new rule that watches for
file changes in the user's home dir.
The problem with the plugin is that it would have to analyze
every single message from the dispatcher, parse it and look for
an appropriate rule in a rule set that caused this message was
generated. The process of parsing every message isn't the right
thing to do because of overheat.
I suggest that a change should be done in the kernel. The events
are filtered in it so that there is no need parsing the messages
sent to the auditd and this solution wouldn't cause any increase
in the load of the system caused by auditing.
First of all, the syntax of the rules should be changed a bit to
include reactive rules. It could look like this:
rule1
rule2 {
rule2_1
rule2_2
}
rule3
When an event that rule2 watches for occurs, rule2_1 and rule2_2
will be added/removed to/from the rule set.
The change in the syntax means a change in auditctl.c. Also,
struct audit_rule_data needs to be altered to include some flag
that makes it possible to recognize between the types of rules
when passed to the kernel.
Furthermore, ordinary rules are added/removed to/from the rule
set as soon as the kernel receives a request from the user space.
>From the example above, rules rule2_1 and rule2_2 can't be
added/removed to/from the rule set immediately because an event
that matches rule2 must occur at first. Although, they must be
saved in the kernel, for example, they could be kept in a list
of type struct list_head and the associated reactive rule would
keep a reference to this list.
----------
15 years, 4 months
Gavin Appleton is out of the office.
by Gavin Appleton
I will be out of the office starting 21/08/2009 and will not return until
31/08/2009.
I will respond to your message when I return.
15 years, 4 months
Gavin Appleton is out of the office.
by Gavin Appleton
I will be out of the office starting 17/08/2009 and will not return until
20/08/2009.
I will respond to your message when I return.
15 years, 4 months
Re: [PATCH -v3] SELinux: Convert avc_audit to use lsm_audit.h
by Stephen Smalley
On Tue, 2009-07-14 at 12:14 -0400, Thomas Liu wrote:
> Convert avc_audit in security/selinux/avc.c to use lsm_audit.h,
> for better maintainability.
>
> - changed selinux to use common_audit_data instead of
> avc_audit_data
> - eliminated code in avc.c and used code from lsm_audit.h instead.
>
> Had to add a LSM_AUDIT_NO_AUDIT to lsm_audit.h so that avc_audit
> can call common_lsm_audit and do the pre and post callbacks without
> doing the actual dump. This makes it so that the patched version
> behaves the same way as the unpatched version.
>
> Also added a denied field to the selinux_audit_data private space,
> once again to make it so that the patched version behaves like the
> unpatched.
>
> I've tested and confirmed that AVCs look the same before and after
> this patch.
>
> Signed-off-by: Thomas Liu <tliu(a)redhat.com>
Acked-by: Stephen Smalley <sds(a)tycho.nsa.gov>
Looks like there is also further room for consolidation, e.g. the skb
parsing routines.
BTW, it looks to my untrained eye as if dump_common_audit_data() allows
one to pass a separate target task in the union, in which case we'll get
two sets of pid= and comm= data in the same record, one for the subject
and one for the target/object. It appears that Smack is already using
that facility for things like ptrace, kill, etc, whereas SELinux is not.
Two questions:
1) Will the multiple pid= comm= entries get handled correctly by auditd
and the audit tools? Do we need separate names for the target vs source
pid/comm values?
2) Should we start using ad.u.tsk in SELinux as well to capture the
target of a ptrace, kill, wait, ... in the avc audit record?
> ---
> Sorry about the previous version!
>
> include/linux/lsm_audit.h | 2
> security/Makefile | 4 -
> security/lsm_audit.c | 2
> security/selinux/avc.c | 197 +++++++----------------------------
> security/selinux/hooks.c | 142 +++++++++++++------------
> security/selinux/include/avc.h | 49 +--------
> security/selinux/include/netlabel.h | 4 -
> security/selinux/include/xfrm.h | 8 +
> security/selinux/netlabel.c | 2
> security/selinux/xfrm.c | 4 -
> 10 files changed, 131 insertions(+), 283 deletions(-)
>
>
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index a5514a3..190c378 100644
> --- a/include/linux/lsm_audit.h
> +++ b/include/linux/lsm_audit.h
> @@ -33,6 +33,7 @@ struct common_audit_data {
> #define LSM_AUDIT_DATA_IPC 4
> #define LSM_AUDIT_DATA_TASK 5
> #define LSM_AUDIT_DATA_KEY 6
> +#define LSM_AUDIT_NO_AUDIT 7
> struct task_struct *tsk;
> union {
> struct {
> @@ -86,6 +87,7 @@ struct common_audit_data {
> u16 tclass;
> u32 requested;
> u32 audited;
> + u32 denied;
> struct av_decision *avd;
> int result;
> } selinux_audit_data;
> diff --git a/security/Makefile b/security/Makefile
> index c67557c..8dcc1fd 100644
> --- a/security/Makefile
> +++ b/security/Makefile
> @@ -16,9 +16,7 @@ obj-$(CONFIG_SECURITYFS) += inode.o
> # Must precede capability.o in order to stack properly.
> obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
> obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
> -ifeq ($(CONFIG_AUDIT),y)
> -obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o
> -endif
> +obj-$(CONFIG_AUDIT) += lsm_audit.o
> obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
> obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
> obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
> diff --git a/security/lsm_audit.c b/security/lsm_audit.c
> index 94b8684..500aad0 100644
> --- a/security/lsm_audit.c
> +++ b/security/lsm_audit.c
> @@ -220,6 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
> }
>
> switch (a->type) {
> + case LSM_AUDIT_NO_AUDIT:
> + return;
> case LSM_AUDIT_DATA_IPC:
> audit_log_format(ab, " key=%d ", a->u.ipc_id);
> break;
> diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> index 236aaa2..e3d1901 100644
> --- a/security/selinux/avc.c
> +++ b/security/selinux/avc.c
> @@ -492,23 +492,35 @@ out:
> return node;
> }
>
> -static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
> - struct in6_addr *addr, __be16 port,
> - char *name1, char *name2)
> +/**
> + * avc_audit_pre_callback - SELinux specific information
> + * will be called by generic audit code
> + * @ab: the audit buffer
> + * @a: audit_data
> + */
> +static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
> {
> - if (!ipv6_addr_any(addr))
> - audit_log_format(ab, " %s=%pI6", name1, addr);
> - if (port)
> - audit_log_format(ab, " %s=%d", name2, ntohs(port));
> + struct common_audit_data *ad = a;
> + audit_log_format(ab, "avc: %s ",
> + ad->selinux_audit_data.denied ? "denied" : "granted");
> + avc_dump_av(ab, ad->selinux_audit_data.tclass,
> + ad->selinux_audit_data.audited);
> + audit_log_format(ab, " for ");
> }
>
> -static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
> - __be16 port, char *name1, char *name2)
> +/**
> + * avc_audit_post_callback - SELinux specific information
> + * will be called by generic audit code
> + * @ab: the audit buffer
> + * @a: audit_data
> + */
> +static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
> {
> - if (addr)
> - audit_log_format(ab, " %s=%pI4", name1, &addr);
> - if (port)
> - audit_log_format(ab, " %s=%d", name2, ntohs(port));
> + struct common_audit_data *ad = a;
> + audit_log_format(ab, " ");
> + avc_dump_query(ab, ad->selinux_audit_data.ssid,
> + ad->selinux_audit_data.tsid,
> + ad->selinux_audit_data.tclass);
> }
>
> /**
> @@ -532,13 +544,10 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
> */
> void avc_audit(u32 ssid, u32 tsid,
> u16 tclass, u32 requested,
> - struct av_decision *avd, int result, struct avc_audit_data *a)
> + struct av_decision *avd, int result, struct common_audit_data *a)
> {
> - struct task_struct *tsk = current;
> - struct inode *inode = NULL;
> + struct common_audit_data stack_data;
> u32 denied, audited;
> - struct audit_buffer *ab;
> -
> denied = requested & ~avd->allowed;
> if (denied) {
> audited = denied;
> @@ -551,144 +560,20 @@ void avc_audit(u32 ssid, u32 tsid,
> if (!(audited & avd->auditallow))
> return;
> }
> -
> - ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
> - if (!ab)
> - return; /* audit_panic has been called */
> - audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
> - avc_dump_av(ab, tclass, audited);
> - audit_log_format(ab, " for ");
> - if (a && a->tsk)
> - tsk = a->tsk;
> - if (tsk && tsk->pid) {
> - audit_log_format(ab, " pid=%d comm=", tsk->pid);
> - audit_log_untrustedstring(ab, tsk->comm);
> - }
> - if (a) {
> - switch (a->type) {
> - case AVC_AUDIT_DATA_IPC:
> - audit_log_format(ab, " key=%d", a->u.ipc_id);
> - break;
> - case AVC_AUDIT_DATA_CAP:
> - audit_log_format(ab, " capability=%d", a->u.cap);
> - break;
> - case AVC_AUDIT_DATA_FS:
> - if (a->u.fs.path.dentry) {
> - struct dentry *dentry = a->u.fs.path.dentry;
> - if (a->u.fs.path.mnt) {
> - audit_log_d_path(ab, "path=",
> - &a->u.fs.path);
> - } else {
> - audit_log_format(ab, " name=");
> - audit_log_untrustedstring(ab, dentry->d_name.name);
> - }
> - inode = dentry->d_inode;
> - } else if (a->u.fs.inode) {
> - struct dentry *dentry;
> - inode = a->u.fs.inode;
> - dentry = d_find_alias(inode);
> - if (dentry) {
> - audit_log_format(ab, " name=");
> - audit_log_untrustedstring(ab, dentry->d_name.name);
> - dput(dentry);
> - }
> - }
> - if (inode)
> - audit_log_format(ab, " dev=%s ino=%lu",
> - inode->i_sb->s_id,
> - inode->i_ino);
> - break;
> - case AVC_AUDIT_DATA_NET:
> - if (a->u.net.sk) {
> - struct sock *sk = a->u.net.sk;
> - struct unix_sock *u;
> - int len = 0;
> - char *p = NULL;
> -
> - switch (sk->sk_family) {
> - case AF_INET: {
> - struct inet_sock *inet = inet_sk(sk);
> -
> - avc_print_ipv4_addr(ab, inet->rcv_saddr,
> - inet->sport,
> - "laddr", "lport");
> - avc_print_ipv4_addr(ab, inet->daddr,
> - inet->dport,
> - "faddr", "fport");
> - break;
> - }
> - case AF_INET6: {
> - struct inet_sock *inet = inet_sk(sk);
> - struct ipv6_pinfo *inet6 = inet6_sk(sk);
> -
> - avc_print_ipv6_addr(ab, &inet6->rcv_saddr,
> - inet->sport,
> - "laddr", "lport");
> - avc_print_ipv6_addr(ab, &inet6->daddr,
> - inet->dport,
> - "faddr", "fport");
> - break;
> - }
> - case AF_UNIX:
> - u = unix_sk(sk);
> - if (u->dentry) {
> - struct path path = {
> - .dentry = u->dentry,
> - .mnt = u->mnt
> - };
> - audit_log_d_path(ab, "path=",
> - &path);
> - break;
> - }
> - if (!u->addr)
> - break;
> - len = u->addr->len-sizeof(short);
> - p = &u->addr->name->sun_path[0];
> - audit_log_format(ab, " path=");
> - if (*p)
> - audit_log_untrustedstring(ab, p);
> - else
> - audit_log_n_hex(ab, p, len);
> - break;
> - }
> - }
> -
> - switch (a->u.net.family) {
> - case AF_INET:
> - avc_print_ipv4_addr(ab, a->u.net.v4info.saddr,
> - a->u.net.sport,
> - "saddr", "src");
> - avc_print_ipv4_addr(ab, a->u.net.v4info.daddr,
> - a->u.net.dport,
> - "daddr", "dest");
> - break;
> - case AF_INET6:
> - avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr,
> - a->u.net.sport,
> - "saddr", "src");
> - avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr,
> - a->u.net.dport,
> - "daddr", "dest");
> - break;
> - }
> - if (a->u.net.netif > 0) {
> - struct net_device *dev;
> -
> - /* NOTE: we always use init's namespace */
> - dev = dev_get_by_index(&init_net,
> - a->u.net.netif);
> - if (dev) {
> - audit_log_format(ab, " netif=%s",
> - dev->name);
> - dev_put(dev);
> - }
> - }
> - break;
> - }
> + if (!a) {
> + a = &stack_data;
> + memset(a, 0, sizeof(*a));
> + a->type = LSM_AUDIT_NO_AUDIT;
> }
> - audit_log_format(ab, " ");
> - avc_dump_query(ab, ssid, tsid, tclass);
> - audit_log_end(ab);
> + a->selinux_audit_data.tclass = tclass;
> + a->selinux_audit_data.requested = requested;
> + a->selinux_audit_data.ssid = ssid;
> + a->selinux_audit_data.tsid = tsid;
> + a->selinux_audit_data.audited = audited;
> + a->selinux_audit_data.denied = denied;
> + a->lsm_pre_audit = avc_audit_pre_callback;
> + a->lsm_post_audit = avc_audit_post_callback;
> + common_lsm_audit(a);
> }
>
> /**
> @@ -956,7 +841,7 @@ out:
> * another -errno upon other errors.
> */
> int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
> - u32 requested, struct avc_audit_data *auditdata)
> + u32 requested, struct common_audit_data *auditdata)
> {
> struct av_decision avd;
> int rc;
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 2081055..a7de261 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -1478,14 +1478,14 @@ static int task_has_capability(struct task_struct *tsk,
> const struct cred *cred,
> int cap, int audit)
> {
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> struct av_decision avd;
> u16 sclass;
> u32 sid = cred_sid(cred);
> u32 av = CAP_TO_MASK(cap);
> int rc;
>
> - AVC_AUDIT_DATA_INIT(&ad, CAP);
> + COMMON_AUDIT_DATA_INIT(&ad, CAP);
> ad.tsk = tsk;
> ad.u.cap = cap;
>
> @@ -1524,10 +1524,10 @@ static int task_has_system(struct task_struct *tsk,
> static int inode_has_perm(const struct cred *cred,
> struct inode *inode,
> u32 perms,
> - struct avc_audit_data *adp)
> + struct common_audit_data *adp)
> {
> struct inode_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid;
>
> if (unlikely(IS_PRIVATE(inode)))
> @@ -1538,7 +1538,7 @@ static int inode_has_perm(const struct cred *cred,
>
> if (!adp) {
> adp = &ad;
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.inode = inode;
> }
>
> @@ -1554,9 +1554,9 @@ static inline int dentry_has_perm(const struct cred *cred,
> u32 av)
> {
> struct inode *inode = dentry->d_inode;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.mnt = mnt;
> ad.u.fs.path.dentry = dentry;
> return inode_has_perm(cred, inode, av, &ad);
> @@ -1576,11 +1576,11 @@ static int file_has_perm(const struct cred *cred,
> {
> struct file_security_struct *fsec = file->f_security;
> struct inode *inode = file->f_path.dentry->d_inode;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = cred_sid(cred);
> int rc;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path = file->f_path;
>
> if (sid != fsec->sid) {
> @@ -1611,7 +1611,7 @@ static int may_create(struct inode *dir,
> struct inode_security_struct *dsec;
> struct superblock_security_struct *sbsec;
> u32 sid, newsid;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> int rc;
>
> dsec = dir->i_security;
> @@ -1620,7 +1620,7 @@ static int may_create(struct inode *dir,
> sid = tsec->sid;
> newsid = tsec->create_sid;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.dentry = dentry;
>
> rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
> @@ -1664,7 +1664,7 @@ static int may_link(struct inode *dir,
>
> {
> struct inode_security_struct *dsec, *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> u32 av;
> int rc;
> @@ -1672,7 +1672,7 @@ static int may_link(struct inode *dir,
> dsec = dir->i_security;
> isec = dentry->d_inode->i_security;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.dentry = dentry;
>
> av = DIR__SEARCH;
> @@ -1707,7 +1707,7 @@ static inline int may_rename(struct inode *old_dir,
> struct dentry *new_dentry)
> {
> struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> u32 av;
> int old_is_dir, new_is_dir;
> @@ -1718,7 +1718,7 @@ static inline int may_rename(struct inode *old_dir,
> old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
> new_dsec = new_dir->i_security;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
>
> ad.u.fs.path.dentry = old_dentry;
> rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
> @@ -1760,7 +1760,7 @@ static inline int may_rename(struct inode *old_dir,
> static int superblock_has_perm(const struct cred *cred,
> struct super_block *sb,
> u32 perms,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> struct superblock_security_struct *sbsec;
> u32 sid = cred_sid(cred);
> @@ -2100,7 +2100,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
> const struct task_security_struct *old_tsec;
> struct task_security_struct *new_tsec;
> struct inode_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> struct inode *inode = bprm->file->f_path.dentry->d_inode;
> int rc;
>
> @@ -2138,7 +2138,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
> return rc;
> }
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path = bprm->file->f_path;
>
> if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
> @@ -2231,7 +2231,7 @@ extern struct dentry *selinux_null;
> static inline void flush_unauthorized_files(const struct cred *cred,
> struct files_struct *files)
> {
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> struct file *file, *devnull = NULL;
> struct tty_struct *tty;
> struct fdtable *fdt;
> @@ -2265,7 +2265,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
>
> /* Revalidate access to inherited open files. */
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
>
> spin_lock(&files->file_lock);
> for (;;) {
> @@ -2514,7 +2514,7 @@ out:
> static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
> {
> const struct cred *cred = current_cred();
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> int rc;
>
> rc = superblock_doinit(sb, data);
> @@ -2525,7 +2525,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
> if (flags & MS_KERNMOUNT)
> return 0;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.dentry = sb->s_root;
> return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
> }
> @@ -2533,9 +2533,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
> static int selinux_sb_statfs(struct dentry *dentry)
> {
> const struct cred *cred = current_cred();
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.dentry = dentry->d_sb->s_root;
> return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
> }
> @@ -2755,7 +2755,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
> struct inode *inode = dentry->d_inode;
> struct inode_security_struct *isec = inode->i_security;
> struct superblock_security_struct *sbsec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 newsid, sid = current_sid();
> int rc = 0;
>
> @@ -2769,7 +2769,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
> if (!is_owner_or_cap(inode))
> return -EPERM;
>
> - AVC_AUDIT_DATA_INIT(&ad, FS);
> + COMMON_AUDIT_DATA_INIT(&ad, FS);
> ad.u.fs.path.dentry = dentry;
>
> rc = avc_has_perm(sid, isec->sid, isec->sclass,
> @@ -3401,7 +3401,7 @@ static void selinux_task_to_inode(struct task_struct *p,
>
> /* Returns error only if unable to parse addresses */
> static int selinux_parse_skb_ipv4(struct sk_buff *skb,
> - struct avc_audit_data *ad, u8 *proto)
> + struct common_audit_data *ad, u8 *proto)
> {
> int offset, ihlen, ret = -EINVAL;
> struct iphdr _iph, *ih;
> @@ -3482,7 +3482,7 @@ out:
>
> /* Returns error only if unable to parse addresses */
> static int selinux_parse_skb_ipv6(struct sk_buff *skb,
> - struct avc_audit_data *ad, u8 *proto)
> + struct common_audit_data *ad, u8 *proto)
> {
> u8 nexthdr;
> int ret = -EINVAL, offset;
> @@ -3553,7 +3553,7 @@ out:
>
> #endif /* IPV6 */
>
> -static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
> +static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
> char **_addrp, int src, u8 *proto)
> {
> char *addrp;
> @@ -3635,7 +3635,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
> u32 perms)
> {
> struct inode_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid;
> int err = 0;
>
> @@ -3645,7 +3645,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
> goto out;
> sid = task_sid(task);
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.sk = sock->sk;
> err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
>
> @@ -3732,7 +3732,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
> if (family == PF_INET || family == PF_INET6) {
> char *addrp;
> struct inode_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> struct sockaddr_in *addr4 = NULL;
> struct sockaddr_in6 *addr6 = NULL;
> unsigned short snum;
> @@ -3761,7 +3761,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
> snum, &sid);
> if (err)
> goto out;
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.sport = htons(snum);
> ad.u.net.family = family;
> err = avc_has_perm(isec->sid, sid,
> @@ -3794,7 +3794,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
> if (err)
> goto out;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.sport = htons(snum);
> ad.u.net.family = family;
>
> @@ -3828,7 +3828,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
> isec = SOCK_INODE(sock)->i_security;
> if (isec->sclass == SECCLASS_TCP_SOCKET ||
> isec->sclass == SECCLASS_DCCP_SOCKET) {
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> struct sockaddr_in *addr4 = NULL;
> struct sockaddr_in6 *addr6 = NULL;
> unsigned short snum;
> @@ -3853,7 +3853,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
> perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
> TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.dport = htons(snum);
> ad.u.net.family = sk->sk_family;
> err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
> @@ -3943,13 +3943,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
> struct sk_security_struct *ssec;
> struct inode_security_struct *isec;
> struct inode_security_struct *other_isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> int err;
>
> isec = SOCK_INODE(sock)->i_security;
> other_isec = SOCK_INODE(other)->i_security;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.sk = other->sk;
>
> err = avc_has_perm(isec->sid, other_isec->sid,
> @@ -3975,13 +3975,13 @@ static int selinux_socket_unix_may_send(struct socket *sock,
> {
> struct inode_security_struct *isec;
> struct inode_security_struct *other_isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> int err;
>
> isec = SOCK_INODE(sock)->i_security;
> other_isec = SOCK_INODE(other)->i_security;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.sk = other->sk;
>
> err = avc_has_perm(isec->sid, other_isec->sid,
> @@ -3994,7 +3994,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,
>
> static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
> u32 peer_sid,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> int err;
> u32 if_sid;
> @@ -4022,10 +4022,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
> struct sk_security_struct *sksec = sk->sk_security;
> u32 peer_sid;
> u32 sk_sid = sksec->sid;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> char *addrp;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.netif = skb->iif;
> ad.u.net.family = family;
> err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
> @@ -4063,7 +4063,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
> struct sk_security_struct *sksec = sk->sk_security;
> u16 family = sk->sk_family;
> u32 sk_sid = sksec->sid;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> char *addrp;
> u8 secmark_active;
> u8 peerlbl_active;
> @@ -4087,7 +4087,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
> if (!secmark_active && !peerlbl_active)
> return 0;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.netif = skb->iif;
> ad.u.net.family = family;
> err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
> @@ -4345,7 +4345,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
> int err;
> char *addrp;
> u32 peer_sid;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u8 secmark_active;
> u8 netlbl_active;
> u8 peerlbl_active;
> @@ -4362,7 +4362,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
> if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
> return NF_DROP;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.netif = ifindex;
> ad.u.net.family = family;
> if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
> @@ -4450,7 +4450,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
> {
> struct sock *sk = skb->sk;
> struct sk_security_struct *sksec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> char *addrp;
> u8 proto;
>
> @@ -4458,7 +4458,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
> return NF_ACCEPT;
> sksec = sk->sk_security;
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.netif = ifindex;
> ad.u.net.family = family;
> if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
> @@ -4482,7 +4482,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
> u32 secmark_perm;
> u32 peer_sid;
> struct sock *sk;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> char *addrp;
> u8 secmark_active;
> u8 peerlbl_active;
> @@ -4541,7 +4541,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
> secmark_perm = PACKET__SEND;
> }
>
> - AVC_AUDIT_DATA_INIT(&ad, NET);
> + COMMON_AUDIT_DATA_INIT(&ad, NET);
> ad.u.net.netif = ifindex;
> ad.u.net.family = family;
> if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
> @@ -4611,13 +4611,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
> static int selinux_netlink_recv(struct sk_buff *skb, int capability)
> {
> int err;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
>
> err = cap_netlink_recv(skb, capability);
> if (err)
> return err;
>
> - AVC_AUDIT_DATA_INIT(&ad, CAP);
> + COMMON_AUDIT_DATA_INIT(&ad, CAP);
> ad.u.cap = capability;
>
> return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
> @@ -4676,12 +4676,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
> u32 perms)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
>
> isec = ipc_perms->security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = ipc_perms->key;
>
> return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
> @@ -4701,7 +4701,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg)
> static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> int rc;
>
> @@ -4711,7 +4711,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
>
> isec = msq->q_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = msq->q_perm.key;
>
> rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
> @@ -4731,12 +4731,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq)
> static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
>
> isec = msq->q_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = msq->q_perm.key;
>
> return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
> @@ -4775,7 +4775,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
> {
> struct ipc_security_struct *isec;
> struct msg_security_struct *msec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> int rc;
>
> @@ -4796,7 +4796,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
> return rc;
> }
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = msq->q_perm.key;
>
> /* Can this process write to the queue? */
> @@ -4820,14 +4820,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
> {
> struct ipc_security_struct *isec;
> struct msg_security_struct *msec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = task_sid(target);
> int rc;
>
> isec = msq->q_perm.security;
> msec = msg->security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = msq->q_perm.key;
>
> rc = avc_has_perm(sid, isec->sid,
> @@ -4842,7 +4842,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
> static int selinux_shm_alloc_security(struct shmid_kernel *shp)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> int rc;
>
> @@ -4852,7 +4852,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
>
> isec = shp->shm_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = shp->shm_perm.key;
>
> rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
> @@ -4872,12 +4872,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp)
> static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
>
> isec = shp->shm_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = shp->shm_perm.key;
>
> return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
> @@ -4934,7 +4934,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
> static int selinux_sem_alloc_security(struct sem_array *sma)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
> int rc;
>
> @@ -4944,7 +4944,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
>
> isec = sma->sem_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = sma->sem_perm.key;
>
> rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
> @@ -4964,12 +4964,12 @@ static void selinux_sem_free_security(struct sem_array *sma)
> static int selinux_sem_associate(struct sem_array *sma, int semflg)
> {
> struct ipc_security_struct *isec;
> - struct avc_audit_data ad;
> + struct common_audit_data ad;
> u32 sid = current_sid();
>
> isec = sma->sem_perm.security;
>
> - AVC_AUDIT_DATA_INIT(&ad, IPC);
> + COMMON_AUDIT_DATA_INIT(&ad, IPC);
> ad.u.ipc_id = sma->sem_perm.key;
>
> return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
> diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
> index ae4c3a0..e94e82f 100644
> --- a/security/selinux/include/avc.h
> +++ b/security/selinux/include/avc.h
> @@ -13,6 +13,7 @@
> #include <linux/spinlock.h>
> #include <linux/init.h>
> #include <linux/audit.h>
> +#include <linux/lsm_audit.h>
> #include <linux/in6.h>
> #include <linux/path.h>
> #include <asm/system.h>
> @@ -36,48 +37,6 @@ struct inode;
> struct sock;
> struct sk_buff;
>
> -/* Auxiliary data to use in generating the audit record. */
> -struct avc_audit_data {
> - char type;
> -#define AVC_AUDIT_DATA_FS 1
> -#define AVC_AUDIT_DATA_NET 2
> -#define AVC_AUDIT_DATA_CAP 3
> -#define AVC_AUDIT_DATA_IPC 4
> - struct task_struct *tsk;
> - union {
> - struct {
> - struct path path;
> - struct inode *inode;
> - } fs;
> - struct {
> - int netif;
> - struct sock *sk;
> - u16 family;
> - __be16 dport;
> - __be16 sport;
> - union {
> - struct {
> - __be32 daddr;
> - __be32 saddr;
> - } v4;
> - struct {
> - struct in6_addr daddr;
> - struct in6_addr saddr;
> - } v6;
> - } fam;
> - } net;
> - int cap;
> - int ipc_id;
> - } u;
> -};
> -
> -#define v4info fam.v4
> -#define v6info fam.v6
> -
> -/* Initialize an AVC audit data structure. */
> -#define AVC_AUDIT_DATA_INIT(_d,_t) \
> - { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; }
> -
> /*
> * AVC statistics
> */
> @@ -98,7 +57,9 @@ void __init avc_init(void);
>
> void avc_audit(u32 ssid, u32 tsid,
> u16 tclass, u32 requested,
> - struct av_decision *avd, int result, struct avc_audit_data *auditdata);
> + struct av_decision *avd,
> + int result,
> + struct common_audit_data *a);
>
> #define AVC_STRICT 1 /* Ignore permissive mode. */
> int avc_has_perm_noaudit(u32 ssid, u32 tsid,
> @@ -108,7 +69,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
>
> int avc_has_perm(u32 ssid, u32 tsid,
> u16 tclass, u32 requested,
> - struct avc_audit_data *auditdata);
> + struct common_audit_data *auditdata);
>
> u32 avc_policy_seqno(void);
>
> diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
> index b4b5b9b..8d73842 100644
> --- a/security/selinux/include/netlabel.h
> +++ b/security/selinux/include/netlabel.h
> @@ -59,7 +59,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
> int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
> struct sk_buff *skb,
> u16 family,
> - struct avc_audit_data *ad);
> + struct common_audit_data *ad);
> int selinux_netlbl_socket_setsockopt(struct socket *sock,
> int level,
> int optname);
> @@ -129,7 +129,7 @@ static inline int selinux_netlbl_socket_post_create(struct sock *sk,
> static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
> struct sk_buff *skb,
> u16 family,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> return 0;
> }
> diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
> index 289e24b..13128f9 100644
> --- a/security/selinux/include/xfrm.h
> +++ b/security/selinux/include/xfrm.h
> @@ -41,9 +41,9 @@ static inline int selinux_xfrm_enabled(void)
> }
>
> int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
> - struct avc_audit_data *ad);
> + struct common_audit_data *ad);
> int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
> - struct avc_audit_data *ad, u8 proto);
> + struct common_audit_data *ad, u8 proto);
> int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
>
> static inline void selinux_xfrm_notify_policyload(void)
> @@ -57,13 +57,13 @@ static inline int selinux_xfrm_enabled(void)
> }
>
> static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> return 0;
> }
>
> static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
> - struct avc_audit_data *ad, u8 proto)
> + struct common_audit_data *ad, u8 proto)
> {
> return 0;
> }
> diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
> index 2e98441..e688237 100644
> --- a/security/selinux/netlabel.c
> +++ b/security/selinux/netlabel.c
> @@ -342,7 +342,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
> int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
> struct sk_buff *skb,
> u16 family,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> int rc;
> u32 nlbl_sid;
> diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
> index 72b1845..f3cb9ed 100644
> --- a/security/selinux/xfrm.c
> +++ b/security/selinux/xfrm.c
> @@ -401,7 +401,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
> * gone thru the IPSec process.
> */
> int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
> - struct avc_audit_data *ad)
> + struct common_audit_data *ad)
> {
> int i, rc = 0;
> struct sec_path *sp;
> @@ -442,7 +442,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
> * checked in the selinux_xfrm_state_pol_flow_match hook above.
> */
> int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
> - struct avc_audit_data *ad, u8 proto)
> + struct common_audit_data *ad, u8 proto)
> {
> struct dst_entry *dst;
> int rc = 0;
>
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo(a)tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
--
Stephen Smalley
National Security Agency
15 years, 4 months
Gavin Appleton is out of the office.
by Gavin Appleton
I will be out of the office starting 11/08/2009 and will not return until
13/08/2009.
I will respond to your message when I return.
15 years, 4 months