From 7591f5b0901978454be9f20c2923cfb0dd87a180 Mon Sep 17 00:00:00 2001 From: Kudrjavtsev Nickita Date: Tue, 5 Mar 2013 15:46:09 +0400 Subject: [PATCH] if swap.ini has undefined path to lib or app driver will return this wrong path --- driver/Kbuild | 2 +- driver/device_driver.c | 9 ++++- driver/ec_ioctl.h | 2 + driver/error_storage.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ driver/error_storage.h | 6 +++ driver/storage.c | 3 ++ driver/storage.h | 4 +- 7 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 driver/error_storage.c create mode 100644 driver/error_storage.h diff --git a/driver/Kbuild b/driver/Kbuild index f7c2c8d..b50621d 100644 --- a/driver/Kbuild +++ b/driver/Kbuild @@ -1,6 +1,6 @@ EXTRA_CFLAGS := $(extra_cflags) obj-m := swap_driver.o -swap_driver-y := device_driver.o ec.o legacy.o module.o probes.o \ +swap_driver-y := error_storage.o device_driver.o ec.o legacy.o module.o probes.o \ probes_manager.o storage.o us_proc_inst.o java_inst.o \ sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_procs.o diff --git a/driver/device_driver.c b/driver/device_driver.c index 9259124..1699aee 100644 --- a/driver/device_driver.c +++ b/driver/device_driver.c @@ -414,6 +414,9 @@ static long device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned l result = -1; break; } + if (has_last_error() == -1) { + result = -1; + } break; } @@ -675,7 +678,11 @@ sad_cleanup: DPRINTF("Get Size of Predefined User Space Probes"); break; } - + case EC_IOCTL_GET_LAST_ERROR: + { + result = get_last_error((void*)arg); + break; + } default: EPRINTF ("Unknown driver command = %u", cmd); result = -EINVAL; diff --git a/driver/ec_ioctl.h b/driver/ec_ioctl.h index 2428235..740e73c 100644 --- a/driver/ec_ioctl.h +++ b/driver/ec_ioctl.h @@ -74,6 +74,8 @@ typedef enum EC_IOCTL_SET_PID, + // error consist of wrong path to apps or libs + EC_IOCTL_GET_LAST_ERROR, } EC_IOCTL_CMD; typedef struct diff --git a/driver/error_storage.c b/driver/error_storage.c new file mode 100644 index 0000000..0398212 --- /dev/null +++ b/driver/error_storage.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include "error_storage.h" + +static int create_errno_buffer(void); +static void delete_errno_buffer(void); +static unsigned int get_max_error_buffer_size(void); + +static struct errno_struct +{ + unsigned int size; + char *buffer; +}; + +static struct errno_struct *last_error = NULL; + +static int create_errno_buffer(void) +{ + struct errno_struct *error = NULL; + if (last_error != NULL){ + return -1; + } + error = (struct errno_struct*)vmalloc(sizeof(struct errno_struct)); + if (error == NULL){ + return -1; + } + error->buffer = vmalloc(MAX_ERROR_BUF_PATH); + if (error->buffer == NULL) + { + vfree(error); + return -1; + } + error->buffer[0] = '\0'; + error->size = 0; + last_error = (struct errno_struct*) error; + + return 0; +} + +static unsigned int get_max_error_buffer_size(void) +{ + return (unsigned int)MAX_ERROR_BUF_PATH; +} + +int update_errno_buffer(const char *buffer) +{ + unsigned int size; + + if (last_error == NULL) + { + if (create_errno_buffer() != 0) + return -1; + } + + size = strlen(buffer); + + if (last_error->size + size + 1 >= get_max_error_buffer_size()) { + return -1; + } + + strncat((char*)(last_error->buffer), buffer, size); + + last_error->size += size + 1; + last_error->buffer[last_error->size - 1] = ','; + last_error->buffer[last_error->size] = '\0'; + + return 0; +} + +static void delete_errno_buffer(void) +{ + if (last_error == NULL) + return; + + vfree((char*)last_error->buffer); + vfree(last_error); + + last_error = NULL; + + return; +} + +int get_last_error(void* u_addr) +{ + int result; + + if (last_error == NULL) + return -1; + + result = copy_to_user ((void*)u_addr, (void*)(last_error->buffer), last_error->size + 1); + if (result) { + result = -EFAULT; + } + + delete_errno_buffer(); + + return result; +} + +int has_last_error() +{ + if(last_error == NULL) + return 0; + return -1; +} diff --git a/driver/error_storage.h b/driver/error_storage.h new file mode 100644 index 0000000..d32b4f1 --- /dev/null +++ b/driver/error_storage.h @@ -0,0 +1,6 @@ +#define MAX_ERROR_BUF_PATH 256 + +// copy error buffer from kernelspace to userspace +int get_last_error(void* u_addr); +int has_last_error(void); +int update_errno_buffer(const char *buffer); diff --git a/driver/storage.c b/driver/storage.c index 393eb17..3542229 100644 --- a/driver/storage.c +++ b/driver/storage.c @@ -700,6 +700,7 @@ int link_bundle(void) if (strcmp(us_proc_info.path, "*")) { us_proc_info.m_f_dentry = dentry_by_path(us_proc_info.path); if (us_proc_info.m_f_dentry == NULL) { + update_errno_buffer(us_proc_info.path); return -1; } } @@ -769,6 +770,7 @@ int link_bundle(void) { if (strcmp(d_lib->path_dyn, "") == 0) { EPRINTF("Cannot find path for lib %s!", d_lib->path); + update_errno_buffer(d_lib->path); /* Just skip all the IPs and go to next lib */ p += d_lib->ips_count * 3 * sizeof(u_int32_t); d_lib->ips_count = 0; @@ -788,6 +790,7 @@ int link_bundle(void) d_lib->m_f_dentry = dentry_by_path(d_lib->path); if (d_lib->m_f_dentry == NULL) { EPRINTF ("failed to lookup dentry for path %s!", d_lib->path); + update_errno_buffer(d_lib->path); /* Just skip all the IPs and go to next lib */ p += d_lib->ips_count * 3 * sizeof(u_int32_t); d_lib->ips_count = 0; diff --git a/driver/storage.h b/driver/storage.h index 4c6289f..a778091 100644 --- a/driver/storage.h +++ b/driver/storage.h @@ -29,6 +29,9 @@ #include "probes.h" #include "event_tmpl.h" +extern int update_errno_buffer(const char *buffer); +extern int get_last_error(void* u_addr); +extern int has_last_error(void); /////////////////////////////////////////////////////////////////////////////////////////////////// extern int EnableContinuousRetrieval(void); @@ -64,7 +67,6 @@ extern void pack_task_event_info (struct task_struct *task, probe_id_t probe_id, /* Set most links from us_proc_info to data in the bundle */ int link_bundle(void); - /* Undo the actions of link_bundle() */ void unlink_bundle(void); -- 2.7.4