mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-08 02:18:53 +00:00
Merge pull request #425 from theopolis/feature-catching-exceptions
Fix unwind exception catching
This commit is contained in:
commit
c0dc2720fb
@ -11,17 +11,19 @@
|
||||
|
||||
#include "osquery/database/results.h"
|
||||
|
||||
#ifndef STR
|
||||
#define STR_OF(x) #x
|
||||
#define STR(x) STR_OF(x)
|
||||
#endif
|
||||
|
||||
namespace osquery {
|
||||
|
||||
/**
|
||||
* @brief The version of osquery
|
||||
*/
|
||||
extern const std::string kVersion;
|
||||
|
||||
/// Use a macro for the version literal, set the kVersion symbol in the library.
|
||||
#ifndef STR
|
||||
#define STR_OF(x) #x
|
||||
#define STR(x) STR_OF(x)
|
||||
#endif
|
||||
#define OSQUERY_VERSION STR(OSQUERY_BUILD_VERSION)
|
||||
|
||||
/**
|
||||
|
@ -223,13 +223,6 @@ class DBHandle {
|
||||
*/
|
||||
rocksdb::ColumnFamilyHandle* getHandleForColumnFamily(const std::string& cf);
|
||||
|
||||
/**
|
||||
* @brief Determine if a DBInstance can be created for the requested env.
|
||||
*
|
||||
* @return an estimate of a sane environment as an exception.
|
||||
*/
|
||||
static void requireInstance(const std::string& path, bool in_memory);
|
||||
|
||||
private:
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Private members
|
||||
|
@ -18,6 +18,7 @@ SET(OSQUERY_APPLE_LIBS
|
||||
glog
|
||||
)
|
||||
|
||||
# Warning: Do not statically compile unwind
|
||||
SET(OSQUERY_LINUX_LIBS
|
||||
libgflags.a
|
||||
libglog.a
|
||||
@ -28,6 +29,7 @@ SET(OSQUERY_LINUX_LIBS
|
||||
libboost_filesystem.a
|
||||
libboost_program_options.a
|
||||
libboost_regex.a
|
||||
unwind
|
||||
udev
|
||||
blkid
|
||||
rt
|
||||
@ -37,7 +39,6 @@ SET(OSQUERY_UBUNTU_LIBS
|
||||
libz.a
|
||||
libbz2.a
|
||||
libsnappy.a
|
||||
libunwind.a
|
||||
liblzma.a
|
||||
)
|
||||
|
||||
@ -45,7 +46,6 @@ SET(OSQUERY_CENTOS_LIBS
|
||||
libz.so
|
||||
libbz2.so
|
||||
libsnappy.so
|
||||
libunwind.so
|
||||
liblzma.so
|
||||
libproc.so
|
||||
)
|
||||
|
@ -44,6 +44,16 @@ DBHandle::DBHandle(const std::string& path, bool in_memory) {
|
||||
options_.create_if_missing = true;
|
||||
options_.create_missing_column_families = true;
|
||||
|
||||
if (in_memory) {
|
||||
// Remove when upgrading to RocksDB 3.3
|
||||
// options_.env = rocksdb::NewMemEnv(rocksdb::Env::Default());
|
||||
throw std::domain_error("Required RocksDB 3.3 (and setMemEnv)");
|
||||
}
|
||||
|
||||
if (pathExists(path).ok() && !isWritable(path).ok()) {
|
||||
throw std::domain_error("Cannot write to RocksDB path: " + path);
|
||||
}
|
||||
|
||||
column_families_.push_back(rocksdb::ColumnFamilyDescriptor(
|
||||
rocksdb::kDefaultColumnFamilyName, rocksdb::ColumnFamilyOptions()));
|
||||
|
||||
@ -56,18 +66,6 @@ DBHandle::DBHandle(const std::string& path, bool in_memory) {
|
||||
rocksdb::DB::Open(options_, path, column_families_, &handles_, &db_);
|
||||
}
|
||||
|
||||
void DBHandle::requireInstance(const std::string& path, bool in_memory) {
|
||||
if (in_memory) {
|
||||
// Remove when upgrading to RocksDB 3.3
|
||||
// options_.env = rocksdb::NewMemEnv(rocksdb::Env::Default());
|
||||
throw std::domain_error("Required RocksDB 3.3 (and setMemEnv)");
|
||||
}
|
||||
|
||||
if (pathExists(path).ok() && !isWritable(path).ok()) {
|
||||
throw std::domain_error("Cannot write to RocksDB path: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
DBHandle::~DBHandle() {
|
||||
for (auto handle : handles_) {
|
||||
delete handle;
|
||||
@ -92,14 +90,6 @@ std::shared_ptr<DBHandle> DBHandle::getInstanceAtPath(const std::string& path) {
|
||||
|
||||
std::shared_ptr<DBHandle> DBHandle::getInstance(const std::string& path,
|
||||
bool in_memory) {
|
||||
static bool valid_instance = false;
|
||||
if (!valid_instance) {
|
||||
// Throw any possible exceptions before the accessor.
|
||||
// Workaround for issue #423
|
||||
requireInstance(path, in_memory);
|
||||
valid_instance = true;
|
||||
}
|
||||
|
||||
static std::shared_ptr<DBHandle> db_handle =
|
||||
std::shared_ptr<DBHandle>(new DBHandle(path, in_memory));
|
||||
return db_handle;
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sqlite3.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
137
osquery/tables/networking/linux/inet_diag.h
Normal file
137
osquery/tables/networking/linux/inet_diag.h
Normal file
@ -0,0 +1,137 @@
|
||||
#ifndef _UAPI_INET_DIAG_H_
|
||||
#define _UAPI_INET_DIAG_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Just some random number */
|
||||
#define TCPDIAG_GETSOCK 18
|
||||
#define DCCPDIAG_GETSOCK 19
|
||||
|
||||
#define INET_DIAG_GETSOCK_MAX 24
|
||||
|
||||
/* Socket identity */
|
||||
struct inet_diag_sockid {
|
||||
__be16 idiag_sport;
|
||||
__be16 idiag_dport;
|
||||
__be32 idiag_src[4];
|
||||
__be32 idiag_dst[4];
|
||||
__u32 idiag_if;
|
||||
__u32 idiag_cookie[2];
|
||||
#define INET_DIAG_NOCOOKIE (~0U)
|
||||
};
|
||||
|
||||
/* Request structure */
|
||||
|
||||
struct inet_diag_req {
|
||||
__u8 idiag_family; /* Family of addresses. */
|
||||
__u8 idiag_src_len;
|
||||
__u8 idiag_dst_len;
|
||||
__u8 idiag_ext; /* Query extended information */
|
||||
|
||||
struct inet_diag_sockid id;
|
||||
|
||||
__u32 idiag_states; /* States to dump */
|
||||
__u32 idiag_dbs; /* Tables to dump (NI) */
|
||||
};
|
||||
|
||||
struct inet_diag_req_v2 {
|
||||
__u8 sdiag_family;
|
||||
__u8 sdiag_protocol;
|
||||
__u8 idiag_ext;
|
||||
__u8 pad;
|
||||
__u32 idiag_states;
|
||||
struct inet_diag_sockid id;
|
||||
};
|
||||
|
||||
enum {
|
||||
INET_DIAG_REQ_NONE,
|
||||
INET_DIAG_REQ_BYTECODE,
|
||||
};
|
||||
|
||||
#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
|
||||
|
||||
/* Bytecode is sequence of 4 byte commands followed by variable arguments.
|
||||
* All the commands identified by "code" are conditional jumps forward:
|
||||
* to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be
|
||||
* length of the command and its arguments.
|
||||
*/
|
||||
|
||||
struct inet_diag_bc_op {
|
||||
unsigned char code;
|
||||
unsigned char yes;
|
||||
unsigned short no;
|
||||
};
|
||||
|
||||
enum {
|
||||
INET_DIAG_BC_NOP,
|
||||
INET_DIAG_BC_JMP,
|
||||
INET_DIAG_BC_S_GE,
|
||||
INET_DIAG_BC_S_LE,
|
||||
INET_DIAG_BC_D_GE,
|
||||
INET_DIAG_BC_D_LE,
|
||||
INET_DIAG_BC_AUTO,
|
||||
INET_DIAG_BC_S_COND,
|
||||
INET_DIAG_BC_D_COND,
|
||||
};
|
||||
|
||||
struct inet_diag_hostcond {
|
||||
__u8 family;
|
||||
__u8 prefix_len;
|
||||
int port;
|
||||
__be32 addr[0];
|
||||
};
|
||||
|
||||
/* Base info structure. It contains socket identity (addrs/ports/cookie)
|
||||
* and, alas, the information shown by netstat. */
|
||||
struct inet_diag_msg {
|
||||
__u8 idiag_family;
|
||||
__u8 idiag_state;
|
||||
__u8 idiag_timer;
|
||||
__u8 idiag_retrans;
|
||||
|
||||
struct inet_diag_sockid id;
|
||||
|
||||
__u32 idiag_expires;
|
||||
__u32 idiag_rqueue;
|
||||
__u32 idiag_wqueue;
|
||||
__u32 idiag_uid;
|
||||
__u32 idiag_inode;
|
||||
};
|
||||
|
||||
/* Extensions */
|
||||
|
||||
enum {
|
||||
INET_DIAG_NONE,
|
||||
INET_DIAG_MEMINFO,
|
||||
INET_DIAG_INFO,
|
||||
INET_DIAG_VEGASINFO,
|
||||
INET_DIAG_CONG,
|
||||
INET_DIAG_TOS,
|
||||
INET_DIAG_TCLASS,
|
||||
INET_DIAG_SKMEMINFO,
|
||||
INET_DIAG_SHUTDOWN,
|
||||
};
|
||||
|
||||
#define INET_DIAG_MAX INET_DIAG_SHUTDOWN
|
||||
|
||||
|
||||
/* INET_DIAG_MEM */
|
||||
|
||||
struct inet_diag_meminfo {
|
||||
__u32 idiag_rmem;
|
||||
__u32 idiag_wmem;
|
||||
__u32 idiag_fmem;
|
||||
__u32 idiag_tmem;
|
||||
};
|
||||
|
||||
/* INET_DIAG_VEGASINFO */
|
||||
|
||||
struct tcpvegas_info {
|
||||
__u32 tcpv_enabled;
|
||||
__u32 tcpv_rttcnt;
|
||||
__u32 tcpv_rtt;
|
||||
__u32 tcpv_minrtt;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _UAPI_INET_DIAG_H_ */
|
@ -4,10 +4,8 @@
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/inet_diag.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/sock_diag.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pwd.h>
|
||||
@ -27,6 +25,14 @@
|
||||
#include "osquery/database.h"
|
||||
#include "osquery/logger.h"
|
||||
|
||||
// From uapi/linux/sock_diag.h
|
||||
// From linux/sock_diag.h (<= 3.6)
|
||||
#ifndef SOCK_DIAG_BY_FAMILY
|
||||
#define SOCK_DIAG_BY_FAMILY 20
|
||||
#endif
|
||||
|
||||
#include "inet_diag.h"
|
||||
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
||||
|
@ -28,7 +28,7 @@ class {{class_name}} {
|
||||
struct sqlite3_{{table_name}} {
|
||||
int n;
|
||||
{% for col in schema %}\
|
||||
std::vector<{{col.type.type}}> {{col.name}};
|
||||
std::vector<{{col.type.type}}> xCol_{{col.name}};
|
||||
{% endfor %}\
|
||||
};
|
||||
|
||||
@ -75,7 +75,7 @@ int {{table_name_cc}}Column(
|
||||
{% if col.type.affinity == "TEXT" %}\
|
||||
sqlite3_result_text(
|
||||
ctx,
|
||||
(pVtab->pContent->{{col.name}}[pCur->row]).c_str(),
|
||||
(pVtab->pContent->xCol_{{col.name}}[pCur->row]).c_str(),
|
||||
-1,
|
||||
nullptr
|
||||
);
|
||||
@ -83,13 +83,13 @@ int {{table_name_cc}}Column(
|
||||
{% if col.type.affinity == "INTEGER" %}\
|
||||
sqlite3_result_int(
|
||||
ctx,
|
||||
({{col.type.type}})pVtab->pContent->{{col.name}}[pCur->row]
|
||||
({{col.type.type}})pVtab->pContent->xCol_{{col.name}}[pCur->row]
|
||||
);
|
||||
{% endif %}\
|
||||
{% if col.type.affinity == "BIGINT" %}\
|
||||
sqlite3_result_int64(
|
||||
ctx,
|
||||
({{col.type.type}})pVtab->pContent->{{col.name}}[pCur->row]
|
||||
({{col.type.type}})pVtab->pContent->xCol_{{col.name}}[pCur->row]
|
||||
);
|
||||
{% endif %}\
|
||||
break;
|
||||
@ -112,7 +112,7 @@ int {{table_name_cc}}Filter(
|
||||
|
||||
pCur->row = 0;
|
||||
{% for col in schema %}\
|
||||
pVtab->pContent->{{col.name}}.clear();
|
||||
pVtab->pContent->xCol_{{col.name}}.clear();
|
||||
{% endfor %}\
|
||||
|
||||
{% if class_name != "" %}
|
||||
@ -122,30 +122,32 @@ int {{table_name_cc}}Filter(
|
||||
{% endif %}
|
||||
{% for col in schema %}\
|
||||
{% if col.type.affinity == "TEXT" %}\
|
||||
pVtab->pContent->{{col.name}}.push_back(row["{{col.name}}"]);
|
||||
pVtab->pContent->xCol_{{col.name}}.push_back(row["{{col.name}}"]);
|
||||
{% endif %}\
|
||||
{% if col.type.affinity == "INTEGER" %}\
|
||||
try {
|
||||
pVtab->pContent->{{col.name}}\
|
||||
pVtab->pContent->xCol_{{col.name}}\
|
||||
.push_back(boost::lexical_cast<{{col.type.type}}>(row["{{col.name}}"]));
|
||||
} catch (const boost::bad_lexical_cast& e) {
|
||||
LOG(WARNING) << "Error casting " << row["{{col.name}}"] << " to {{col.type.type}}";
|
||||
pVtab->pContent->{{col.name}}.push_back(-1);
|
||||
LOG(WARNING) << "Error casting {{col.name}} ("
|
||||
<< row["{{col.name}}"] << ") to {{col.type.type}}";
|
||||
pVtab->pContent->xCol_{{col.name}}.push_back(-1);
|
||||
}
|
||||
{% endif %}\
|
||||
{% if col.type == "BIGINT" %}\
|
||||
try {
|
||||
pVtab->pContent->{{col.name}}\
|
||||
pVtab->pContent->xCol_{{col.name}}\
|
||||
.push_back(boost::lexical_cast<{{col.type.type}}>(row["{{col.name}}"]));
|
||||
} catch (const boost::bad_lexical_cast& e) {
|
||||
LOG(WARNING) << "Error casting " << row["{{col.name}}"] << " to {{col.type.type}}";
|
||||
pVtab->pContent->{{col.name}}.push_back(-1);
|
||||
LOG(WARNING) << "Error casting {{col.name}} ("
|
||||
<< row["{{col.name}}"] << ") to {{col.type.type}}";
|
||||
pVtab->pContent->xCol_{{col.name}}.push_back(-1);
|
||||
}
|
||||
{% endif %}\
|
||||
{% endfor %}\
|
||||
}
|
||||
|
||||
pVtab->pContent->n = pVtab->pContent->{{schema[0].name}}.size();
|
||||
pVtab->pContent->n = pVtab->pContent->xCol_{{schema[0].name}}.size();
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ import uuid
|
||||
|
||||
from gentable import Column, ForeignKey, \
|
||||
table_name, schema, implementation, description, table, \
|
||||
DataType, BIGINT, DATE, DATETIME, INTEGER, TEXT
|
||||
DataType, BIGINT, DATE, DATETIME, INTEGER, TEXT \
|
||||
is_blacklisted
|
||||
|
||||
# the log format for the logging module
|
||||
LOG_FORMAT = "%(levelname)s [Line %(lineno)d]: %(message)s"
|
||||
@ -122,6 +123,13 @@ def main(argc, argv):
|
||||
logging.error("Cannot parse profile data: %s" % (str(e)))
|
||||
exit(2)
|
||||
|
||||
# Read in the optional list of blacklisted tables
|
||||
blacklist = None
|
||||
blacklist_path = os.path.join(args.tables, "blacklist")
|
||||
if os.path.exists(blacklist_path):
|
||||
with open(blacklist_path, "r") as fh:
|
||||
blacklist = fh.read()
|
||||
|
||||
categories = {}
|
||||
for base, folders, files in os.walk(args.tables):
|
||||
for spec_file in files:
|
||||
@ -138,6 +146,8 @@ def main(argc, argv):
|
||||
table_spec = gen_spec(tree)
|
||||
table_profile = profile.get("%s.%s" % (platform, name), {})
|
||||
table_spec["profile"] = NoIndent(table_profile)
|
||||
table_spec["blacklisted"] = is_blacklisted(table_spec["name"],
|
||||
blacklist=blacklist)
|
||||
categories[platform]["tables"].append(table_spec)
|
||||
categories = [{"key": k, "name": v["name"], "tables": v["tables"]}
|
||||
for k, v in categories.iteritems()]
|
||||
|
@ -22,16 +22,18 @@ LOG_FORMAT = "%(levelname)s [Line %(lineno)d]: %(message)s"
|
||||
TEMPLATES = {}
|
||||
|
||||
# Temporary reserved column names
|
||||
RESERVED = ["group"]
|
||||
RESERVED = ["n"]
|
||||
|
||||
# Supported SQL types for spec
|
||||
class DataType(object):
|
||||
def __init__(self, affinity, cpp_type="std::string"):
|
||||
'''A column datatype is a pair of a SQL affinity to C++ type.'''
|
||||
self.affinity = affinity
|
||||
self.type = cpp_type
|
||||
def __repr__(self):
|
||||
return self.affinity
|
||||
|
||||
# Define column-type MACROs for the table specs
|
||||
TEXT = DataType("TEXT")
|
||||
DATE = DataType("TEXT")
|
||||
DATETIME = DataType("TEXT")
|
||||
@ -50,22 +52,22 @@ def to_camel_case(snake_case):
|
||||
def lightred(msg):
|
||||
return "\033[1;31m %s \033[0m" % str(msg)
|
||||
|
||||
def is_blacklisted(path, table_name):
|
||||
def is_blacklisted(table_name, path=None, blacklist=None):
|
||||
"""Allow blacklisting by tablename."""
|
||||
specs_path = os.path.dirname(os.path.dirname(path))
|
||||
blacklist_path = os.path.join(specs_path, "blacklist")
|
||||
if not os.path.exists(blacklist_path):
|
||||
return False
|
||||
try:
|
||||
with open(blacklist_path, "r") as fh:
|
||||
blacklist = [line.strip() for line in fh.read().split("\n")
|
||||
if len(line.strip()) > 0 and line.strip()[0] != "#"]
|
||||
if table_name in blacklist:
|
||||
return True
|
||||
except:
|
||||
# Blacklist is not readable.
|
||||
pass
|
||||
return False
|
||||
if blacklist is None:
|
||||
specs_path = os.path.dirname(os.path.dirname(path))
|
||||
blacklist_path = os.path.join(specs_path, "blacklist")
|
||||
if not os.path.exists(blacklist_path):
|
||||
return False
|
||||
try:
|
||||
with open(blacklist_path, "r") as fh:
|
||||
blacklist = [line.strip() for line in fh.read().split("\n")
|
||||
if len(line.strip()) > 0 and line.strip()[0] != "#"]
|
||||
except:
|
||||
# Blacklist is not readable.
|
||||
return False
|
||||
# table_name based blacklisting!
|
||||
return table_name in blacklist if blacklist else False
|
||||
|
||||
def setup_templates(path):
|
||||
tables_path = os.path.dirname(os.path.dirname(os.path.dirname(path)))
|
||||
@ -237,7 +239,8 @@ def main(argc, argv):
|
||||
with open(filename, "rU") as file_handle:
|
||||
tree = ast.parse(file_handle.read())
|
||||
exec(compile(tree, "<string>", "exec"))
|
||||
if not disable_blacklist and is_blacklisted(filename, table.table_name):
|
||||
blacklisted = is_blacklisted(table.table_name, path=filename)
|
||||
if not disable_blacklist and blacklisted:
|
||||
table.blacklist(output)
|
||||
else:
|
||||
table.generate(output)
|
||||
|
@ -3,6 +3,7 @@
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
BUILD_DIR="$SCRIPT_DIR/../build"
|
||||
WORKING_DIR="$SCRIPT_DIR/../.sources"
|
||||
export PATH="$PATH:/usr/local/bin"
|
||||
|
||||
@ -243,6 +244,9 @@ function check() {
|
||||
|
||||
if [[ "$1" = "build" ]]; then
|
||||
echo $HASH > "$2/.provision"
|
||||
if [[ ! -z "$SUDO_USER" ]]; then
|
||||
chown $SUDO_USER "$2/.provision"
|
||||
fi
|
||||
return
|
||||
elif [[ ! "$1" = "check" ]]; then
|
||||
return
|
||||
@ -271,6 +275,10 @@ function main() {
|
||||
fi
|
||||
|
||||
mkdir -p "$WORKING_DIR"
|
||||
if [[ ! -z "$SUDO_USER" ]]; then
|
||||
chown -R $SUDO_USER "$BUILD_DIR"
|
||||
chown -R $SUDO_USER "$WORKING_DIR"
|
||||
fi
|
||||
cd "$WORKING_DIR"
|
||||
|
||||
if [[ $OS = "centos" ]]; then
|
||||
|
Loading…
Reference in New Issue
Block a user