* commit '4336d13cb12a8e779d4c56c45dc6d7a47c0b7898': logd: selinux auditd initial commit
This commit is contained in:
commit
219ed7079a
7 changed files with 639 additions and 2 deletions
|
@ -19,7 +19,9 @@ LOCAL_SRC_FILES := \
|
|||
LogBufferElement.cpp \
|
||||
LogTimes.cpp \
|
||||
LogStatistics.cpp \
|
||||
LogWhiteBlackList.cpp
|
||||
LogWhiteBlackList.cpp \
|
||||
libaudit.c \
|
||||
LogAudit.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libsysutils \
|
||||
|
|
184
logd/LogAudit.cpp
Normal file
184
logd/LogAudit.cpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/klog.h>
|
||||
|
||||
#include "libaudit.h"
|
||||
#include "LogAudit.h"
|
||||
|
||||
LogAudit::LogAudit(LogBuffer *buf, LogReader *reader)
|
||||
: SocketListener(getLogSocket(), false)
|
||||
, logbuf(buf)
|
||||
, reader(reader) {
|
||||
logDmsg();
|
||||
}
|
||||
|
||||
bool LogAudit::onDataAvailable(SocketClient *cli) {
|
||||
struct audit_message rep;
|
||||
|
||||
if (audit_get_reply(cli->getSocket(), &rep, GET_REPLY_BLOCKING, 0) < 0) {
|
||||
SLOGE("Failed on audit_get_reply with error: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define AUDIT_LOG_ID LOG_ID_MAIN
|
||||
#define AUDIT_LOG_PRIO ANDROID_LOG_WARN
|
||||
|
||||
int LogAudit::logPrint(const char *fmt, ...) {
|
||||
if (fmt == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
|
||||
char *str = NULL;
|
||||
va_start(args, fmt);
|
||||
int rc = vasprintf(&str, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pid_t pid = getpid();
|
||||
pid_t tid = gettid();
|
||||
uid_t uid = getuid();
|
||||
log_time now;
|
||||
|
||||
static const char audit_str[] = " audit(";
|
||||
char *timeptr = strstr(str, audit_str);
|
||||
char *cp;
|
||||
if (timeptr
|
||||
&& ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q")))
|
||||
&& (*cp == ':')) {
|
||||
memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3);
|
||||
strcpy(timeptr + sizeof(audit_str) - 1 + 3, cp);
|
||||
} else {
|
||||
now.strptime("", ""); // side effect of setting CLOCK_REALTIME
|
||||
}
|
||||
|
||||
static const char pid_str[] = " pid=";
|
||||
char *pidptr = strstr(str, pid_str);
|
||||
if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) {
|
||||
cp = pidptr + sizeof(pid_str) - 1;
|
||||
pid = 0;
|
||||
while (isdigit(*cp)) {
|
||||
pid = (pid * 10) + (*cp - '0');
|
||||
++cp;
|
||||
}
|
||||
tid = pid;
|
||||
uid = logbuf->pidToUid(pid);
|
||||
strcpy(pidptr, cp);
|
||||
}
|
||||
|
||||
static const char comm_str[] = " comm=\"";
|
||||
char *comm = strstr(str, comm_str);
|
||||
if (comm) {
|
||||
cp = comm;
|
||||
comm += sizeof(comm_str) - 1;
|
||||
char *ecomm = strchr(comm, '"');
|
||||
if (ecomm) {
|
||||
*ecomm = '\0';
|
||||
}
|
||||
comm = strdup(comm);
|
||||
if (ecomm) {
|
||||
strcpy(cp, ecomm + 1);
|
||||
}
|
||||
} else if (pid == getpid()) {
|
||||
pid = tid;
|
||||
comm = strdup("auditd");
|
||||
} else if (!(comm = logbuf->pidToName(pid))) {
|
||||
comm = strdup("unknown");
|
||||
}
|
||||
|
||||
size_t l = strlen(comm) + 1;
|
||||
size_t n = l + strlen(str) + 2;
|
||||
|
||||
char *newstr = reinterpret_cast<char *>(malloc(n));
|
||||
if (!newstr) {
|
||||
free(comm);
|
||||
free(str);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*newstr = AUDIT_LOG_PRIO;
|
||||
strcpy(newstr + 1, comm);
|
||||
free(comm);
|
||||
strcpy(newstr + 1 + l, str);
|
||||
free(str);
|
||||
|
||||
unsigned short len = n; // cap to internal maximum
|
||||
if (len != n) {
|
||||
len = -1;
|
||||
}
|
||||
logbuf->log(AUDIT_LOG_ID, now, uid, pid, tid, newstr, len);
|
||||
reader->notifyNewLog();
|
||||
|
||||
free(newstr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void LogAudit::logDmsg() {
|
||||
int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
|
||||
if (len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
len++;
|
||||
char buf[len];
|
||||
|
||||
int rc = klogctl(KLOG_READ_ALL, buf, len);
|
||||
|
||||
buf[len - 1] = '\0';
|
||||
|
||||
for(char *tok = buf; (rc >= 0) && ((tok = strtok(tok, "\r\n"))); tok = NULL) {
|
||||
char *audit = strstr(tok, " audit(");
|
||||
if (!audit) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*audit++ = '\0';
|
||||
|
||||
char *type = strstr(tok, "type=");
|
||||
if (type) {
|
||||
rc = logPrint("%s %s", type, audit);
|
||||
} else {
|
||||
rc = logPrint("%s", audit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LogAudit::getLogSocket() {
|
||||
int fd = audit_open();
|
||||
if (fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) {
|
||||
audit_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
40
logd/LogAudit.h
Normal file
40
logd/LogAudit.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LOGD_LOG_AUDIT_H__
|
||||
#define _LOGD_LOG_AUDIT_H__
|
||||
|
||||
#include <sysutils/SocketListener.h>
|
||||
#include "LogReader.h"
|
||||
|
||||
class LogAudit : public SocketListener {
|
||||
LogBuffer *logbuf;
|
||||
LogReader *reader;
|
||||
|
||||
public:
|
||||
LogAudit(LogBuffer *buf, LogReader *reader);
|
||||
|
||||
protected:
|
||||
virtual bool onDataAvailable(SocketClient *cli);
|
||||
|
||||
private:
|
||||
static int getLogSocket();
|
||||
void logDmsg();
|
||||
int logPrint(const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
};
|
||||
|
||||
#endif
|
17
logd/README.auditd
Normal file
17
logd/README.auditd
Normal file
|
@ -0,0 +1,17 @@
|
|||
Auditd Daemon
|
||||
|
||||
The audit daemon is a simplified version of its desktop
|
||||
counterpart designed to gather the audit logs from the
|
||||
audit kernel subsystem. The audit subsystem of the kernel
|
||||
includes Linux Security Modules (LSM) messages as well.
|
||||
|
||||
To enable the audit subsystem, you must add this to your
|
||||
kernel config:
|
||||
CONFIG_AUDIT=y
|
||||
|
||||
To enable a LSM, you must consult that LSM's documentation, the
|
||||
example below is for SELinux:
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
|
||||
This does not include possible dependencies that may need to be
|
||||
satisfied for that particular LSM.
|
276
logd/libaudit.c
Normal file
276
logd/libaudit.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Copyright 2012, Samsung Telecommunications of America
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Written by William Roberts <w.roberts@sta.samsung.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LOG_TAG "libaudit"
|
||||
#include <log/log.h>
|
||||
|
||||
#include "libaudit.h"
|
||||
|
||||
/**
|
||||
* Waits for an ack from the kernel
|
||||
* @param fd
|
||||
* The netlink socket fd
|
||||
* @param seq
|
||||
* The current sequence number were acking on
|
||||
* @return
|
||||
* This function returns 0 on success, else -errno.
|
||||
*/
|
||||
static int get_ack(int fd, int16_t seq)
|
||||
{
|
||||
int rc;
|
||||
struct audit_message rep;
|
||||
|
||||
/* Sanity check, this is an internal interface this shouldn't happen */
|
||||
if (fd < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, MSG_PEEK);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rep.nlh.nlmsg_type == NLMSG_ERROR) {
|
||||
audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, 0);
|
||||
rc = ((struct nlmsgerr *)rep.data)->error;
|
||||
if (rc) {
|
||||
return -rc;
|
||||
}
|
||||
}
|
||||
|
||||
if ((int16_t)rep.nlh.nlmsg_seq != seq) {
|
||||
SLOGW("Expected sequence number between user space and kernel space is out of skew, "
|
||||
"expected %u got %u", seq, rep.nlh.nlmsg_seq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fd
|
||||
* The netlink socket fd
|
||||
* @param type
|
||||
* The type of netlink message
|
||||
* @param data
|
||||
* The data to send
|
||||
* @param size
|
||||
* The length of the data in bytes
|
||||
* @return
|
||||
* This function returns a positive sequence number on success, else -errno.
|
||||
*/
|
||||
static int audit_send(int fd, int type, const void *data, size_t size)
|
||||
{
|
||||
int rc;
|
||||
static int16_t sequence = 0;
|
||||
struct audit_message req;
|
||||
struct sockaddr_nl addr;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
/* We always send netlink messaged */
|
||||
addr.nl_family = AF_NETLINK;
|
||||
|
||||
/* Set up the netlink headers */
|
||||
req.nlh.nlmsg_type = type;
|
||||
req.nlh.nlmsg_len = NLMSG_SPACE(size);
|
||||
req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
|
||||
/*
|
||||
* Check for a valid fd, even though sendto would catch this, its easier
|
||||
* to always blindly increment the sequence number
|
||||
*/
|
||||
if (fd < 0) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* Ensure the message is not too big */
|
||||
if (NLMSG_SPACE(size) > MAX_AUDIT_MESSAGE_LENGTH) {
|
||||
SLOGE("netlink message is too large");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Only memcpy in the data if it was specified */
|
||||
if (size && data) {
|
||||
memcpy(NLMSG_DATA(&req.nlh), data, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only increment the sequence number on a guarantee
|
||||
* you will send it to the kernel.
|
||||
*
|
||||
* Also, the sequence is defined as a u32 in the kernel
|
||||
* struct. Using an int here might not work on 32/64 bit splits. A
|
||||
* signed 64 bit value can overflow a u32..but a u32
|
||||
* might not fit in the response, so we need to use s32.
|
||||
* Which is still kind of hackish since int could be 16 bits
|
||||
* in size. The only safe type to use here is a signed 16
|
||||
* bit value.
|
||||
*/
|
||||
req.nlh.nlmsg_seq = ++sequence;
|
||||
|
||||
/* While failing and its due to interrupts */
|
||||
|
||||
rc = TEMP_FAILURE_RETRY(sendto(fd, &req, req.nlh.nlmsg_len, 0,
|
||||
(struct sockaddr*) &addr, sizeof(addr)));
|
||||
|
||||
/* Not all the bytes were sent */
|
||||
if (rc < 0) {
|
||||
rc = -errno;
|
||||
SLOGE("Error sending data over the netlink socket: %s", strerror(-errno));
|
||||
goto out;
|
||||
} else if ((uint32_t) rc != req.nlh.nlmsg_len) {
|
||||
rc = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* We sent all the bytes, get the ack */
|
||||
rc = get_ack(fd, sequence);
|
||||
|
||||
/* If the ack failed, return the error, else return the sequence number */
|
||||
rc = (rc == 0) ? (int) sequence : rc;
|
||||
|
||||
out:
|
||||
/* Don't let sequence roll to negative */
|
||||
if (sequence < 0) {
|
||||
SLOGW("Auditd to Kernel sequence number has rolled over");
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
|
||||
{
|
||||
int rc;
|
||||
struct audit_message rep;
|
||||
struct audit_status status;
|
||||
|
||||
memset(&status, 0, sizeof(status));
|
||||
|
||||
/*
|
||||
* In order to set the auditd PID we send an audit message over the netlink
|
||||
* socket with the pid field of the status struct set to our current pid,
|
||||
* and the the mask set to AUDIT_STATUS_PID
|
||||
*/
|
||||
status.pid = pid;
|
||||
status.mask = AUDIT_STATUS_PID;
|
||||
|
||||
/* Let the kernel know this pid will be registering for audit events */
|
||||
rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
|
||||
if (rc < 0) {
|
||||
SLOGE("Could net set pid for audit events, error: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* In a request where we need to wait for a response, wait for the message
|
||||
* and discard it. This message confirms and sync's us with the kernel.
|
||||
* This daemon is now registered as the audit logger. Only wait if the
|
||||
* wmode is != WAIT_NO
|
||||
*/
|
||||
if (wmode != WAIT_NO) {
|
||||
/* TODO
|
||||
* If the daemon dies and restarts the message didn't come back,
|
||||
* so I went to non-blocking and it seemed to fix the bug.
|
||||
* Need to investigate further.
|
||||
*/
|
||||
audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audit_open()
|
||||
{
|
||||
return socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
|
||||
}
|
||||
|
||||
int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek)
|
||||
{
|
||||
ssize_t len;
|
||||
int flags;
|
||||
int rc = 0;
|
||||
|
||||
struct sockaddr_nl nladdr;
|
||||
socklen_t nladdrlen = sizeof(nladdr);
|
||||
|
||||
if (fd < 0) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
/* Set up the flags for recv from */
|
||||
flags = (block == GET_REPLY_NONBLOCKING) ? MSG_DONTWAIT : 0;
|
||||
flags |= peek;
|
||||
|
||||
/*
|
||||
* Get the data from the netlink socket but on error we need to be carefull,
|
||||
* the interface shows that EINTR can never be returned, other errors,
|
||||
* however, can be returned.
|
||||
*/
|
||||
len = TEMP_FAILURE_RETRY(recvfrom(fd, rep, sizeof(*rep), flags,
|
||||
(struct sockaddr*) &nladdr, &nladdrlen));
|
||||
|
||||
/*
|
||||
* EAGAIN should be re-tried until success or another error manifests.
|
||||
*/
|
||||
if (len < 0) {
|
||||
rc = -errno;
|
||||
if (block == GET_REPLY_NONBLOCKING && rc == -EAGAIN) {
|
||||
/* If request is non blocking and errno is EAGAIN, just return 0 */
|
||||
return 0;
|
||||
}
|
||||
SLOGE("Error receiving from netlink socket, error: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (nladdrlen != sizeof(nladdr)) {
|
||||
SLOGE("Protocol fault, error: %s", strerror(EPROTO));
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
/* Make sure the netlink message was not spoof'd */
|
||||
if (nladdr.nl_pid) {
|
||||
SLOGE("Invalid netlink pid received, expected 0 got: %d", nladdr.nl_pid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if the reply from the kernel was ok */
|
||||
if (!NLMSG_OK(&rep->nlh, (size_t)len)) {
|
||||
rc = (len == sizeof(*rep)) ? -EFBIG : -EBADE;
|
||||
SLOGE("Bad kernel response %s", strerror(-rc));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void audit_close(int fd)
|
||||
{
|
||||
int rc = close(fd);
|
||||
if (rc < 0) {
|
||||
SLOGE("Attempting to close invalid fd %d, error: %s", fd, strerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
104
logd/libaudit.h
Normal file
104
logd/libaudit.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright 2012, Samsung Telecommunications of America
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Written by William Roberts <w.roberts@sta.samsung.com>
|
||||
*/
|
||||
|
||||
#ifndef _LIBAUDIT_H_
|
||||
#define _LIBAUDIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define MAX_AUDIT_MESSAGE_LENGTH 8970
|
||||
|
||||
typedef enum {
|
||||
GET_REPLY_BLOCKING=0,
|
||||
GET_REPLY_NONBLOCKING
|
||||
} reply_t;
|
||||
|
||||
typedef enum {
|
||||
WAIT_NO,
|
||||
WAIT_YES
|
||||
} rep_wait_t;
|
||||
|
||||
/* type == AUDIT_SIGNAL_INFO */
|
||||
struct audit_sig_info {
|
||||
uid_t uid;
|
||||
pid_t pid;
|
||||
char ctx[0];
|
||||
};
|
||||
|
||||
struct audit_message {
|
||||
struct nlmsghdr nlh;
|
||||
char data[MAX_AUDIT_MESSAGE_LENGTH];
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens a connection to the Audit netlink socket
|
||||
* @return
|
||||
* A valid fd on success or < 0 on error with errno set.
|
||||
* Returns the same errors as man 2 socket.
|
||||
*/
|
||||
extern int audit_open(void);
|
||||
|
||||
/**
|
||||
* Closes the fd returned from audit_open()
|
||||
* @param fd
|
||||
* The fd to close
|
||||
*/
|
||||
extern void audit_close(int fd);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fd
|
||||
* The fd returned by a call to audit_open()
|
||||
* @param rep
|
||||
* The response struct to store the response in.
|
||||
* @param block
|
||||
* Whether or not to block on IO
|
||||
* @param peek
|
||||
* Whether or not we are to remove the message from
|
||||
* the queue when we do a read on the netlink socket.
|
||||
* @return
|
||||
* This function returns 0 on success, else -errno.
|
||||
*/
|
||||
extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block,
|
||||
int peek);
|
||||
|
||||
/**
|
||||
* Sets a pid to recieve audit netlink events from the kernel
|
||||
* @param fd
|
||||
* The fd returned by a call to audit_open()
|
||||
* @param pid
|
||||
* The pid whom to set as the reciever of audit messages
|
||||
* @param wmode
|
||||
* Whether or not to block on the underlying socket io calls.
|
||||
* @return
|
||||
* This function returns 0 on success, -errno on error.
|
||||
*/
|
||||
extern int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include "CommandListener.h"
|
||||
#include "LogBuffer.h"
|
||||
#include "LogListener.h"
|
||||
#include "LogAudit.h"
|
||||
|
||||
static int drop_privs() {
|
||||
struct sched_param param;
|
||||
|
@ -63,7 +64,10 @@ static int drop_privs() {
|
|||
capheader.pid = 0;
|
||||
|
||||
capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
|
||||
capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
|
||||
capdata[CAP_TO_INDEX(CAP_AUDIT_CONTROL)].permitted |= CAP_TO_MASK(CAP_AUDIT_CONTROL);
|
||||
|
||||
capdata[0].effective = capdata[0].permitted;
|
||||
capdata[1].effective = capdata[1].permitted;
|
||||
capdata[0].inheritable = 0;
|
||||
capdata[1].inheritable = 0;
|
||||
|
||||
|
@ -127,6 +131,16 @@ int main() {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// LogAudit listens on NETLINK_AUDIT socket for selinux
|
||||
// initiated log messages. New log entries are added to LogBuffer
|
||||
// and LogReader is notified to send updates to connected clients.
|
||||
|
||||
// failure is an option ... messages are in dmesg (required by standard)
|
||||
LogAudit *al = new LogAudit(logBuf, reader);
|
||||
if (al->startListener()) {
|
||||
delete al;
|
||||
}
|
||||
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue