Add MariaDB 10.1.13 offsets. Format the code.
parent
051b1fd67e
commit
80646620e9
|
@ -63,8 +63,7 @@ typedef size_t OFFSET;
|
|||
/**
|
||||
* The struct used to hold offsets. We should have one per version.
|
||||
*/
|
||||
typedef struct ThdOffsets
|
||||
{
|
||||
typedef struct ThdOffsets {
|
||||
const char *version;
|
||||
const char *md5digest;
|
||||
OFFSET query_id;
|
||||
|
@ -96,8 +95,7 @@ typedef ssize_t (*audit_write_func)(const char *, size_t);
|
|||
/**
|
||||
* Interface for an io writer
|
||||
*/
|
||||
class IWriter
|
||||
{
|
||||
class IWriter {
|
||||
public:
|
||||
virtual ~IWriter() {}
|
||||
// return negative on fail
|
||||
|
@ -113,7 +111,6 @@ public:
|
|||
|
||||
class ThdSesData {
|
||||
public:
|
||||
|
||||
// enum indicating from where the object list came from
|
||||
enum ObjectIterType {OBJ_NONE, OBJ_DB, OBJ_QUERY_CACHE, OBJ_TABLE_LIST};
|
||||
ThdSesData(THD *pTHD);
|
||||
|
@ -130,6 +127,7 @@ public:
|
|||
* obj_type is optional and may be null.
|
||||
*/
|
||||
bool getNextObject(const char **db_name, const char **obj_name, const char **obj_type);
|
||||
|
||||
private:
|
||||
THD *m_pThd;
|
||||
const char *m_CmdName;
|
||||
|
@ -143,6 +141,7 @@ private:
|
|||
// used for query cache iter
|
||||
QueryTableInf *m_tableInf;
|
||||
int m_index;
|
||||
|
||||
protected:
|
||||
ThdSesData(const ThdSesData&);
|
||||
ThdSesData &operator =(const ThdSesData&);
|
||||
|
@ -151,10 +150,8 @@ protected:
|
|||
/**
|
||||
* Base for audit formatter
|
||||
*/
|
||||
class Audit_formatter
|
||||
{
|
||||
class Audit_formatter {
|
||||
public:
|
||||
|
||||
virtual ~Audit_formatter() {}
|
||||
|
||||
/**
|
||||
|
@ -335,17 +332,14 @@ public:
|
|||
{
|
||||
return table->view_tables != 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Format the audit even in json format
|
||||
*/
|
||||
class Audit_json_formatter: public Audit_formatter
|
||||
{
|
||||
class Audit_json_formatter: public Audit_formatter {
|
||||
public:
|
||||
|
||||
static const char *DEF_MSG_DELIMITER;
|
||||
|
||||
Audit_json_formatter(): m_msg_delimiter(NULL), m_write_start_msg(true), m_password_mask_regex_preg(NULL),
|
||||
|
@ -354,6 +348,7 @@ public:
|
|||
config.beautify = 0;
|
||||
config.indentString = NULL;
|
||||
}
|
||||
|
||||
virtual ~Audit_json_formatter()
|
||||
{
|
||||
if (m_password_mask_regex_preg)
|
||||
|
@ -375,9 +370,9 @@ public:
|
|||
|
||||
/**
|
||||
* Compile password masking regex
|
||||
* Return 0 on success
|
||||
* Return true on success
|
||||
*/
|
||||
int compile_password_masking_regex(const char * str);
|
||||
bool compile_password_masking_regex(const char *str);
|
||||
|
||||
/**
|
||||
* Boolean indicating if to log start msg.
|
||||
|
@ -418,18 +413,13 @@ protected:
|
|||
* Regex used for password masking
|
||||
*/
|
||||
pcre *m_password_mask_regex_preg;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for audit handlers. Provides basic locking setup.
|
||||
*/
|
||||
class Audit_handler
|
||||
{
|
||||
class Audit_handler {
|
||||
public:
|
||||
|
||||
|
||||
|
||||
static const size_t MAX_AUDIT_HANDLERS_NUM = 4;
|
||||
static const size_t JSON_FILE_HANDLER = 1;
|
||||
static const size_t JSON_SOCKET_HANDLER = 3;
|
||||
|
@ -447,7 +437,8 @@ public:
|
|||
static void stop_all();
|
||||
|
||||
Audit_handler() :
|
||||
m_initialized(false), m_enabled(false), m_print_offset_err(true), m_formatter(NULL), m_failed(false), m_log_io_errors(true)
|
||||
m_initialized(false), m_enabled(false), m_print_offset_err(true),
|
||||
m_formatter(NULL), m_failed(false), m_log_io_errors(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -567,10 +558,10 @@ private:
|
|||
/**
|
||||
* Base class for handler which have io and need a lock
|
||||
*/
|
||||
class Audit_io_handler: public Audit_handler, public IWriter
|
||||
{
|
||||
class Audit_io_handler: public Audit_handler, public IWriter {
|
||||
public:
|
||||
Audit_io_handler() : m_io_dest(NULL), m_io_type(NULL)
|
||||
Audit_io_handler()
|
||||
: m_io_dest(NULL), m_io_type(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -591,8 +582,7 @@ protected:
|
|||
const char *m_io_type;
|
||||
};
|
||||
|
||||
class Audit_file_handler: public Audit_io_handler
|
||||
{
|
||||
class Audit_file_handler: public Audit_io_handler {
|
||||
public:
|
||||
|
||||
Audit_file_handler() :
|
||||
|
@ -632,8 +622,6 @@ protected:
|
|||
Audit_file_handler & operator=(const Audit_file_handler&);
|
||||
Audit_file_handler(const Audit_file_handler&);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Will acquire locks and call handler_write
|
||||
*/
|
||||
|
@ -641,12 +629,9 @@ protected:
|
|||
FILE *m_log_file;
|
||||
// the period to use for syncing
|
||||
unsigned int m_sync_counter;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class Audit_socket_handler: public Audit_io_handler
|
||||
{
|
||||
class Audit_socket_handler: public Audit_io_handler {
|
||||
public:
|
||||
|
||||
Audit_socket_handler() :
|
||||
|
@ -688,4 +673,3 @@ protected:
|
|||
};
|
||||
|
||||
#endif /* AUDIT_HANDLER_H_ */
|
||||
|
||||
|
|
|
@ -92,8 +92,4 @@ extern "C" char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // MYSQL_INCL_H
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Created on: Feb 6, 2011
|
||||
* Author: guyl
|
||||
*/
|
||||
|
||||
#include "audit_handler.h"
|
||||
// for definition of sockaddr_un
|
||||
#include <sys/un.h>
|
||||
|
@ -42,7 +43,6 @@
|
|||
// regex flags used in compilation
|
||||
static const int regex_flags = PCRE_DOTALL | PCRE_UTF8 | PCRE_CASELESS | PCRE_DUPNAMES;
|
||||
|
||||
|
||||
// initialize static stuff
|
||||
ThdOffsets Audit_formatter::thd_offsets = { 0 };
|
||||
Audit_handler *Audit_handler::m_audit_handler_list[Audit_handler::MAX_AUDIT_HANDLERS_NUM];
|
||||
|
@ -52,7 +52,6 @@ const char * Audit_json_formatter::DEF_MSG_DELIMITER = "\\n";
|
|||
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
|
||||
#endif
|
||||
|
||||
|
||||
const char *Audit_formatter::retrieve_object_type(TABLE_LIST *pObj)
|
||||
{
|
||||
if (table_is_view(pObj))
|
||||
|
@ -62,7 +61,6 @@ const char * Audit_formatter::retrieve_object_type (TABLE_LIST *pObj)
|
|||
return "TABLE";
|
||||
}
|
||||
|
||||
|
||||
void Audit_handler::stop_all()
|
||||
{
|
||||
for (size_t i = 0; i < MAX_AUDIT_HANDLERS_NUM; ++i)
|
||||
|
@ -149,7 +147,8 @@ void Audit_handler::log_audit(ThdSesData *pThdData)
|
|||
}
|
||||
}
|
||||
else
|
||||
{//offsets are good
|
||||
{
|
||||
// offsets are good
|
||||
m_print_offset_err = true; // mark to print offset err to log in case we encounter in the future
|
||||
pthread_mutex_lock(&LOCK_io);
|
||||
// check if failed
|
||||
|
@ -200,6 +199,7 @@ ssize_t Audit_file_handler::write(const char * data, size_t size)
|
|||
int Audit_file_handler::open(const char *io_dest, bool log_errors)
|
||||
{
|
||||
char format_name[FN_REFLEN];
|
||||
|
||||
fn_format(format_name, io_dest, "", "", MY_UNPACK_FILENAME);
|
||||
m_log_file = my_fopen(format_name, O_WRONLY | O_APPEND| O_CREAT, MYF(0));
|
||||
if (! m_log_file)
|
||||
|
@ -212,6 +212,7 @@ int Audit_file_handler::open(const char * io_dest, bool log_errors)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t bufsize = BUFSIZ;
|
||||
int res = 0;
|
||||
// 0 -> use default, 1 or negative -> disabled
|
||||
|
@ -219,6 +220,7 @@ int Audit_file_handler::open(const char * io_dest, bool log_errors)
|
|||
{
|
||||
bufsize = m_bufsize;
|
||||
}
|
||||
|
||||
if (1 == m_bufsize || m_bufsize < 0)
|
||||
{
|
||||
// disabled
|
||||
|
@ -229,6 +231,7 @@ int Audit_file_handler::open(const char * io_dest, bool log_errors)
|
|||
res = setvbuf(m_log_file, NULL, _IOFBF, bufsize);
|
||||
|
||||
}
|
||||
|
||||
if (res)
|
||||
{
|
||||
sql_print_error(
|
||||
|
@ -260,7 +263,7 @@ bool Audit_io_handler::handler_start_internal()
|
|||
}
|
||||
ssize_t res = m_formatter->start_msg_format(this);
|
||||
/*
|
||||
sanity check of writing to the log. If we fail. We will print an erorr and disable this handler.
|
||||
* Sanity check of writing to the log. If we fail, we print an erorr and disable this handler.
|
||||
*/
|
||||
if (res < 0)
|
||||
{
|
||||
|
@ -307,6 +310,7 @@ void Audit_handler::handler_start()
|
|||
handler_start_nolock();
|
||||
pthread_mutex_unlock(&LOCK_io);
|
||||
}
|
||||
|
||||
void Audit_handler::handler_stop()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_io);
|
||||
|
@ -406,7 +410,6 @@ bool Audit_socket_handler::handler_log_audit(ThdSesData *pThdData)
|
|||
|
||||
|
||||
|
||||
|
||||
static yajl_gen_status yajl_add_string(yajl_gen hand, const char *str)
|
||||
{
|
||||
return yajl_gen_string(hand, (const unsigned char *) str, strlen(str));
|
||||
|
@ -435,6 +438,7 @@ static void yajl_add_uint64(yajl_gen gen, const char * name, uint64 num)
|
|||
snprintf(buf, max_int64_str_len, "%llu", num);
|
||||
yajl_add_string_val(gen, name, buf);
|
||||
}
|
||||
|
||||
static void yajl_add_obj(yajl_gen gen, const char *db, const char *ptype, const char *name = NULL)
|
||||
{
|
||||
if (db)
|
||||
|
@ -450,14 +454,13 @@ static void yajl_add_obj( yajl_gen gen, const char *db,const char* ptype,const
|
|||
|
||||
static const char *retrieve_user(THD *thd)
|
||||
{
|
||||
|
||||
const char *user = Audit_formatter::thd_inst_main_security_ctx_user(thd);
|
||||
if(user != NULL && *user != 0x0) //non empty
|
||||
if (user != NULL && *user != '\0') // non empty
|
||||
{
|
||||
return user;
|
||||
}
|
||||
user = Audit_formatter::thd_inst_main_security_ctx_priv_user(thd); // try using priv user
|
||||
if(user != NULL && *user != 0x0) //non empty
|
||||
if (user != NULL && *user != '\0') // non empty
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
@ -489,6 +492,7 @@ static const char * thd_query_str(THD * thd, size_t * len)
|
|||
extern "C" {
|
||||
MYSQL_LEX_STRING *thd_query_string(MYSQL_THD thd);
|
||||
}
|
||||
|
||||
static const char *thd_query_str(THD *thd, size_t *len)
|
||||
{
|
||||
MYSQL_LEX_STRING * str = thd_query_string(thd);
|
||||
|
@ -505,6 +509,7 @@ static const char * thd_query_str(THD * thd, size_t * len)
|
|||
// we still want to support thd_query_string if we are run on a version higher than 5.1.40, so we try to lookup the symbol
|
||||
static LEX_STRING * (*thd_query_string_func)(THD *thd) = (LEX_STRING*(*)(THD*))dlsym(RTLD_DEFAULT, "thd_query_string");
|
||||
static bool print_thd_query_string_func = true; // debug info print only once
|
||||
|
||||
static const char *thd_query_str(THD *thd, size_t *len)
|
||||
{
|
||||
if (print_thd_query_string_func)
|
||||
|
@ -534,6 +539,7 @@ ssize_t Audit_json_formatter::start_msg_format(IWriter * writer)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// initialize yajl
|
||||
yajl_gen gen = yajl_gen_alloc(&config, NULL);
|
||||
yajl_gen_map_open(gen);
|
||||
|
@ -548,6 +554,7 @@ ssize_t Audit_json_formatter::start_msg_format(IWriter * writer)
|
|||
yajl_add_string_val(gen, "mysql-socket", mysqld_unix_port);
|
||||
yajl_add_uint64(gen, "mysql-port", mysqld_port);
|
||||
ssize_t res = -2;
|
||||
|
||||
yajl_gen_status stat = yajl_gen_map_close(gen); // close the object
|
||||
if (stat == yajl_gen_status_ok) // all is good write the buffer out
|
||||
{
|
||||
|
@ -565,7 +572,6 @@ ssize_t Audit_json_formatter::start_msg_format(IWriter * writer)
|
|||
}
|
||||
yajl_gen_free(gen); // free the generator
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
// This routine replaces clear text with the string in `replace', leaving the rest of the string intact.
|
||||
|
@ -625,6 +631,7 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
yajl_add_string_val(gen, "ip", Audit_formatter::thd_inst_main_security_ctx_ip(thd));
|
||||
const char *cmd = pThdData->getCmdName();
|
||||
yajl_add_string_val(gen, "cmd", cmd);
|
||||
|
||||
// get objects
|
||||
if (pThdData->startGetObjects())
|
||||
{
|
||||
|
@ -658,7 +665,8 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
const char *query_text = query;
|
||||
size_t query_len = qlen;
|
||||
|
||||
if (strcmp(col_connection->csname, "utf8") != 0) {
|
||||
if (strcmp(col_connection->csname, "utf8") != 0)
|
||||
{
|
||||
// max UTF-8 bytes per char is 4.
|
||||
size_t to_amount = (qlen * 4) + 1;
|
||||
char* to = (char *) thd_alloc(thd, to_amount);
|
||||
|
@ -676,7 +684,10 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
qlen = len;
|
||||
}
|
||||
|
||||
if(m_perform_password_masking && m_password_mask_regex_compiled && m_password_mask_regex_preg && m_perform_password_masking(cmd))
|
||||
if (m_perform_password_masking
|
||||
&& m_password_mask_regex_compiled
|
||||
&& m_password_mask_regex_preg
|
||||
&& m_perform_password_masking(cmd))
|
||||
{
|
||||
// do password masking
|
||||
int matches[90] = { 0 };
|
||||
|
@ -700,7 +711,12 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
// interfaces in MySQL have changed fairly drastically. So we just do the
|
||||
// replacement ourselves.
|
||||
const char *pass_replace = "***";
|
||||
const char *updated = replace_in_string(thd, query_text, query_len, matches[n*2], matches[(n*2) + 1] - matches[n*2], pass_replace);
|
||||
const char *updated = replace_in_string(thd,
|
||||
query_text,
|
||||
query_len,
|
||||
matches[n*2],
|
||||
matches[(n*2) + 1] - matches[n*2],
|
||||
pass_replace);
|
||||
query_text = updated;
|
||||
query_len = strlen(query_text);
|
||||
break;
|
||||
|
@ -722,6 +738,7 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
yajl_add_string_val(gen, "query", "n/a", strlen("n/a"));
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t res = -2;
|
||||
yajl_gen_status stat = yajl_gen_map_close(gen); // close the object
|
||||
if (stat == yajl_gen_status_ok) // all is good write the buffer out
|
||||
|
@ -742,10 +759,8 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ThdSesData::ThdSesData (THD *pTHD) :
|
||||
m_pThd (pTHD), m_CmdName(NULL), m_UserName(NULL),
|
||||
ThdSesData::ThdSesData(THD *pTHD)
|
||||
: m_pThd (pTHD), m_CmdName(NULL), m_UserName(NULL),
|
||||
m_objIterType(OBJ_NONE), m_tables(NULL), m_firstTable(true),
|
||||
m_tableInf(NULL), m_index(0), m_isSqlCmd(false)
|
||||
{
|
||||
|
@ -782,7 +797,7 @@ bool ThdSesData::startGetObjects()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
//only return query tabls if command is COM_QUERY
|
||||
// only return query tables if command is COM_QUERY
|
||||
// TODO: check if other commands can also generate query tables such as "show fields"
|
||||
if (pLex && command == COM_QUERY && pLex->query_tables)
|
||||
{
|
||||
|
@ -873,25 +888,26 @@ pcre * Audit_json_formatter::regex_compile(const char * str)
|
|||
return re;
|
||||
}
|
||||
|
||||
int Audit_json_formatter::compile_password_masking_regex(const char * str)
|
||||
bool Audit_json_formatter::compile_password_masking_regex(const char *str)
|
||||
{
|
||||
// first free existing
|
||||
if (m_password_mask_regex_compiled)
|
||||
{
|
||||
m_password_mask_regex_compiled = false;
|
||||
//small sleep to let threads oomplete regexc
|
||||
// small sleep to let threads complete regexec
|
||||
my_sleep(10 * 1000);
|
||||
pcre_free(m_password_mask_regex_preg);
|
||||
}
|
||||
int error = 1; //default is error (case of empty string)
|
||||
|
||||
bool success = false; // default is error (case of empty string)
|
||||
if (NULL != str && str[0] != '\0')
|
||||
{
|
||||
m_password_mask_regex_preg = regex_compile(str);
|
||||
if (m_password_mask_regex_preg)
|
||||
{
|
||||
m_password_mask_regex_compiled = true;
|
||||
error = 0;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.38","ae5937fbe5856b36b1ac7b0cb400abdd", 6136, 6184, 3816, 4312, 88, 2592, 96, 0, 32, 104},
|
||||
//offsets for: /mysqlrpm/5.6.19/usr/sbin/mysqld (5.6.19)
|
||||
{"5.6.19","2a01471dc6b6b59ae25a7efe675d1af4", 7928, 7976, 3992, 4512, 72, 2704, 96, 0, 32, 104},
|
||||
|
||||
//offsets for: mysqlrpm/5.1.30/usr/sbin/mysqld (5.1.30-community)
|
||||
{"5.1.30-community","8e43bda3644a883d46a1d064304b4f1d", 6184, 6248, 3656, 3928, 88, 2048},
|
||||
//offsets for: mysqlrpm/5.1.31/usr/sbin/mysqld (5.1.31-community)
|
||||
|
@ -157,7 +156,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.1.68-community","4042e9a2778090df6fd8481e03ed6737", 6376, 6440, 3736, 4008, 88, 2056},
|
||||
//offsets for: /mysqlrpm/5.1.69/usr/sbin/mysqld (5.1.69-community)
|
||||
{"5.1.69-community","e9cb524b604419964f4dd55a8c87d618", 6376, 6440, 3736, 4008, 88, 2056},
|
||||
|
||||
//offsets for: mysqlrpm/5.5.8/usr/sbin/mysqld (5.5.8)
|
||||
{"5.5.8","70a882693d54df8ab7c7d9f256e317bb", 6032, 6080, 3776, 4200, 88, 2560},
|
||||
//offsets for: mysqlrpm/5.5.9/usr/sbin/mysqld (5.5.9)
|
||||
|
@ -216,7 +214,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.30-ndb-7.2.12-cluster-commercial-advanced","9f96bc38bf06a9b18a945227ff9e5c42", 6096, 6144, 3816, 4240, 88, 2568},
|
||||
//offsets for: /mysqlrpm/5.5.31/usr/sbin/mysqld (5.5.31)
|
||||
{"5.5.31","f6604e70b9592f484a7a04a0173f0b25", 6064, 6112, 3816, 4240, 88, 2568},
|
||||
|
||||
//offsets for: MySQL-server-5.6.10-1.el6.x86_64/usr/sbin/mysqld (5.6.10)
|
||||
{"5.6.10","7016428728fe057d6825682d30e37b3d", 7808, 7856, 3960, 4400, 72, 2664},
|
||||
//offsets for: /mysqlrpm/5.6.10/usr/sbin/mysqld (5.6.10)
|
||||
|
@ -308,7 +305,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.1.68","673dd031ea4ad3493b47d74662a49079", 6392, 6456, 3752, 4024, 88, 2056},
|
||||
//offsets for: /mysql/5.1.69/bin/mysqld (5.1.69)
|
||||
{"5.1.69","af2936f85db019bfd44c7e12a2138707", 6392, 6456, 3752, 4024, 88, 2056},
|
||||
|
||||
//offsets for: mysql/5.5.8/bin/mysqld (5.5.8)
|
||||
{"5.5.8","a32b163f08ca8bfd7486cd77200d9df3", 6032, 6080, 3776, 4200, 88, 2560},
|
||||
//offsets for: mysql/5.5.9/bin/mysqld (5.5.9)
|
||||
|
@ -362,12 +358,10 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.31","858dc19ffc5d34e669ab85d32a8a0623", 6064, 6112, 3816, 4240, 88, 2568},
|
||||
//offsets for: /mysql/5.5.31/bin/mysqld (5.5.31)
|
||||
{"5.5.31","61e65a4cc9360e03f3810ef2928c916d", 6064, 6112, 3816, 4240, 88, 2568},
|
||||
|
||||
//offsets for: /mysql/5.6.10/bin/mysqld (5.6.10)
|
||||
{"5.6.10","37f9c31dd092bb2d0da7eb6e2098732f", 7808, 7856, 3960, 4400, 72, 2664},
|
||||
//offsets for: /mysql/5.6.11/bin/mysqld (5.6.11)
|
||||
{"5.6.11","85fd884192cc5cd12fba52b7b140c819", 7808, 7856, 3960, 4400, 72, 2672},
|
||||
|
||||
//offsets for: /mysqlrpm/5.1.70/usr/sbin/mysqld (5.1.70-community)
|
||||
{"5.1.70-community","e70f9d48dad2a30b24e6c2744bed94d2", 6376, 6440, 3736, 4008, 88, 2072},
|
||||
//offsets for: /mysqlrpm/5.5.32/usr/sbin/mysqld (5.5.32)
|
||||
|
@ -481,7 +475,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.38","89e8b85dd5731e15df3d5597020c0ec8", 3868, 3896, 2368, 2748, 44, 1656, 60, 0, 20, 64},
|
||||
//offsets for: /mysqlrpm/5.6.19/usr/sbin/mysqld (5.6.19)
|
||||
{"5.6.19","3f94430e20b564951159aa78627df97f", 5652, 5680, 2656, 3048, 36, 1748, 60, 0, 20, 64},
|
||||
|
||||
//offsets for: mysqlrpm/5.1.30/usr/sbin/mysqld (5.1.30-community)
|
||||
{"5.1.30-community","fdfe108d05c262c185a7c28b2e493c10", 4024, 4064, 2224, 2404, 44, 1180},
|
||||
//offsets for: mysqlrpm/5.1.31/usr/sbin/mysqld (5.1.31-community)
|
||||
|
@ -563,7 +556,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.1.68-community","df5dc268b36dbe853ed37d91fd4b6b3f", 4124, 4164, 2268, 2448, 44, 1180},
|
||||
//offsets for: /mysqlrpm/5.1.69/usr/sbin/mysqld (5.1.69-community)
|
||||
{"5.1.69-community","4c8acbca31f3f4ba44d35db9f5c65bc0", 4124, 4164, 2268, 2448, 44, 1180},
|
||||
|
||||
//offsets for: mysqlrpm/5.5.8/usr/sbin/mysqld (5.5.8)
|
||||
{"5.5.8","3132e8c883f72caf4c8eddb24fd005b4", 3792, 3820, 2336, 2668, 44, 1640},
|
||||
//offsets for: mysqlrpm/5.5.9/usr/sbin/mysqld (5.5.9)
|
||||
|
@ -610,7 +602,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.30","0186d1ef4725814924bfe968e3455138", 3816, 3844, 2368, 2700, 44, 1644},
|
||||
//offsets for: /mysqlrpm/5.5.31/usr/sbin/mysqld (5.5.31)
|
||||
{"5.5.31","190e7556e226f8690ba8672869178e4c", 3816, 3844, 2368, 2700, 44, 1644},
|
||||
|
||||
//offsets for: /mysqlrpm/5.6.10/usr/sbin/mysqld (5.6.10)
|
||||
{"5.6.10","dd3abddcfd0015de81b6a26b6190cefb", 5572, 5600, 2640, 2980, 36, 1712},
|
||||
//offsets for: /mysqlrpm/5.6.11/usr/sbin/mysqld (5.6.11)
|
||||
|
@ -696,7 +687,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.1.68","d03c42d8a8946f11ace86a5e1189114d", 4140, 4180, 2284, 2464, 44, 1180},
|
||||
//offsets for: /mysql/5.1.69/bin/mysqld (5.1.69)
|
||||
{"5.1.69","5abf5a9f9f9c01be997595b066a40986", 4140, 4180, 2284, 2464, 44, 1180},
|
||||
|
||||
//offsets for: /mysqlrpm/5.5.8/usr/sbin/mysqld (5.5.8)
|
||||
{"5.5.8","3132e8c883f72caf4c8eddb24fd005b4", 3792, 3820, 2336, 2668, 44, 1640},
|
||||
{"5.5.8","ad8a16d9bbfb783dab53f38cef757900", 3792, 3820, 2336, 2668, 44, 1640},
|
||||
|
@ -748,12 +738,10 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
{"5.5.30","c7b98be45d35b77da6679c354c23d1fa", 3816, 3844, 2368, 2700, 44, 1644},
|
||||
//offsets for: /mysql/5.5.31/bin/mysqld (5.5.31)
|
||||
{"5.5.31","36631a7c748358598ba21cd4157545d9", 3816, 3844, 2368, 2700, 44, 1644},
|
||||
|
||||
//offsets for: /mysql/5.6.10/bin/mysqld (5.6.10)
|
||||
{"5.6.10","84600f18354f519e38302c04fe55ed9c", 5572, 5600, 2640, 2980, 36, 1712},
|
||||
//offsets for: /mysql/5.6.11/bin/mysqld (5.6.11)
|
||||
{"5.6.11","72e67111f3c1d1c1d4e7095e3a004fcf", 5572, 5600, 2640, 2980, 36, 1724},
|
||||
|
||||
//offsets for: /mysqlrpm/5.1.70/usr/sbin/mysqld (5.1.70-community)
|
||||
{"5.1.70-community","605c76c9d37a890cea85c075aeaaa2e6", 4124, 4164, 2268, 2448, 44, 1188},
|
||||
//offsets for: /mysqlrpm/5.5.32/usr/sbin/mysqld (5.5.32)
|
||||
|
@ -812,7 +800,6 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
//start offsets for MariaDB
|
||||
#ifdef __x86_64__
|
||||
|
@ -820,6 +807,8 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
const ThdOffsets thd_offsets_arr[] =
|
||||
{
|
||||
/* +++ MARIADB 64 OFFSETS GO HERE +++ */
|
||||
//offsets for: /mariadb/10.1.13/bin/mysqld (10.1.13-MariaDB)
|
||||
{"10.1.13-MariaDB","cd322698dcd46dd82770dc091f1eec51", 13592, 13656, 6368, 7976, 88, 2976, 8, 0, 16, 24, 152, 13748},
|
||||
//offsets for: /mariadb/10.1.12/bin/mysqld (10.1.12-MariaDB)
|
||||
{"10.1.12-MariaDB","e2ba726e2e6f56976518581da0a2c443", 13592, 13656, 6368, 7976, 88, 2976, 8, 0, 16, 24, 152, 13748},
|
||||
//offsets for: /mariadb/10.0.24/bin/mysqld (10.0.24-MariaDB)
|
||||
|
@ -911,6 +900,8 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
const ThdOffsets thd_offsets_arr[] =
|
||||
{
|
||||
/* +++ MARIADB 32 OFFSETS GO HERE +++ */
|
||||
//offsets for: /mariadb/10.1.13/bin/mysqld (10.1.13-MariaDB)
|
||||
{"10.1.13-MariaDB","546cb7233e8567aea304fda3d9812a7b", 8472, 8508, 3816, 5276, 44, 1892, 4, 0, 8, 12, 84, 8584},
|
||||
//offsets for: /mariadb/10.1.12/bin/mysqld (10.1.12-MariaDB)
|
||||
{"10.1.12-MariaDB","590bb2be8fb17c7b3599539d4a69ab44", 8472, 8508, 3816, 5276, 44, 1892, 4, 0, 8, 12, 84, 8584},
|
||||
//offsets for: /mariadb/10.0.24/bin/mysqld (10.0.24-MariaDB)
|
||||
|
@ -1003,4 +994,3 @@ const ThdOffsets thd_offsets_arr[] =
|
|||
|
||||
//the size of the offsets arr
|
||||
const size_t thd_offsets_arr_size = array_elements(thd_offsets_arr);
|
||||
|
||||
|
|
|
@ -103,11 +103,9 @@ static const char default_pw_masking_regex[] =
|
|||
// "|ENGINE"_COMMENT_SPACE_"="_COMMENT_SPACE_"FEDERATED"_COMMENT_SPACE_".*CONNECTION"_COMMENT_SPACE_"="_COMMENT_SPACE_"[\'|\"]\\S+?://\\S+?:(?<psw>.*)@\\S+[\'|\"]"
|
||||
;
|
||||
|
||||
|
||||
// socket name
|
||||
static char json_socket_name_buff[1024] = {0};
|
||||
|
||||
|
||||
/**
|
||||
* The trampoline functions we use. Will be set to point to allocated mem.
|
||||
*/
|
||||
|
@ -128,7 +126,8 @@ static unsigned int trampoline_acl_authenticate_size =0;
|
|||
#endif
|
||||
|
||||
static MYSQL_THDVAR_ULONG(is_thd_printed_list,
|
||||
PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT, "avoid duplicate printing",
|
||||
PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT,
|
||||
"avoid duplicate printing",
|
||||
NULL, NULL,0,0,
|
||||
#ifdef __x86_64__
|
||||
0xffffffffffffff,
|
||||
|
@ -138,7 +137,8 @@ NULL, NULL,0,0,
|
|||
1);
|
||||
|
||||
static MYSQL_THDVAR_ULONG(query_cache_table_list,
|
||||
PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT, "Pointer to query cache table list.",
|
||||
PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT,
|
||||
"Pointer to query cache table list.",
|
||||
NULL, NULL,0,0,
|
||||
#ifdef __x86_64__
|
||||
0xffffffffffffff,
|
||||
|
@ -158,16 +158,21 @@ THDPRINTED * GetThdPrintedList (THD *thd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int check_array(const char *cmds[],const char *array, int length) {
|
||||
for (int k=0; array[k * length] !='\0';k++) {
|
||||
for (int q = 0; cmds[q] != NULL; q++) {
|
||||
static int check_array(const char *cmds[],const char *array, int length)
|
||||
{
|
||||
for (int k = 0; array[k * length] !='\0';k++)
|
||||
{
|
||||
for (int q = 0; cmds[q] != NULL; q++)
|
||||
{
|
||||
const char *cmd = cmds[q];
|
||||
int j = 0;
|
||||
while (array[k * length + j] != '\0' && cmd[j] != '\0'
|
||||
&& array[k * length + j] == tolower(cmd[j])) {
|
||||
&& array[k * length + j] == tolower(cmd[j]))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
if (array[k * length + j] == '\0' && j != 0) {
|
||||
if (array[k * length + j] == '\0' && j != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -217,16 +222,21 @@ static my_bool check_do_password_masking(const char * cmd)
|
|||
static void audit(ThdSesData *pThdData)
|
||||
{
|
||||
THDPRINTED *pThdPrintedList = GetThdPrintedList(pThdData->getTHD());
|
||||
if (num_whitelist_cmds > 0) {
|
||||
|
||||
if (num_whitelist_cmds > 0)
|
||||
{
|
||||
const char * cmd = pThdData->getCmdName();
|
||||
const char *cmds[2];
|
||||
cmds[0] = cmd;
|
||||
cmds[1] = NULL;
|
||||
if (check_array(cmds, (char *) whitelist_cmds_array, MAX_COMMAND_CHAR_NUMBERS)) {
|
||||
if (check_array(cmds, (char *) whitelist_cmds_array, MAX_COMMAND_CHAR_NUMBERS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (num_whitelist_users > 0) {
|
||||
|
||||
if (num_whitelist_users > 0)
|
||||
{
|
||||
const char *user = pThdData->getUserName(); // If name is present, then no need to log the query
|
||||
const char *users[2];
|
||||
if (NULL == user || '\0' == user[0]) // empty user use special symbol: "{}"
|
||||
|
@ -235,27 +245,38 @@ static void audit(ThdSesData *pThdData)
|
|||
}
|
||||
users[0] = user;
|
||||
users[1] = NULL;
|
||||
if (check_array(users, (char *) whitelist_users_array, MAX_USER_CHAR_NUMBERS)) {
|
||||
if (check_array(users, (char *) whitelist_users_array, MAX_USER_CHAR_NUMBERS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_objs_cmds_check = true;
|
||||
if (force_record_logins_enable) {
|
||||
if (force_record_logins_enable)
|
||||
{
|
||||
const char *cmd = pThdData->getCmdName();
|
||||
if (!strcasecmp(cmd, "Connect") || !strcasecmp(cmd, "Quit") || !strcasecmp(cmd, "Failed Login")) {
|
||||
if (strcasecmp(cmd, "Connect") == 0
|
||||
|| strcasecmp(cmd, "Quit") == 0
|
||||
|| strcasecmp(cmd, "Failed Login") == 0)
|
||||
{
|
||||
do_objs_cmds_check = false;
|
||||
}
|
||||
}
|
||||
if (num_record_cmds > 0 && do_objs_cmds_check) {
|
||||
|
||||
if (num_record_cmds > 0 && do_objs_cmds_check)
|
||||
{
|
||||
const char *cmd = pThdData->getCmdName();
|
||||
const char *cmds[2];
|
||||
cmds[0] = cmd;
|
||||
cmds[1] = NULL;
|
||||
if (!check_array(cmds, (char *) record_cmds_array, MAX_COMMAND_CHAR_NUMBERS)) {
|
||||
if (! check_array(cmds, (char *) record_cmds_array, MAX_COMMAND_CHAR_NUMBERS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (num_record_objs > 0 && do_objs_cmds_check) {
|
||||
|
||||
if (num_record_objs > 0 && do_objs_cmds_check)
|
||||
{
|
||||
bool matched = false;
|
||||
if (pThdData->startGetObjects())
|
||||
{
|
||||
|
@ -270,13 +291,16 @@ static void audit(ThdSesData *pThdData)
|
|||
{
|
||||
matched = record_empty_objs_set;
|
||||
}
|
||||
if (!matched) {
|
||||
if (! matched)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pThdPrintedList && pThdPrintedList->cur_index < MAX_NUM_QUEUE_ELEM)
|
||||
{
|
||||
//audit the event if we haven't done so yet or in the case of prepare_sql we audit as the test "test select" doesn't go through mysql_execute_command
|
||||
// audit the event if we haven't done so yet or in the case of prepare_sql
|
||||
// we audit as the test "test select" doesn't go through mysql_execute_command
|
||||
if (pThdPrintedList->is_thd_printed_queue[pThdPrintedList->cur_index] == 0 || strcmp(pThdData->getCmdName(), "prepare_sql") == 0)
|
||||
{
|
||||
Audit_handler::log_audit_all(pThdData);
|
||||
|
@ -291,6 +315,7 @@ static void audit(ThdSesData *pThdData)
|
|||
{
|
||||
Audit_handler::log_audit_all(pThdData);
|
||||
}
|
||||
|
||||
if (delay_ms_val > 0)
|
||||
{
|
||||
const char * cmd = pThdData->getCmdName();
|
||||
|
@ -326,7 +351,6 @@ static int (*trampoline_open_tables)(THD *thd, TABLE_LIST **start, uint *counter
|
|||
|
||||
QueryTableInf *Audit_formatter::getQueryCacheTableList1(THD *thd)
|
||||
{
|
||||
|
||||
return (QueryTableInf*) THDVAR(thd, query_cache_table_list);
|
||||
}
|
||||
|
||||
|
@ -356,7 +380,6 @@ static bool audit_check_table_access(THD *thd, ulong want_access,TABLE_LIST *tab
|
|||
}
|
||||
pTables = pTables->next_global;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -373,12 +396,12 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, const LEX_
|
|||
int res;
|
||||
void *pList = thd_alloc (thd, sizeof (QueryTableInf));
|
||||
|
||||
|
||||
if (pList)
|
||||
{
|
||||
memset (pList,0,sizeof (QueryTableInf));
|
||||
THDVAR(thd, query_cache_table_list) =(ulong)pList;
|
||||
}
|
||||
|
||||
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
|
||||
res = trampoline_send_result_to_client (pthis,thd, sql, query_length);
|
||||
#else
|
||||
|
@ -392,6 +415,7 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, const LEX_
|
|||
THDVAR(thd, query_cache_table_list) = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static unsigned int trampoline_send_result_to_client_size = 0;
|
||||
|
||||
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
|
||||
|
@ -404,7 +428,6 @@ static bool audit_open_tables(THD *thd, const DDL_options_st &options, TABLE_LIS
|
|||
static bool audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
|
||||
Prelocking_strategy *prelocking_strategy)
|
||||
{
|
||||
|
||||
bool res;
|
||||
res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy);
|
||||
#else
|
||||
|
@ -422,11 +445,8 @@ static int audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint f
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int trampoline_open_tables_size = 0;
|
||||
|
||||
|
||||
|
||||
// called by log_slow_statement and general audit event caught by audit interface
|
||||
static void audit_post_execute(THD * thd)
|
||||
{
|
||||
|
@ -452,8 +472,7 @@ static void audit_post_execute(THD * thd)
|
|||
#if MYSQL_VERSION_ID < 50600
|
||||
|
||||
static int plugin_type = MYSQL_DAEMON_PLUGIN;
|
||||
static struct st_mysql_daemon audit_plugin =
|
||||
{ MYSQL_DAEMON_INTERFACE_VERSION };
|
||||
static struct st_mysql_daemon audit_plugin = { MYSQL_DAEMON_INTERFACE_VERSION };
|
||||
|
||||
#else
|
||||
|
||||
|
@ -513,13 +532,11 @@ static struct st_mysql_audit audit_plugin=
|
|||
#else
|
||||
{ (unsigned long) MYSQL_AUDIT_GENERAL_CLASSMASK |
|
||||
MYSQL_AUDIT_CONNECTION_CLASSMASK } /* class mask */
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// some extern definitions which are not in include files
|
||||
extern void log_slow_statement(THD *thd);
|
||||
extern int mysql_execute_command(THD *thd);
|
||||
|
@ -529,16 +546,17 @@ extern int mysql_execute_command(THD *thd);
|
|||
#endif
|
||||
extern struct st_mysql_plugin *mysqld_builtins[];
|
||||
|
||||
|
||||
void remove_hot_functions()
|
||||
{
|
||||
void * target_function = NULL;
|
||||
|
||||
#if MYSQL_VERSION_ID < 50600
|
||||
target_function = (void *) log_slow_statement;
|
||||
remove_hot_patch_function(target_function,
|
||||
(void*) trampoline_log_slow_statement, trampoline_log_slow_statement_size, true);
|
||||
trampoline_log_slow_statement_size = 0;
|
||||
#endif
|
||||
|
||||
#if MYSQL_VERSION_ID < 50505
|
||||
target_function = (void *) check_user;
|
||||
remove_hot_patch_function(target_function,
|
||||
|
@ -593,7 +611,6 @@ void remove_hot_functions ()
|
|||
|
||||
int is_remove_patches(ThdSesData *pThdData)
|
||||
{
|
||||
|
||||
static bool called_once = false;
|
||||
const char *cmd = pThdData->getCmdName();
|
||||
const char *sUninstallPlugin = "uninstall_plugin";
|
||||
|
@ -605,12 +622,13 @@ int is_remove_patches (ThdSesData *pThdData)
|
|||
{
|
||||
if (! uninstall_plugin_enable)
|
||||
{
|
||||
|
||||
my_message(ER_NOT_ALLOWED_COMMAND, "Uninstall AUDIT plugin disabled", MYF(0));
|
||||
return 2;
|
||||
}
|
||||
|
||||
Audit_handler::stop_all();
|
||||
remove_hot_functions();
|
||||
|
||||
if (! called_once)
|
||||
{
|
||||
called_once = true;
|
||||
|
@ -631,6 +649,7 @@ static int audit_mysql_execute_command(THD *thd)
|
|||
{
|
||||
bool firstTime = false;
|
||||
THDPRINTED *pThdPrintedList = GetThdPrintedList(thd);
|
||||
|
||||
if (pThdPrintedList)
|
||||
{
|
||||
if (pThdPrintedList->cur_index < (MAX_NUM_QUEUE_ELEM - 1))
|
||||
|
@ -650,12 +669,19 @@ static int audit_mysql_execute_command(THD *thd)
|
|||
THDVAR(thd,is_thd_printed_list) = (ulong) pThdPrintedList;
|
||||
}
|
||||
}
|
||||
|
||||
ThdSesData thd_data(thd);
|
||||
const char *cmd = thd_data.getCmdName();
|
||||
if (strcasestr (cmd,"alter") !=NULL || strcasestr (cmd,"drop") !=NULL || strcasestr (cmd, "create") !=NULL || strcasestr (cmd, "truncate") !=NULL || strcasestr (cmd, "rename") !=NULL)
|
||||
|
||||
if (strcasestr(cmd, "alter") != NULL ||
|
||||
strcasestr(cmd, "drop") != NULL ||
|
||||
strcasestr(cmd, "create") != NULL ||
|
||||
strcasestr(cmd, "truncate") != NULL ||
|
||||
strcasestr(cmd, "rename") != NULL)
|
||||
{
|
||||
audit(&thd_data);
|
||||
}
|
||||
|
||||
int res;
|
||||
#if defined(MARIADB_BASE_VERSION)
|
||||
if (Audit_formatter::thd_killed(thd) >= KILL_CONNECTION)
|
||||
|
@ -686,11 +712,14 @@ static int audit_mysql_execute_command(THD *thd)
|
|||
res = trampoline_mysql_execute_command(thd);
|
||||
}
|
||||
}
|
||||
|
||||
audit(&thd_data);
|
||||
|
||||
if (pThdPrintedList && pThdPrintedList->cur_index > 0)
|
||||
{
|
||||
pThdPrintedList->cur_index--;
|
||||
}
|
||||
|
||||
if (firstTime)
|
||||
{
|
||||
THDVAR(thd,is_thd_printed_list) = 0;
|
||||
|
@ -699,7 +728,6 @@ static int audit_mysql_execute_command(THD *thd)
|
|||
|
||||
}
|
||||
|
||||
|
||||
#if MYSQL_VERSION_ID < 50600
|
||||
static void audit_log_slow_statement(THD *thd)
|
||||
{
|
||||
|
@ -715,6 +743,7 @@ static int audit_check_user(THD *thd, enum enum_server_command command,
|
|||
{
|
||||
int res = trampoline_check_user(thd, command, passwd, passwd_len, db, check_count);
|
||||
ThdSesData ThdData(thd);
|
||||
|
||||
audit(&ThdData);
|
||||
|
||||
return (res);
|
||||
|
@ -726,17 +755,20 @@ static bool audit_acl_authenticate(THD *thd, uint connect_errors, uint com_chang
|
|||
{
|
||||
bool res = trampoline_acl_authenticate(thd, connect_errors, com_change_user_pkt_len);
|
||||
ThdSesData ThdData(thd);
|
||||
|
||||
audit(&ThdData);
|
||||
|
||||
return (res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool parse_thd_offsets_string (char *poffsets_string)
|
||||
{
|
||||
|
||||
char offset_str[2048] = {0};
|
||||
char *poffset_str = offset_str;
|
||||
|
||||
strncpy(poffset_str,poffsets_string,array_elements(offset_str));
|
||||
|
||||
char *comma_delimiter = strchr(poffset_str, ',');
|
||||
size_t i = 0;
|
||||
OFFSET *pOffset;
|
||||
|
@ -745,8 +777,10 @@ static bool parse_thd_offsets_string (char *poffsets_string)
|
|||
for (size_t j = 0; j < len; j++)
|
||||
{
|
||||
if (!((poffset_str[j] >= '0' && poffset_str[j] <= '9') || poffset_str[j] == ' ' || poffset_str[j] == ','))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (poffset_str != NULL)
|
||||
{
|
||||
comma_delimiter = strchr(poffset_str, ',');
|
||||
|
@ -754,6 +788,7 @@ static bool parse_thd_offsets_string (char *poffsets_string)
|
|||
{
|
||||
*comma_delimiter = '\0';
|
||||
}
|
||||
|
||||
pOffset = (OFFSET *) &Audit_formatter::thd_offsets.query_id + i;
|
||||
if ((size_t)pOffset- (size_t)&Audit_formatter::thd_offsets < sizeof(Audit_formatter::thd_offsets))
|
||||
{
|
||||
|
@ -768,7 +803,9 @@ static bool parse_thd_offsets_string (char *poffsets_string)
|
|||
sql_print_error("%s Failed parsing audit_offsets: too many offsets specified", log_prefix);
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (comma_delimiter)
|
||||
{
|
||||
poffset_str = comma_delimiter + 1;
|
||||
|
@ -778,6 +815,7 @@ static bool parse_thd_offsets_string (char *poffsets_string)
|
|||
poffset_str = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// validate that we got all offsets. If there is still space in thd_offsets then we didn't get all offsets
|
||||
pOffset = (OFFSET*)&Audit_formatter::thd_offsets.query_id + i;
|
||||
if ((size_t)pOffset- (size_t)&Audit_formatter::thd_offsets < sizeof (Audit_formatter::thd_offsets))
|
||||
|
@ -793,6 +831,7 @@ static bool validate_offsets(const ThdOffsets * offset)
|
|||
// check that offsets are actually correct. We use a buff of memory as a dummy THD (32K is high enough)
|
||||
char buf[32*1024] = {0};
|
||||
THD *thd = (THD *)buf;
|
||||
|
||||
// sanity check that offsets match
|
||||
|
||||
// we set the thread id to a value using the offset and then check that the value matches what thd_get_thread_id returns
|
||||
|
@ -807,14 +846,17 @@ static bool validate_offsets(const ThdOffsets * offset)
|
|||
(unsigned long) res);
|
||||
return false;
|
||||
}
|
||||
|
||||
// extended validation via security_context method
|
||||
// can be disabled via: audit_validate_offsets_extended=OFF
|
||||
if (validate_offsets_extended_enable)
|
||||
{
|
||||
const query_id_t query_id_test_val = 789;
|
||||
(*(query_id_t *) (((char *) thd)+ offset->query_id)) = query_id_test_val;
|
||||
|
||||
Security_context *sctx = (Security_context *) (((unsigned char *) thd) + offset->main_security_ctx);
|
||||
char user_test_val[] = "aud_tusr";
|
||||
|
||||
if (! offset->sec_ctx_user) // use compiled header
|
||||
{
|
||||
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
|
||||
|
@ -827,6 +869,7 @@ static bool validate_offsets(const ThdOffsets * offset)
|
|||
{
|
||||
(*(const char **) (((unsigned char *) sctx) + offset->sec_ctx_user)) = user_test_val;
|
||||
}
|
||||
|
||||
char buffer[2048] = {0};
|
||||
thd_security_context(thd, buffer, 2048, 1000);
|
||||
|
||||
|
@ -857,6 +900,7 @@ static bool calc_file_md5(const char * file_name, char * digest_str)
|
|||
File fd;
|
||||
unsigned char digest[16] = {0};
|
||||
bool ret = false;
|
||||
|
||||
if ((fd = my_open(file_name, O_RDONLY, MYF(MY_WME))) < 0)
|
||||
{
|
||||
sql_print_error("%s Failed file open: [%s], errno: %d.",
|
||||
|
@ -879,6 +923,7 @@ static bool calc_file_md5(const char * file_name, char * digest_str)
|
|||
}
|
||||
}
|
||||
while (res > 0);
|
||||
|
||||
if (res == 0) // reached end of file
|
||||
{
|
||||
my_MD5Final(digest, &context);
|
||||
|
@ -889,7 +934,9 @@ static bool calc_file_md5(const char * file_name, char * digest_str)
|
|||
sql_print_error("%s Failed program read. res: %zd, errno: %d.",
|
||||
log_prefix, res, errno);
|
||||
}
|
||||
|
||||
(void) my_close(fd, MYF(0));
|
||||
|
||||
if (ret) // we got the digest
|
||||
{
|
||||
for (int j = 0; j < 16; j++)
|
||||
|
@ -944,6 +991,7 @@ static int setup_offsets()
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_thd_offsets_string (offsets_string))
|
||||
{
|
||||
sql_print_information ("%s setup_offsets Audit_formatter::thd_offsets values: %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu", log_prefix,
|
||||
|
@ -971,6 +1019,7 @@ static int setup_offsets()
|
|||
sql_print_error("%s Failed parsing audit_offsets: %s", log_prefix, offsets_string);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
sql_print_information ("%s Validation passed. Using offsets from audit_offsets: %s",log_prefix, offsets_string);
|
||||
DBUG_RETURN(0);
|
||||
// exit from function
|
||||
|
@ -985,7 +1034,7 @@ static int setup_offsets()
|
|||
offset = thd_offsets_arr + i;
|
||||
if (strlen(offset->md5digest) > 0)
|
||||
{
|
||||
if (!strncasecmp(digest_str, offset->md5digest, 32))
|
||||
if (strncasecmp(digest_str, offset->md5digest, 32) == 0)
|
||||
{
|
||||
sql_print_information("%s Checksum verified. Using offsets from offset version: %s (%s)", log_prefix, offset->version, digest_str);
|
||||
Audit_formatter::thd_offsets = *offset;
|
||||
|
@ -995,6 +1044,7 @@ static int setup_offsets()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (offsets_by_version_enable)
|
||||
{
|
||||
bool server_is_ndb = strstr(server_version, "ndb") != NULL;
|
||||
|
@ -1008,10 +1058,12 @@ static int setup_offsets()
|
|||
if (dash) // we use the version string up to the '-'
|
||||
{
|
||||
size_t tocopy = dash - version;
|
||||
if(tocopy > 15) tocopy = 15; //sanity
|
||||
if (tocopy > 15)
|
||||
tocopy = 15; // sanity
|
||||
strncpy(version_stripped, version, tocopy);
|
||||
version = version_stripped;
|
||||
}
|
||||
|
||||
if (strstr(server_version, version))
|
||||
{
|
||||
if (server_is_ndb == version_is_ndb)
|
||||
|
@ -1024,7 +1076,8 @@ static int setup_offsets()
|
|||
}
|
||||
else
|
||||
{
|
||||
//try doing 24 byte decrement on THD offsets. Seen that on Ubuntu/Debian this is valid. On 5.6 this is 16 bytes.
|
||||
// try doing 24 byte decrement on THD offsets.
|
||||
// Seen that on Ubuntu/Debian this is valid. On 5.6 this is 16 bytes.
|
||||
#if MYSQL_VERSION_ID < 50600
|
||||
OFFSET dec = 24;
|
||||
#else
|
||||
|
@ -1100,11 +1153,13 @@ const char * retrieve_command (THD * thd, bool & is_sql_cmd)
|
|||
{
|
||||
command = COM_END;
|
||||
}
|
||||
|
||||
// check if from query cache. If so set to select and return
|
||||
if (THDVAR(thd, query_cache_table_list) != 0)
|
||||
{
|
||||
return "select";
|
||||
}
|
||||
|
||||
const int sql_command = thd_sql_command(thd);
|
||||
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
|
||||
if (command == COM_QUERY && sql_command >= 0 && sql_command < SQLCOM_END)
|
||||
|
@ -1115,13 +1170,17 @@ const char * retrieve_command (THD * thd, bool & is_sql_cmd)
|
|||
is_sql_cmd = true;
|
||||
cmd = com_status_vars_array[sql_command].name;
|
||||
}
|
||||
|
||||
if (! cmd)
|
||||
{
|
||||
cmd = command_name[command].str;
|
||||
}
|
||||
|
||||
const char *user = Audit_formatter::thd_inst_main_security_ctx_user(thd);
|
||||
const char *priv_user = Audit_formatter::thd_inst_main_security_ctx_priv_user(thd);
|
||||
if (strcmp (cmd, "Connect") ==0 && ((user && strcmp(user, "event_scheduler") != 0) && (priv_user == NULL || *priv_user == 0x0)))
|
||||
if (strcmp(cmd, "Connect") == 0 &&
|
||||
((user && strcmp(user, "event_scheduler") != 0) &&
|
||||
(priv_user == NULL || *priv_user == 0x0)))
|
||||
{
|
||||
cmd = "Failed Login";
|
||||
}
|
||||
|
@ -1133,10 +1192,12 @@ static int set_com_status_vars_array ()
|
|||
DBUG_ENTER("set_com_status_vars_array");
|
||||
SHOW_VAR *com_status_vars;
|
||||
int sv_idx = 0;
|
||||
|
||||
while (strcmp(status_vars[sv_idx].name,"Com") != 0 && status_vars[sv_idx].name != NullS)
|
||||
{
|
||||
sv_idx++;
|
||||
}
|
||||
|
||||
if (strcmp(status_vars[sv_idx].name,"Com") == 0)
|
||||
{
|
||||
com_status_vars = (SHOW_VAR *) status_vars[sv_idx].value;
|
||||
|
@ -1147,14 +1208,17 @@ static int set_com_status_vars_array ()
|
|||
{
|
||||
status_vars_index++;
|
||||
}
|
||||
|
||||
if (strcmp(com_status_vars[status_vars_index].name,"select") != 0)
|
||||
{
|
||||
sql_print_error("%s Failed finding 'select' index in com_status_vars: [%p]. Plugin Init failed.",
|
||||
log_prefix, com_status_vars);
|
||||
DBUG_RETURN (1);
|
||||
}
|
||||
|
||||
size_t initial_offset = (size_t) com_status_vars[status_vars_index].value;
|
||||
status_vars_index = 0;
|
||||
|
||||
while (com_status_vars[status_vars_index].name != NullS)
|
||||
{
|
||||
int sql_command_idx = ((size_t)(com_status_vars[status_vars_index].value) - (initial_offset)) / sizeof (ulong);
|
||||
|
@ -1177,14 +1241,15 @@ static int set_com_status_vars_array ()
|
|||
}
|
||||
DBUG_RETURN (0);
|
||||
}
|
||||
static int string_to_array(const void *save, void *array,
|
||||
int rows, int length)
|
||||
|
||||
static int string_to_array(const void *save, void *array, int rows, int length)
|
||||
{
|
||||
const char *save_string;
|
||||
save_string = *static_cast<const char* const *> (save);
|
||||
char *string_array;
|
||||
string_array = (char *) array;
|
||||
int r = 0;
|
||||
|
||||
if (save_string != NULL)
|
||||
{
|
||||
int p = 0;
|
||||
|
@ -1234,8 +1299,10 @@ __attribute__ ((noinline)) static void trampoline_dummy_func_for_mem()
|
|||
{
|
||||
TRAMPOLINE_NOP_DEF
|
||||
}
|
||||
|
||||
// holds memory used for trampoline
|
||||
static void *trampoline_mem = NULL;
|
||||
|
||||
// pointer to current free mem
|
||||
static void *trampoline_mem_free = NULL;
|
||||
|
||||
|
@ -1248,8 +1315,8 @@ static int do_hot_patch(void ** trampoline_func_pp, unsigned int * trampoline_si
|
|||
// 16 byte align the pointer
|
||||
DATATYPE_ADDRESS addrs = (DATATYPE_ADDRESS)trampoline_mem_free + 15;
|
||||
*trampoline_func_pp = (void*)(addrs & ~0x0F);
|
||||
//hot patch functions
|
||||
|
||||
// hot patch functions
|
||||
int res = hot_patch_function(target_function, audit_function,
|
||||
*trampoline_func_pp, trampoline_size, true);
|
||||
if (res != 0)
|
||||
|
@ -1305,8 +1372,8 @@ static void password_masking_regex_string_update(THD *thd, struct st_mysql_sys_v
|
|||
// if a string value supplied, check that it compiles
|
||||
if (*str_val)
|
||||
{
|
||||
int res = json_formatter.compile_password_masking_regex(str_val);
|
||||
if (res != 0) // fails compilation
|
||||
bool res = json_formatter.compile_password_masking_regex(str_val);
|
||||
if (! res) // fails compilation
|
||||
{
|
||||
// copy in default pw
|
||||
strncpy(password_masking_regex_buff, default_pw_masking_regex, array_elements(password_masking_regex_buff) - 1);
|
||||
|
@ -1376,16 +1443,19 @@ static void json_socket_name_update(THD *thd, struct st_mysql_sys_var *var, void
|
|||
|
||||
size_t indx = strlen(name_prefix); // count how much to move forward the buff
|
||||
strncpy(json_socket_name_buff, name_prefix, buff_len);
|
||||
|
||||
char cwd_buff[512] = {0};
|
||||
my_getwd(cwd_buff, array_elements(cwd_buff) - 1, 0);
|
||||
replace_char(cwd_buff, '/', '_');
|
||||
size_t cwd_len = strlen(cwd_buff);
|
||||
|
||||
if (cwd_len > 0 && '_' != cwd_buff[cwd_len-1]) // add _ to end
|
||||
{
|
||||
strncpy(cwd_buff + cwd_len, "_", array_elements(cwd_buff) - 1 - cwd_len);
|
||||
}
|
||||
strncpy(json_socket_name_buff + indx, cwd_buff, buff_len - indx);
|
||||
indx += cwd_len;
|
||||
|
||||
if (indx < buff_len)
|
||||
{
|
||||
if (mysqld_port > 0)
|
||||
|
@ -1444,16 +1514,15 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
sql_print_information("%s Set record_empty_objs: %d", log_prefix, record_empty_objs_set);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize the plugin installation.
|
||||
|
||||
SYNOPSIS
|
||||
audit_plugin_init()
|
||||
|
||||
RETURN VALUE
|
||||
0 success
|
||||
1 failure
|
||||
* Initialize the plugin installation.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* audit_plugin_init()
|
||||
*
|
||||
* RETURN VALUE
|
||||
* 0 success
|
||||
* 1 failure
|
||||
*/
|
||||
static int audit_plugin_init(void *p)
|
||||
{
|
||||
|
@ -1481,27 +1550,35 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (delay_cmds_string != NULL) {
|
||||
if (delay_cmds_string != NULL)
|
||||
{
|
||||
delay_cmds_string_update(NULL, NULL, NULL, &delay_cmds_string);
|
||||
}
|
||||
if (whitelist_cmds_string != NULL) {
|
||||
if (whitelist_cmds_string != NULL)
|
||||
{
|
||||
whitelist_cmds_string_update(NULL, NULL, NULL, &whitelist_cmds_string);
|
||||
}
|
||||
if (record_cmds_string != NULL) {
|
||||
if (record_cmds_string != NULL)
|
||||
{
|
||||
record_cmds_string_update(NULL, NULL, NULL, &record_cmds_string);
|
||||
}
|
||||
if (whitelist_users_string != NULL) {
|
||||
if (whitelist_users_string != NULL)
|
||||
{
|
||||
whitelist_users_string_update(NULL, NULL, NULL, &whitelist_users_string);
|
||||
}
|
||||
if (record_objs_string != NULL) {
|
||||
if (record_objs_string != NULL)
|
||||
{
|
||||
record_objs_string_update_extended(NULL, NULL, NULL, &record_objs_string);
|
||||
}
|
||||
if (NULL != password_masking_cmds_string) {
|
||||
if (NULL != password_masking_cmds_string)
|
||||
{
|
||||
password_masking_cmds_string_update(NULL, NULL, NULL, &password_masking_cmds_string);
|
||||
}
|
||||
if (NULL != password_masking_regex_string) {
|
||||
if (NULL != password_masking_regex_string)
|
||||
{
|
||||
password_masking_regex_string_update(NULL, NULL, NULL, &password_masking_regex_string);
|
||||
}
|
||||
|
||||
// update to generate the default if needed
|
||||
json_socket_name_update(NULL, NULL, NULL, &(json_socket_handler.m_io_dest));
|
||||
|
||||
|
@ -1517,6 +1594,7 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
log_prefix, res);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
res = json_socket_handler.init(&json_formatter);
|
||||
if (res != 0)
|
||||
{
|
||||
|
@ -1525,13 +1603,12 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
log_prefix, res);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
// enable according to what we have in *file_handler_enable (this is set accordingly by sysvar functionality)
|
||||
json_file_handler.set_enable(json_file_handler_enable);
|
||||
json_socket_handler.set_enable(json_socket_handler_enable);
|
||||
Audit_handler::m_audit_handler_list[Audit_handler::JSON_FILE_HANDLER]
|
||||
= &json_file_handler;
|
||||
Audit_handler::m_audit_handler_list[Audit_handler::JSON_SOCKET_HANDLER]
|
||||
= &json_socket_handler;
|
||||
Audit_handler::m_audit_handler_list[Audit_handler::JSON_FILE_HANDLER] = &json_file_handler;
|
||||
Audit_handler::m_audit_handler_list[Audit_handler::JSON_SOCKET_HANDLER] = &json_socket_handler;
|
||||
|
||||
// align our trampoline mem on its own page
|
||||
const unsigned long page_size = GETPAGESIZE();
|
||||
|
@ -1561,6 +1638,7 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
}
|
||||
}
|
||||
trampoline_mem_free = trampoline_mem;
|
||||
|
||||
// hot patch stuff
|
||||
void * target_function = NULL;
|
||||
|
||||
|
@ -1570,6 +1648,7 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
target_function = (void*)
|
||||
(int (*)(THD *thd, bool first_level)) &mysql_execute_command;
|
||||
#endif
|
||||
|
||||
if (do_hot_patch((void **)&trampoline_mysql_execute_command, &trampoline_mysql_execute_size,
|
||||
target_function, (void *)audit_mysql_execute_command, "mysql_execute_command"))
|
||||
{
|
||||
|
@ -1586,7 +1665,6 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if MYSQL_VERSION_ID < 50505
|
||||
if (do_hot_patch((void **)&trampoline_check_user, &trampoline_check_user_size,
|
||||
(void *)check_user, (void *)audit_check_user, "check_user"))
|
||||
|
@ -1632,6 +1710,7 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (set_com_status_vars_array () != 0)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
|
@ -1641,16 +1720,15 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
|
|||
}
|
||||
|
||||
/*
|
||||
plugin deinstallation.
|
||||
|
||||
SYNOPSIS
|
||||
audit_plugin_deinit()
|
||||
Does nothing.
|
||||
|
||||
RETURN VALUE
|
||||
0 success
|
||||
1 failure (cannot happen)
|
||||
|
||||
* plugin deinstallation.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* audit_plugin_deinit()
|
||||
* Does nothing.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* 0 success
|
||||
* 1 failure (cannot happen)
|
||||
*/
|
||||
|
||||
static int audit_plugin_deinit(void *p)
|
||||
|
@ -1708,9 +1786,6 @@ static void json_log_file_flush(THD *thd, struct st_mysql_sys_var *var,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void json_log_socket_enable(THD *thd, struct st_mysql_sys_var *var,
|
||||
void *tgt, const void *save)
|
||||
{
|
||||
|
@ -1721,7 +1796,6 @@ static void json_log_socket_enable(THD *thd, struct st_mysql_sys_var *var,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// setup sysvars which update directly the relevant plugins
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(header_msg, json_formatter.m_write_start_msg,
|
||||
|
@ -1922,8 +1996,6 @@ extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
|
|||
extern struct st_mysql_plugin *mysql_mandatory_plugins[];
|
||||
extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
|
||||
{
|
||||
|
||||
|
||||
audit_plugin.interface_version = *(int *) mysql_mandatory_plugins[0]->info;
|
||||
sql_print_information("%s Set interface version to: %d (%d)",
|
||||
log_prefix, audit_plugin.interface_version,
|
||||
|
@ -1948,9 +2020,9 @@ extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
|
|||
#endif
|
||||
|
||||
/*
|
||||
Pure virtual handler. Needed when running in mysql compiled with a newer version of gcc.
|
||||
Versions of mysql for RH 6 and Percona this function is defined local in mysqld.
|
||||
So we define our own implementation.
|
||||
* Pure virtual handler. Needed when running in mysql compiled with a newer version of gcc.
|
||||
* Versions of mysql for RH 6 and Percona this function is defined local in mysqld.
|
||||
* So we define our own implementation.
|
||||
*/
|
||||
extern "C" int __cxa_pure_virtual (void)
|
||||
{
|
||||
|
@ -1964,8 +2036,3 @@ extern "C" int __cxa_pure_virtual (void)
|
|||
* Variable to hold version
|
||||
*/
|
||||
MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION() = '\0';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ static int unprotect(void *addr, size_t len)
|
|||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
res = mprotect(addr, len, PROT_READ|PROT_WRITE);
|
||||
if (0 != res) // log the failure
|
||||
{
|
||||
|
@ -183,9 +184,7 @@ static void WriteJump(void *pAddress, ULONG_PTR JumpTo)
|
|||
*((ULONG_PTR *)pCur) = JumpTo;
|
||||
|
||||
#endif
|
||||
//}
|
||||
|
||||
//DWORD dwBuf = 0; // nessary othewrise the function fails
|
||||
// DWORD dwBuf = 0; // necessary othewrise the function fails
|
||||
|
||||
protect((void*)AddressPage, PAGE_SIZE);
|
||||
}
|
||||
|
@ -222,6 +221,7 @@ static bool HookFunction(ULONG_PTR targetFunction, ULONG_PTR newFunction, ULONG
|
|||
log_prefix, (void *)trampolineFunctionPage);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool disassemble_valid = false;
|
||||
while (ud_disassemble(&ud_obj))
|
||||
{
|
||||
|
@ -232,6 +232,7 @@ static bool HookFunction(ULONG_PTR targetFunction, ULONG_PTR newFunction, ULONG
|
|||
log_prefix, (void *)(InstrSize + targetFunction));
|
||||
break;
|
||||
}
|
||||
|
||||
// make sure there isn't a jmp/call (or similar operand) as these use
|
||||
// relative addressing and if we copy as is we will mess up the jmp/call target
|
||||
if (ud_obj.mnemonic == UD_Ijmp || ud_obj.mnemonic == UD_Icall ||
|
||||
|
@ -255,6 +256,7 @@ static bool HookFunction(ULONG_PTR targetFunction, ULONG_PTR newFunction, ULONG
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect((void*)trampolineFunctionPage, PAGE_SIZE)) // 0 valid return
|
||||
{
|
||||
sql_print_error(
|
||||
|
@ -262,10 +264,12 @@ static bool HookFunction(ULONG_PTR targetFunction, ULONG_PTR newFunction, ULONG
|
|||
log_prefix, (void *)trampolineFunctionPage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! disassemble_valid) // something went wrong. log was written before so return false
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteJump((BYTE*)trampolineFunction + uCurrentSize, targetFunction + InstrSize);
|
||||
WriteJump((void *) targetFunction, newFunction);
|
||||
*trampolinesize = uCurrentSize;
|
||||
|
|
Loading…
Reference in New Issue