+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 __RUNTIME_NETLINK_AUDIT_RULE_H__
-#define __RUNTIME_NETLINK_AUDIT_RULE_H__
-
-#include <vector>
-
-#include <linux/audit.h>
-
-#include <klay/klay.h>
-
-namespace netlink {
-
-class KLAY_EXPORT AuditRule final {
-public:
- AuditRule();
- AuditRule(std::vector<char>& buf);
- ~AuditRule();
-
- void setSystemCall(unsigned int syscall);
- void unsetSystemCall(unsigned int syscall);
- void setAllSystemCalls();
- void clearAllSystemCalls();
- std::vector<unsigned int> getSystemCalls() const;
-
- void setReturn(unsigned int val);
- void unsetReturn();
- unsigned int getReturn() const;
- bool hasReturn() const;
-
- void setKey(const std::string &name);
- void unsetKey();
- const std::string getkey() const;
- bool hasKey() const;
-
- const char *data() const
- {
- return buf.data();
- }
-
- unsigned int size() const
- {
- return buf.size();
- }
-
-private:
- std::vector<char> buf;
-};
-
-} // namespace runtime
-
-#endif //!__RUNTIME_NETLINK_AUDIT_RULE_H__
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 __RUNTIME_NETLINK_AUDIT_H__
-#define __RUNTIME_NETLINK_AUDIT_H__
-
-#include <list>
-#include <vector>
-
-#include <linux/audit.h>
-
-#include <klay/klay.h>
-#include <klay/mainloop.h>
-#include <klay/netlink/netlink.h>
-#include <klay/netlink/audit-rule.h>
-
-namespace netlink {
-
-class KLAY_EXPORT Audit final {
-public:
- typedef std::pair<int, std::vector<char>> Message;
- typedef std::function<void(Message&)> MessageHandler;
-
- Audit();
- Audit(Audit&&);
- Audit(const Audit&) = delete;
- ~Audit();
-
- Audit& operator=(const Audit&) = delete;
-
- void setPID(pid_t pid);
- void setEnabled(int enabled);
- int isEnabled();
-
- std::vector<AuditRule> getRules();
- void addRule(const AuditRule& rule);
- void removeRule(const AuditRule& rule);
-
- void setMainloop(runtime::Mainloop *ml);
- void setMessageHandler(MessageHandler&& handler);
-
-private:
- void send(int type, const void *data, unsigned int size);
- Message recv(int options = 0);
-
- void processMessage(int fd, runtime::Mainloop::Event event);
-
- Netlink nl;
- unsigned int sequence = 0;
- runtime::Mainloop *mainloop;
- MessageHandler messageHandler;
-};
-
-} // namespace runtime
-
-#endif //!__RUNTIME_NETLINK_AUDIT_H__
${KLAY_SRC}/audit/console-sink.cpp
${KLAY_SRC}/audit/dlog-sink.cpp
${KLAY_SRC}/audit/audit-trail.cpp
- ${KLAY_SRC}/netlink/audit.cpp
${KLAY_SRC}/netlink/netlink.cpp
- ${KLAY_SRC}/netlink/audit-rule.cpp
)
SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <klay/error.h>
-#include <klay/exception.h>
-
-#include <klay/netlink/audit-rule.h>
-
-namespace netlink {
-
-AuditRule::AuditRule() :
- buf(sizeof(struct audit_rule_data))
-{
- auto r = (struct audit_rule_data *)buf.data();
- r->flags = AUDIT_FILTER_EXIT;
- r->action = AUDIT_ALWAYS;
-}
-
-AuditRule::AuditRule(std::vector<char> &buf) :
- buf(buf)
-{
-}
-
-AuditRule::~AuditRule()
-{
-}
-
-void AuditRule::setSystemCall(unsigned int syscall)
-{
- auto r = (struct audit_rule_data *)buf.data();
- r->mask[syscall / 32] |= 1 << (syscall % 32);
-}
-
-void AuditRule::unsetSystemCall(unsigned int syscall)
-{
- auto r = (struct audit_rule_data *)buf.data();
- r->mask[syscall / 32] &= ~(1 << (syscall % 32));
-}
-
-void AuditRule::setAllSystemCalls()
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (auto &m : r->mask) {
- m = 0xffffffff;
- }
-}
-
-void AuditRule::clearAllSystemCalls()
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (auto &m : r->mask) {
- m = 0;
- }
-}
-
-std::vector<unsigned int> AuditRule::getSystemCalls() const
-{
- auto r = (struct audit_rule_data *)buf.data();
- std::vector<unsigned int> ret;
-
- for (int i = 0; i < AUDIT_BITMASK_SIZE; i++) {
- for (int j = 0, k = 1; j < 32; j++, k <<= 1) {
- if (r->mask[i] & k) {
- ret.push_back(i << 5 | j);
- }
- }
- }
- return ret;
-}
-
-void AuditRule::setReturn(unsigned int val)
-{
- auto r = (struct audit_rule_data *)buf.data();
- unsigned int i;
-
- for (i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_EXIT) {
- break;
- }
- }
- if (i == r->field_count) {
- r->fields[i] = AUDIT_EXIT;
- r->fieldflags[i] = AUDIT_EQUAL;
- r->field_count++;
- }
- r->values[i] = val;
-}
-
-void AuditRule::unsetReturn()
-{
- auto r = (struct audit_rule_data *)buf.data();
- unsigned int i;
-
- for (i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_EXIT) {
- break;
- }
- }
-
- if (i == r->field_count) {
- return;
- }
-
- std::move(&r->values[i + 1], &r->values[r->field_count], &r->values[i]);
- std::move(&r->fields[i + 1], &r->fields[r->field_count], &r->fields[i]);
- std::move(&r->fieldflags[i + 1], &r->fieldflags[r->field_count], &r->fieldflags[i]);
-
- r->field_count--;
-
- r->values[r->field_count] = 0;
- r->fields[r->field_count] = 0;
- r->fieldflags[r->field_count] = 0;
-}
-
-unsigned int AuditRule::getReturn() const
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (unsigned int i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_EXIT) {
- return r->values[i];
- }
- }
- throw runtime::Exception("No rule for return");
-}
-
-bool AuditRule::hasReturn() const
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (unsigned int i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_EXIT) {
- return true;
- }
- }
- return false;
-}
-
-void AuditRule::setKey(const std::string &name)
-{
- auto r = (struct audit_rule_data *)buf.data();
- unsigned int i;
-
- for (i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_FILTERKEY) {
- break;
- }
- }
-
- if (i == r->field_count) {
- r->fields[i] = AUDIT_FILTERKEY;
- r->fieldflags[i] = AUDIT_EQUAL;
- r->field_count++;
- }
-
- // TODO : Calculate the offset. It assummed that there is no field to use buffer
-
- r->values[i] = name.size();
- r->buflen = name.size();
-
- buf.resize(sizeof(struct audit_rule_data) + name.size());
- r = (struct audit_rule_data *)buf.data();
- std::copy(name.begin(), name.end(), r->buf);
-}
-
-void AuditRule::unsetKey()
-{
- auto r = (struct audit_rule_data *)buf.data();
- unsigned int i;
-
- for (i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_FILTERKEY) {
- break;
- }
- }
-
- if (i == r->field_count) {
- return;
- }
-
- std::move(&r->values[i + 1], &r->values[r->field_count], &r->values[i]);
- std::move(&r->fields[i + 1], &r->fields[r->field_count], &r->fields[i]);
- std::move(&r->fieldflags[i + 1], &r->fieldflags[r->field_count], &r->fieldflags[i]);
-
- r->field_count--;
-
- r->values[r->field_count] = 0;
- r->fields[r->field_count] = 0;
- r->fieldflags[r->field_count] = 0;
-}
-
-const std::string AuditRule::getkey() const
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (unsigned int i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_FILTERKEY) {
- // TODO : Calculate the offset. It assummed that there is no field to use buffer
- return r->buf;
- }
- }
-
- throw runtime::Exception("No rule for key");
-}
-
-bool AuditRule::hasKey() const
-{
- auto r = (struct audit_rule_data *)buf.data();
- for (unsigned int i = 0; i < r->field_count; i++) {
- if (r->fields[i] == AUDIT_FILTERKEY) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace runtime
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <poll.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/socket.h>
-
-#include <cstring>
-
-#include <klay/error.h>
-#include <klay/exception.h>
-
-#include <klay/netlink/audit.h>
-
-using namespace std::placeholders;
-
-namespace netlink {
-
-Audit::Audit() :
- nl(NETLINK_AUDIT), sequence(0), mainloop(nullptr)
-{
-}
-
-Audit::Audit(Audit&& audit) :
- nl(std::move(audit.nl)), sequence(audit.sequence), mainloop(audit.mainloop)
-{
-}
-
-Audit::~Audit()
-{
-}
-
-void Audit::setPID(pid_t pid)
-{
- struct audit_status s;
-
- ::memset(&s, 0, sizeof(s));
- s.mask = AUDIT_STATUS_PID;
- s.pid = pid;
-
- send(AUDIT_SET, &s, sizeof(s));
-}
-
-void Audit::setEnabled(int enabled)
-{
- struct audit_status s;
-
- ::memset(&s, 0, sizeof(s));
- s.mask = AUDIT_STATUS_ENABLED;
- s.enabled = enabled;
-
- send(AUDIT_SET, &s, sizeof(s));
-}
-
-int Audit::isEnabled()
-{
- int ret = 0;
- send(AUDIT_GET, NULL, 0);
-
- while (1) {
- auto msg = recv();
-
- switch (msg.first) {
- case NLMSG_DONE:
- case NLMSG_ERROR:
- throw runtime::Exception("Failed to get audit state");
- case AUDIT_GET:
- ret = ((struct audit_status*)msg.second.data())->enabled;
- break;
- default:
- continue;
- }
-
- break;
- }
-
- return ret;
-}
-
-std::vector<AuditRule> Audit::getRules()
-{
- std::vector<AuditRule> ret;
-
- send(AUDIT_LIST_RULES, NULL, 0);
-
- while (1) {
- auto msg = recv();
-
- switch (msg.first) {
- case NLMSG_DONE:
- break;
- case NLMSG_ERROR:
- throw runtime::Exception("Failed to get a list of audit rules");
- case AUDIT_LIST_RULES:
- ret.push_back(msg.second);
- default:
- continue;
- }
-
- break;
- }
- return ret;
-}
-
-void Audit::addRule(const AuditRule& rule)
-{
- send(AUDIT_ADD_RULE, rule.data(), rule.size());
-}
-
-void Audit::removeRule(const AuditRule& rule)
-{
- send(AUDIT_DEL_RULE, rule.data(), rule.size());
-}
-
-void Audit::setMainloop(runtime::Mainloop *ml)
-{
- int fd = nl.getFd();
-
- if (mainloop != nullptr) {
- mainloop->removeEventSource(fd);
- }
- mainloop = ml;
- mainloop->addEventSource(fd, POLLIN, std::bind(&Audit::processMessage,
- this, _1, _2));
-}
-
-void Audit::setMessageHandler(MessageHandler&& handler)
-{
- messageHandler = handler;
-}
-
-void Audit::send(int type, const void *data, unsigned int size)
-{
- char buf[NLMSG_SPACE(size)];
- auto *nlh = (struct nlmsghdr *)buf;
-
- ::memset(buf, 0, sizeof(buf));
-
- nlh->nlmsg_len = sizeof(buf);
- nlh->nlmsg_type = type;
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- nlh->nlmsg_seq = ++sequence;
-
- if (sequence == 0) {
- sequence++;
- }
-
- if (size && data) {
- ::memcpy(NLMSG_DATA(buf), data, size);
- }
-
- nl.send(buf, sizeof(buf));
-
- if (recv(MSG_PEEK).first == NLMSG_ERROR) {
- auto reply = recv().second;
- auto err = (struct nlmsgerr*)reply.data();
- if (err->error) {
- throw runtime::Exception("Audit netlink error: " +
- std::to_string(err->error));
- }
- }
-}
-
-Audit::Message Audit::recv(int options)
-{
- struct nlmsghdr nlh;
-
- processMessage(nl.getFd(), POLLIN);
-
- //To get message size
- nl.recv(&nlh, sizeof(nlh), options | MSG_PEEK);
-
- char buf[nlh.nlmsg_len + NLMSG_HDRLEN];
- nl.recv(buf, sizeof(buf), options);
-
- Message msg = {nlh.nlmsg_type, std::vector<char>(nlh.nlmsg_len)};
-
- ::memcpy(msg.second.data(), NLMSG_DATA(buf), msg.second.size());
- return msg;
-}
-
-void Audit::processMessage(int fd, runtime::Mainloop::Event event)
-{
- struct nlmsghdr nlh;
-
- nl.recv(&nlh, sizeof(nlh), MSG_PEEK);
-
- while (nlh.nlmsg_seq == 0) {
- char buf[nlh.nlmsg_len + NLMSG_HDRLEN];
- nl.recv(buf, sizeof(buf));
-
- Message msg = {nlh.nlmsg_type, std::vector<char>(nlh.nlmsg_len)};
-
- ::memcpy(msg.second.data(), NLMSG_DATA(buf), msg.second.size());
- if (messageHandler) {
- messageHandler(msg);
- }
-
- try {
- nl.recv(&nlh, sizeof(nlh), MSG_PEEK | MSG_DONTWAIT);
- } catch (runtime::Exception &e) {
- break;
- }
- }
-}
-
-} // namespace runtime