From 1bb1dc8ff31d984c02a15b310f761ebcd9ceb811 Mon Sep 17 00:00:00 2001 From: Fikret Can Date: Wed, 25 Jan 2023 11:18:55 -0800 Subject: [PATCH 1/5] Linux VM disk encryption: add a systemd service for detecting arrived/changed volumes --- VMEncryption/volume-notif-svc/UdevVolNotif.c | 152 +++++++++++++++++++ VMEncryption/volume-notif-svc/build.sh | 1 + 2 files changed, 153 insertions(+) create mode 100644 VMEncryption/volume-notif-svc/UdevVolNotif.c create mode 100755 VMEncryption/volume-notif-svc/build.sh diff --git a/VMEncryption/volume-notif-svc/UdevVolNotif.c b/VMEncryption/volume-notif-svc/UdevVolNotif.c new file mode 100644 index 000000000..71037603e --- /dev/null +++ b/VMEncryption/volume-notif-svc/UdevVolNotif.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include +#include + +#define LOG_PRIORITY 3 +#define LOG_LEVEL 3 +#define LOG_TO_CONSOLE 1 + +// TODO: Make this a parameter to the program +static const char *LOG_FILE = "/tmp/ade_vol_notif.log"; + +void custom_log(const char *format, ...) { + FILE *log_file = fopen(LOG_FILE, "a"); + if (!log_file) + { + fprintf(stderr, "Can't open log file %s", LOG_FILE); + exit(1); + } + + va_list args; + va_start(args, format); + // Append current date time in UTC. + time_t now = time(NULL); + struct tm *timeinfo; + timeinfo = gmtime(&now); + char bufferTime[80]; + strftime(bufferTime, sizeof(bufferTime), "[%Y-%m-%d %H:%M:%S] :", timeinfo); + fprintf(log_file, "%s ", bufferTime); + vfprintf(log_file, format, args); + fprintf(log_file, "\n"); + fclose(log_file); + va_end(args); + + + if (LOG_TO_CONSOLE) + { + va_start(args, format); + fprintf(stdout, "%s ", bufferTime); + vprintf(format, args); + printf("\n"); + va_end(args); + } + +} + +void sigint_handler(int signum) { + custom_log("Caught SIGINT! Exiting...\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + custom_log("\n\n### Azure Disk Encryption volume notification service ###"); + custom_log("Starting udev volume notification program (%s) with %d args", argv[0], argc); + signal(SIGINT, sigint_handler); + custom_log("Registered SIGINT handler"); + + struct udev *udev; + struct udev_monitor *mon; + int fd; + int ret; + + udev = udev_new(); + if (!udev) { + custom_log("ERROR: Can't create udev (error no=%d)\n", errno); + exit(1); + } + + // Set custom log function + + mon = udev_monitor_new_from_netlink(udev, "udev"); + if (!mon) { + custom_log("ERROR: Can't create udev monitor (error no=%d)\n", errno); + exit(1); + } + + ret = udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "partition" /*"disk"*/); + if (ret < 0) { + custom_log("ERROR: Can't add udev monitor filter (error no=%d)\n", errno); + exit(1); + } + + ret = udev_monitor_enable_receiving(mon); + if (ret < 0) { + custom_log("ERROR: Can't enable udev monitor receiving (error no=%d)\n", errno); + exit(1); + } + + fd = udev_monitor_get_fd(mon); + if (fd < 0) { + custom_log("ERROR: Can't get udev monitor fd (error no=%d)\n", errno); + exit(1); + } + + custom_log("Entering main event loop"); + while (1) { + fd_set fds; + struct timeval tv; + int ret; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = 0; + + ret = select(fd+1, &fds, NULL, NULL, &tv); + + if (ret > 0 && FD_ISSET(fd, &fds)) { + struct udev_device *dev; + + dev = udev_monitor_receive_device(mon); + custom_log("A new udev monitoring event is received!"); + + const char *action = udev_device_get_action(dev); + custom_log("Action: %s", action); + const char *devtype = udev_device_get_devtype(dev); + custom_log("Device type: %s", devtype); + const char *subsystem = udev_device_get_subsystem(dev); + custom_log("Subsystem: %s", subsystem); + const char *devpath = udev_device_get_devpath(dev); + custom_log("Device path: %s", devpath); + const char *devnode = udev_device_get_devnode(dev); + custom_log("Device node: %s", devnode); + int is_initialized = udev_device_get_is_initialized(dev); + custom_log("is_initialized: %d", is_initialized); + const char *fsType = udev_device_get_property_value(dev, "ID_FS_TYPE"); + custom_log("Filesystem type: %s", fsType); + + + if (action != NULL && strcmp(action, "change") == 0) { + // Handle disk volume change event + const char *devnode = udev_device_get_devnode(dev); + custom_log("Device node: %s has changed. Checking if it is encrypted!", devnode); + + // TODO: Call ADE's handle sh with enable action to scan the volumes and encrypt if necessary. + // Detect ADE path. + // system(""); + } + custom_log("Processing udev monitoring event is done!\n"); + udev_device_unref(dev); + } + } + + udev_monitor_unref(mon); + udev_unref(udev); + return 0; +} + diff --git a/VMEncryption/volume-notif-svc/build.sh b/VMEncryption/volume-notif-svc/build.sh new file mode 100755 index 000000000..b98e577b4 --- /dev/null +++ b/VMEncryption/volume-notif-svc/build.sh @@ -0,0 +1 @@ +gcc UdevVolNotif.c -o ade-volume-notif-svc -ludev From a386954ad22041a6f8f424ec3e79a82597f00738 Mon Sep 17 00:00:00 2001 From: Fikret Can Date: Wed, 25 Jan 2023 15:21:58 -0800 Subject: [PATCH 2/5] Linux VM disk encryption: add a systemd service for detecting arrived/changed volumes --- VMEncryption/volume-notif-svc/UdevVolNotif.c | 76 ++++++++++++++++++- .../azure-diskencryption-vol-notif.service | 21 +++++ 2 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service diff --git a/VMEncryption/volume-notif-svc/UdevVolNotif.c b/VMEncryption/volume-notif-svc/UdevVolNotif.c index 71037603e..d0abe1e6e 100644 --- a/VMEncryption/volume-notif-svc/UdevVolNotif.c +++ b/VMEncryption/volume-notif-svc/UdevVolNotif.c @@ -1,23 +1,30 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include #define LOG_PRIORITY 3 #define LOG_LEVEL 3 #define LOG_TO_CONSOLE 1 +#define LOG_DIRETORY "/tmp" +#define LOG_FILE_TEMPLATE "%s/ade_vol_notif-%s.log" + // TODO: Make this a parameter to the program -static const char *LOG_FILE = "/tmp/ade_vol_notif.log"; +static char log_file_path[1024]; void custom_log(const char *format, ...) { - FILE *log_file = fopen(LOG_FILE, "a"); + FILE *log_file = fopen(log_file_path, "a"); if (!log_file) { - fprintf(stderr, "Can't open log file %s", LOG_FILE); + fprintf(stderr, "Can't open log file %s", log_file_path); exit(1); } @@ -45,6 +52,7 @@ void custom_log(const char *format, ...) { va_end(args); } + // TODO: Log to syslog additionally. } void sigint_handler(int signum) { @@ -52,13 +60,75 @@ void sigint_handler(int signum) { exit(0); } +void prepare_log_file() { + // Create log file with date time in UTC. + time_t now = time(NULL); + struct tm *timeinfo; + timeinfo = gmtime(&now); + char current_time[80]; + strftime(current_time, sizeof(current_time), "%Y-%m-%dT%H-%M-%S", timeinfo); + snprintf(log_file_path, sizeof(log_file_path), LOG_FILE_TEMPLATE, LOG_DIRETORY, current_time); +} + +void daemonize(int argc, char *argv[]) +{ + custom_log("Going to daemonize"); + pid_t pid = fork(); + if (pid < 0) { + custom_log("ERROR: Can't fork (error no=%d)\n", errno); + exit(1); + } + if (pid > 0) { + custom_log("Parent process is exiting, pid=%d", pid); + exit(0); + } + umask(0); + pid_t sid = setsid(); + if (sid < 0) { + custom_log("ERROR: Can't set sid (error no=%d)\n", errno); + exit(1); + } + if ((chdir("/")) < 0) { + custom_log("ERROR: Can't change directory (error no=%d)\n", errno); + exit(1); + } + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + //execve(argv[0], argv, NULL); + // char *newargv[] = { NULL }; + // execv(argv[0], newargv); +} + int main(int argc, char *argv[]) { + prepare_log_file(); + custom_log("\n\n### Azure Disk Encryption volume notification service ###"); custom_log("Starting udev volume notification program (%s) with %d args", argv[0], argc); signal(SIGINT, sigint_handler); custom_log("Registered SIGINT handler"); + // Command line options: -d for daemon mode + int c = 0; + int daemon_mode = 0; + while ((c = getopt(argc, argv, "d")) != -1) { + switch (c) { + case 'd': + custom_log("Option for switching to daemon mode provided"); + daemon_mode = 1; + break; + default: + custom_log("Unknown option %c", c); + exit(1); + } + } + + if (daemon_mode) { + daemonize(argc, argv); + } + struct udev *udev; struct udev_monitor *mon; int fd; diff --git a/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service new file mode 100644 index 000000000..f93a32b9e --- /dev/null +++ b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service @@ -0,0 +1,21 @@ +[Unit] +Description=Azure Disk Encryption Volume Notification Services +Before=shutdown.target +After=remote-fs.target +After=systemd-journald-dev-log.socket +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=on-failure +RestartSec=3 +TimeoutSec=30 +IgnoreSIGPIPE=no +KillMode=control-group +ExecStart=/opt/microsoft/azure-diskencryption/bin/ade-volume-notif-svc -d +#ExecStop=/bin/bash -c '$$(which kill) -15 $MAINPID' +Delegate=yes +MemoryMax=50MB + +[Install] +WantedBy=multi-user.target From 9a1d21e2e7a7b599016fae44bc385791488a3ba8 Mon Sep 17 00:00:00 2001 From: PankajJoshi Date: Thu, 13 Apr 2023 09:44:04 +0530 Subject: [PATCH 3/5] integrating ADE in VNS service --- VMEncryption/volume-notif-svc/UdevVolNotif.c | 221 ++++++++++++++++-- .../azure-diskencryption-vol-notif.service | 4 +- VMEncryption/volume-notif-svc/daemon_delay.sh | 29 +++ 3 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 VMEncryption/volume-notif-svc/daemon_delay.sh diff --git a/VMEncryption/volume-notif-svc/UdevVolNotif.c b/VMEncryption/volume-notif-svc/UdevVolNotif.c index d0abe1e6e..cde15c7a0 100644 --- a/VMEncryption/volume-notif-svc/UdevVolNotif.c +++ b/VMEncryption/volume-notif-svc/UdevVolNotif.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -16,13 +18,90 @@ #define LOG_DIRETORY "/tmp" #define LOG_FILE_TEMPLATE "%s/ade_vol_notif-%s.log" +#define ADE_EVENT_THRESHOLD 4 +#define ADE_COUNT_WAIT_TIME 30 +#define ADE_WAIT_TIME 900 +#define ADE_NOT_STARTED "not_started"; +#define ADE_FINISHED "finished"; +#define ADE_RUNNING "running"; + +char* ade_status = ADE_NOT_STARTED; +time_t ade_finished; + // TODO: Make this a parameter to the program static char log_file_path[1024]; +void custom_log(const char *format, ...); + +struct Node{ + struct Node* next; + char* syspath; +}; + +struct Node* createNode(const char* syspath){ + if(syspath == NULL) return NULL; + struct Node* tmp = (struct Node*)malloc(sizeof(struct Node*)); + tmp->next = NULL; + tmp->syspath = (char*) malloc(sizeof(char)*strlen(syspath)); + strcpy(tmp->syspath,syspath); + return tmp; +} + +struct Node** nextNode(struct Node* node){ + if(node==NULL)return NULL; + return &node->next; +} + +void removeNode(struct Node** node){ + if(*node==NULL) { + custom_log("node is null\n"); + return;} + custom_log("removing syspath: %s\n", (*node)->syspath); + struct Node* tmp = *node; + if(tmp->next==NULL){ + *node = NULL; + free(tmp->syspath); + free(tmp); + }else{ + *node=tmp->next; + free(tmp->syspath); + free(tmp); + } +} + +void addNode(struct Node** first, const char* ch){ + struct Node* node = createNode(ch); + if(node==NULL) return; + if(*first==NULL){ + *first = node; + }else{ + node->next = *first; + *first=node; + } +} + +int lstLength(struct Node* first){ + struct Node* tmp = first; + int count =0; + while(tmp!=NULL){ + tmp=tmp->next; + count++; + } + return count; +} +int is_devnode_added(struct Node* first, const char* syspath){ + struct Node* tmp = first; + while(tmp!=NULL){ + if(strcmp(syspath,tmp->syspath)==0) return 1; + tmp=tmp->next; + } + return 0; +} + void custom_log(const char *format, ...) { FILE *log_file = fopen(log_file_path, "a"); - if (!log_file) + if (!log_file) { fprintf(stderr, "Can't open log file %s", log_file_path); exit(1); @@ -51,7 +130,6 @@ void custom_log(const char *format, ...) { printf("\n"); va_end(args); } - // TODO: Log to syslog additionally. } @@ -96,9 +174,74 @@ void daemonize(int argc, char *argv[]) close(STDOUT_FILENO); close(STDERR_FILENO); - //execve(argv[0], argv, NULL); - // char *newargv[] = { NULL }; - // execv(argv[0], newargv); + open("/dev/null",O_RDWR); + dup(0); +} + +void invoke_ade(const char* path){ + ade_status = ADE_RUNNING; + pid_t pAde = fork(); + if(pAde==0){ + // in case of child process. + custom_log("child process %d created, running ADE", getpid()); + custom_log("changing directory to %s", path); + chdir(path); + execl( "extension_shim.sh", + "extension_shim.sh", + "-c", + "main/handle.py --enable --vnscall", + NULL); + int err = errno; + custom_log("Failed to run process! error: %d",err); + exit(1); + } + if(pAde>0){ + pid_t childPid = wait(NULL); + custom_log("child process %d is completed",childPid); + } + //checking if daemon is still running + pid_t pDaemon = fork(); + if(pDaemon==0){ + custom_log("child process %d created, checking daemon", getpid()); + custom_log("changing directory to %s", path); + chdir(path); + execl( "daemon_delay.sh", + "daemon_delay.sh", + "extension_shim.sh", + NULL); + int err = errno; + custom_log("Failed to run process! error: %d",err); + exit(1); + + } + if(pDaemon>0){ + pid_t childPid = wait(NULL); + custom_log("child process %d is completed",childPid); + } + ade_status = ADE_FINISHED; + ade_finished = time(NULL); +} + +int is_device_crypted_from_syspath(const char* syspath){ + struct udev *udev; + int ret = 0; + udev = udev_new(); + struct udev_device* dev = udev_device_new_from_syspath(udev,syspath); + const char* fs_usage = udev_device_get_property_value(dev,"ID_FS_USAGE"); + custom_log("get_dev_fsUsage_from_syspath: syspath %s usage status is %s",syspath, fs_usage); + if(fs_usage!=NULL && strcmp(fs_usage,"crypto")==0) ret = 1; + udev_device_unref(dev); + return ret; +} +void cleanCryptedDevFromList(struct Node** first){ + struct Node** tmp = first; + while(*tmp!=NULL){ + struct Node** rNode = tmp ; + tmp =&((*tmp)->next); + if(is_device_crypted_from_syspath((*rNode)->syspath)){ + removeNode(rNode); + } + } } int main(int argc, char *argv[]) { @@ -125,6 +268,9 @@ int main(int argc, char *argv[]) { } } + char current_working_directory[1024]; + custom_log("current working directory %s\n",getcwd(current_working_directory,1024)); + if (daemon_mode) { daemonize(argc, argv); } @@ -133,6 +279,7 @@ int main(int argc, char *argv[]) { struct udev_monitor *mon; int fd; int ret; + struct Node* first = NULL; udev = udev_new(); if (!udev) { @@ -164,9 +311,12 @@ int main(int argc, char *argv[]) { if (fd < 0) { custom_log("ERROR: Can't get udev monitor fd (error no=%d)\n", errno); exit(1); - } - + } custom_log("Entering main event loop"); + time_t first_dev_node; + first_dev_node = time(NULL); + ade_finished = time(NULL); + int dev_node_count; while (1) { fd_set fds; struct timeval tv; @@ -186,7 +336,7 @@ int main(int argc, char *argv[]) { custom_log("A new udev monitoring event is received!"); const char *action = udev_device_get_action(dev); - custom_log("Action: %s", action); + custom_log("Action: %s", action); const char *devtype = udev_device_get_devtype(dev); custom_log("Device type: %s", devtype); const char *subsystem = udev_device_get_subsystem(dev); @@ -199,24 +349,53 @@ int main(int argc, char *argv[]) { custom_log("is_initialized: %d", is_initialized); const char *fsType = udev_device_get_property_value(dev, "ID_FS_TYPE"); custom_log("Filesystem type: %s", fsType); - - - if (action != NULL && strcmp(action, "change") == 0) { - // Handle disk volume change event - const char *devnode = udev_device_get_devnode(dev); - custom_log("Device node: %s has changed. Checking if it is encrypted!", devnode); - - // TODO: Call ADE's handle sh with enable action to scan the volumes and encrypt if necessary. - // Detect ADE path. - // system(""); + const char *fsUsage = udev_device_get_property_value(dev, "ID_FS_USAGE"); + custom_log("Filesystem Usage: %s", fsUsage); + const char* syspath = udev_device_get_syspath(dev); + custom_log("Syspath : %s", syspath); + + if ( action != NULL && + strcmp(action, "change") == 0 && + fsUsage != NULL && + strcmp(fsUsage, "filesystem") == 0){ + if(is_devnode_added(first,syspath)==0){ + custom_log("adding Device node %s in list\n",devnode); + addNode(&first,syspath); + if(dev_node_count ==0){ + first_dev_node = time(NULL); + } + } } + //ADE generated dev events must be removed from list. + cleanCryptedDevFromList(&first); + custom_log("Processing udev monitoring event is done!\n"); udev_device_unref(dev); } + usleep(250*1000); + dev_node_count = lstLength(first); + int diff_for_ade_loop = (int)difftime(time(NULL),ade_finished); + int diff_for_dev_nodes = dev_node_count>0?(int)difftime(time(NULL),first_dev_node):0; + //Logic to invoke ADE. + if (dev_node_count >= ADE_EVENT_THRESHOLD){ + custom_log("dev node count %d max to trigger %d for running ADE!" + ,dev_node_count,ADE_EVENT_THRESHOLD); + invoke_ade(current_working_directory); + }else if(diff_for_ade_loop>=ADE_WAIT_TIME){ + custom_log("running ADE in every %d sec, last ade run was at %s, diff: %d, dev nodes in list %d" + ,ADE_WAIT_TIME,ctime(&ade_finished),diff_for_ade_loop,dev_node_count); + custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); + invoke_ade(current_working_directory); + }else if(dev_node_count>0 && diff_for_dev_nodes>ADE_COUNT_WAIT_TIME){ + custom_log("running ADE, dev nodes in list %d, last ade run was at %s, diff: %d" + ,dev_node_count,ctime(&first_dev_node),diff_for_dev_nodes); + custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); + invoke_ade(current_working_directory); + }else{ + printf("..."); + } } - udev_monitor_unref(mon); udev_unref(udev); return 0; -} - +} \ No newline at end of file diff --git a/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service index f93a32b9e..2480328c1 100644 --- a/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service +++ b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service @@ -1,7 +1,6 @@ [Unit] Description=Azure Disk Encryption Volume Notification Services Before=shutdown.target -After=remote-fs.target After=systemd-journald-dev-log.socket Conflicts=shutdown.target @@ -12,7 +11,8 @@ RestartSec=3 TimeoutSec=30 IgnoreSIGPIPE=no KillMode=control-group -ExecStart=/opt/microsoft/azure-diskencryption/bin/ade-volume-notif-svc -d +WorkingDirectory=/var/lib/waagent/Microsoft.Azure.Security.Edp.AzureDiskEncryptionForLinuxTest1-1.2.0.105 +ExecStart=/var/lib/waagent/Microsoft.Azure.Security.Edp.AzureDiskEncryptionForLinuxTest1-1.2.0.105/ade-volume-notif-svc -d #ExecStop=/bin/bash -c '$$(which kill) -15 $MAINPID' Delegate=yes MemoryMax=50MB diff --git a/VMEncryption/volume-notif-svc/daemon_delay.sh b/VMEncryption/volume-notif-svc/daemon_delay.sh new file mode 100644 index 000000000..08342a223 --- /dev/null +++ b/VMEncryption/volume-notif-svc/daemon_delay.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +path=`pwd` +script=$1 + +sleeping=30 +shim="$path/$script" +echo $shim +if [ -d $path ]; then + echo $path is valid directory +else + echo wrong direcotry + exit 1 +fi + +if [ -f $shim ]; then + echo $shim is valid file +else + echo "wrong file.. exiting!" + exit 1 +fi +result=`ps -aux|grep daemon|grep $shim` +#result=`ps -aux|grep daemon` +while [ "$result" != "" ] +do + echo "still daemon is running, apply $sleeping second delay" + sleep $sleeping + result=`ps -aux|grep daemon|grep $shim` +done +echo encryption is finished! \ No newline at end of file From 4c9b33d64ec29881bab640628c7ab690189a44aa Mon Sep 17 00:00:00 2001 From: PankajJoshi Date: Mon, 8 May 2023 20:41:39 +0530 Subject: [PATCH 4/5] updating c++ code and build using c++. --- VMEncryption/volume-notif-svc/UdevVolNotif.c | 164 ++++++++---------- .../{daemon_delay.sh => ade_daemon_delay.sh} | 0 .../azure-diskencryption-vol-notif.service | 4 +- VMEncryption/volume-notif-svc/build.sh | 2 +- 4 files changed, 78 insertions(+), 92 deletions(-) rename VMEncryption/volume-notif-svc/{daemon_delay.sh => ade_daemon_delay.sh} (100%) diff --git a/VMEncryption/volume-notif-svc/UdevVolNotif.c b/VMEncryption/volume-notif-svc/UdevVolNotif.c index cde15c7a0..b88857783 100644 --- a/VMEncryption/volume-notif-svc/UdevVolNotif.c +++ b/VMEncryption/volume-notif-svc/UdevVolNotif.c @@ -11,6 +11,11 @@ #include #include #include +#include +#include +#include +#include +#include #define LOG_PRIORITY 3 #define LOG_LEVEL 3 @@ -19,13 +24,11 @@ #define LOG_DIRETORY "/tmp" #define LOG_FILE_TEMPLATE "%s/ade_vol_notif-%s.log" #define ADE_EVENT_THRESHOLD 4 -#define ADE_COUNT_WAIT_TIME 30 -#define ADE_WAIT_TIME 900 -#define ADE_NOT_STARTED "not_started"; -#define ADE_FINISHED "finished"; -#define ADE_RUNNING "running"; +#define ADE_COUNT_WAIT_TIME_SEC 30 +#define ADE_WAIT_TIME_SEC 900 -char* ade_status = ADE_NOT_STARTED; +enum class AdeStatus{ADE_NOT_STARTED,ADE_RUNNING,ADE_FINISHED}; +AdeStatus ade_status = AdeStatus::ADE_NOT_STARTED; time_t ade_finished; @@ -33,72 +36,15 @@ time_t ade_finished; static char log_file_path[1024]; void custom_log(const char *format, ...); -struct Node{ - struct Node* next; - char* syspath; +struct device{ + std::string syspath; + std::string action; }; -struct Node* createNode(const char* syspath){ - if(syspath == NULL) return NULL; - struct Node* tmp = (struct Node*)malloc(sizeof(struct Node*)); - tmp->next = NULL; - tmp->syspath = (char*) malloc(sizeof(char)*strlen(syspath)); - strcpy(tmp->syspath,syspath); - return tmp; +void addNode(std::deque& dq, const char* syspath, const char* action){ + dq.push_back({syspath,action}); } -struct Node** nextNode(struct Node* node){ - if(node==NULL)return NULL; - return &node->next; -} - -void removeNode(struct Node** node){ - if(*node==NULL) { - custom_log("node is null\n"); - return;} - custom_log("removing syspath: %s\n", (*node)->syspath); - struct Node* tmp = *node; - if(tmp->next==NULL){ - *node = NULL; - free(tmp->syspath); - free(tmp); - }else{ - *node=tmp->next; - free(tmp->syspath); - free(tmp); - } -} - -void addNode(struct Node** first, const char* ch){ - struct Node* node = createNode(ch); - if(node==NULL) return; - if(*first==NULL){ - *first = node; - }else{ - node->next = *first; - *first=node; - } -} - -int lstLength(struct Node* first){ - struct Node* tmp = first; - int count =0; - while(tmp!=NULL){ - tmp=tmp->next; - count++; - } - return count; -} -int is_devnode_added(struct Node* first, const char* syspath){ - struct Node* tmp = first; - while(tmp!=NULL){ - if(strcmp(syspath,tmp->syspath)==0) return 1; - tmp=tmp->next; - } - return 0; -} - - void custom_log(const char *format, ...) { FILE *log_file = fopen(log_file_path, "a"); if (!log_file) @@ -179,7 +125,7 @@ void daemonize(int argc, char *argv[]) } void invoke_ade(const char* path){ - ade_status = ADE_RUNNING; + ade_status = AdeStatus::ADE_RUNNING; pid_t pAde = fork(); if(pAde==0){ // in case of child process. @@ -205,8 +151,8 @@ void invoke_ade(const char* path){ custom_log("child process %d created, checking daemon", getpid()); custom_log("changing directory to %s", path); chdir(path); - execl( "daemon_delay.sh", - "daemon_delay.sh", + execl( "ade_daemon_delay.sh", + "ade_daemon_delay.sh", "extension_shim.sh", NULL); int err = errno; @@ -218,7 +164,7 @@ void invoke_ade(const char* path){ pid_t childPid = wait(NULL); custom_log("child process %d is completed",childPid); } - ade_status = ADE_FINISHED; + ade_status = AdeStatus::ADE_FINISHED; ade_finished = time(NULL); } @@ -231,17 +177,46 @@ int is_device_crypted_from_syspath(const char* syspath){ custom_log("get_dev_fsUsage_from_syspath: syspath %s usage status is %s",syspath, fs_usage); if(fs_usage!=NULL && strcmp(fs_usage,"crypto")==0) ret = 1; udev_device_unref(dev); + udev_unref(udev); return ret; } -void cleanCryptedDevFromList(struct Node** first){ - struct Node** tmp = first; - while(*tmp!=NULL){ - struct Node** rNode = tmp ; - tmp =&((*tmp)->next); - if(is_device_crypted_from_syspath((*rNode)->syspath)){ - removeNode(rNode); + +bool is_devnode_added(std::deque&dq, const char* syspath, const char* action){ + for(auto it:dq) + if( strcmp(it.syspath.c_str(),syspath)==0 && + strcmp(it.action.c_str(),action)==0) return true; + return false; +} + +void cleanCryptedDevFromList(std::deque&dq){ + using itdeque=std::deque::iterator; + std::vector cryptedDevices; + //removing crypted changed devices, + for(itdeque it=dq.begin(); it!=dq.end(); it++){ + if( it->action =="change" && + is_device_crypted_from_syspath(it->syspath.c_str())){ + cryptedDevices.push_back(it); } } + //remove previously add crypted devices, which are mounted now. + for(itdeque it=dq.begin(); it!=dq.end(); it++){ + for(auto itd:cryptedDevices){ + if(it==itd) continue; + if(it->action!="change" && it->syspath==itd->syspath){ + cryptedDevices.push_back(it); break; + } + } + } + for(auto it:cryptedDevices){ + dq.erase(it); + } +} + +void printdq(std::deque&dq){ + custom_log("deque item count: %d",dq.size()); + for(auto it:dq){ + custom_log("deque item: action %s, syspath %s",it.action.c_str(), it.syspath.c_str()); + } } int main(int argc, char *argv[]) { @@ -317,6 +292,7 @@ int main(int argc, char *argv[]) { first_dev_node = time(NULL); ade_finished = time(NULL); int dev_node_count; + std::deque dq; while (1) { fd_set fds; struct timeval tv; @@ -355,45 +331,55 @@ int main(int argc, char *argv[]) { custom_log("Syspath : %s", syspath); if ( action != NULL && - strcmp(action, "change") == 0 && + (strcmp(action, "change") == 0 || + strcmp(action, "add") == 0) && fsUsage != NULL && - strcmp(fsUsage, "filesystem") == 0){ - if(is_devnode_added(first,syspath)==0){ + (strcmp(fsUsage, "filesystem") == 0|| + strcmp(fsUsage, "crypto") == 0)){ + if(!is_devnode_added(dq,syspath,action)){ custom_log("adding Device node %s in list\n",devnode); - addNode(&first,syspath); + addNode(dq,syspath,action); if(dev_node_count ==0){ first_dev_node = time(NULL); } } } //ADE generated dev events must be removed from list. - cleanCryptedDevFromList(&first); - + cleanCryptedDevFromList(dq); + printdq(dq); custom_log("Processing udev monitoring event is done!\n"); udev_device_unref(dev); } usleep(250*1000); - dev_node_count = lstLength(first); + dev_node_count = dq.size(); int diff_for_ade_loop = (int)difftime(time(NULL),ade_finished); int diff_for_dev_nodes = dev_node_count>0?(int)difftime(time(NULL),first_dev_node):0; + bool ade_invoked = false; //Logic to invoke ADE. if (dev_node_count >= ADE_EVENT_THRESHOLD){ custom_log("dev node count %d max to trigger %d for running ADE!" ,dev_node_count,ADE_EVENT_THRESHOLD); invoke_ade(current_working_directory); - }else if(diff_for_ade_loop>=ADE_WAIT_TIME){ + ade_invoked=true; + }else if(diff_for_ade_loop>=ADE_WAIT_TIME_SEC){ custom_log("running ADE in every %d sec, last ade run was at %s, diff: %d, dev nodes in list %d" - ,ADE_WAIT_TIME,ctime(&ade_finished),diff_for_ade_loop,dev_node_count); + ,ADE_WAIT_TIME_SEC,ctime(&ade_finished),diff_for_ade_loop,dev_node_count); custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); invoke_ade(current_working_directory); - }else if(dev_node_count>0 && diff_for_dev_nodes>ADE_COUNT_WAIT_TIME){ + ade_invoked=true; + }else if(dev_node_count>0 && diff_for_dev_nodes>ADE_COUNT_WAIT_TIME_SEC){ custom_log("running ADE, dev nodes in list %d, last ade run was at %s, diff: %d" ,dev_node_count,ctime(&first_dev_node),diff_for_dev_nodes); custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); invoke_ade(current_working_directory); + ade_invoked=true; }else{ printf("..."); } + if(ade_invoked){ + first_dev_node = time(NULL); + } + } udev_monitor_unref(mon); udev_unref(udev); diff --git a/VMEncryption/volume-notif-svc/daemon_delay.sh b/VMEncryption/volume-notif-svc/ade_daemon_delay.sh similarity index 100% rename from VMEncryption/volume-notif-svc/daemon_delay.sh rename to VMEncryption/volume-notif-svc/ade_daemon_delay.sh diff --git a/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service index 2480328c1..cbdced018 100644 --- a/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service +++ b/VMEncryption/volume-notif-svc/azure-diskencryption-vol-notif.service @@ -11,8 +11,8 @@ RestartSec=3 TimeoutSec=30 IgnoreSIGPIPE=no KillMode=control-group -WorkingDirectory=/var/lib/waagent/Microsoft.Azure.Security.Edp.AzureDiskEncryptionForLinuxTest1-1.2.0.105 -ExecStart=/var/lib/waagent/Microsoft.Azure.Security.Edp.AzureDiskEncryptionForLinuxTest1-1.2.0.105/ade-volume-notif-svc -d +WorkingDirectory=WorkingDirectory +ExecStart=WorkingDirectory/ade-volume-notif-svc -d #ExecStop=/bin/bash -c '$$(which kill) -15 $MAINPID' Delegate=yes MemoryMax=50MB diff --git a/VMEncryption/volume-notif-svc/build.sh b/VMEncryption/volume-notif-svc/build.sh index b98e577b4..be650722e 100755 --- a/VMEncryption/volume-notif-svc/build.sh +++ b/VMEncryption/volume-notif-svc/build.sh @@ -1 +1 @@ -gcc UdevVolNotif.c -o ade-volume-notif-svc -ludev +gcc -x c++ UdevVolNotif.c -o ade-volume-notif-svc -lstdc++ -ludev \ No newline at end of file From 7c4d79e01983655640ca3739d4c9cbd032c2897e Mon Sep 17 00:00:00 2001 From: PankajJoshi Date: Mon, 22 May 2023 22:51:39 +0530 Subject: [PATCH 5/5] setting ADE retry attempts for a device for VNS --- VMEncryption/volume-notif-svc/UdevVolNotif.c | 55 ++++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/VMEncryption/volume-notif-svc/UdevVolNotif.c b/VMEncryption/volume-notif-svc/UdevVolNotif.c index b88857783..1dd488f85 100644 --- a/VMEncryption/volume-notif-svc/UdevVolNotif.c +++ b/VMEncryption/volume-notif-svc/UdevVolNotif.c @@ -24,6 +24,7 @@ #define LOG_DIRETORY "/tmp" #define LOG_FILE_TEMPLATE "%s/ade_vol_notif-%s.log" #define ADE_EVENT_THRESHOLD 4 +#define ADE_MAX_ATTEMPT_FOR_DEVICE 2 #define ADE_COUNT_WAIT_TIME_SEC 30 #define ADE_WAIT_TIME_SEC 900 @@ -39,10 +40,11 @@ void custom_log(const char *format, ...); struct device{ std::string syspath; std::string action; + int ade_attempt_count; }; void addNode(std::deque& dq, const char* syspath, const char* action){ - dq.push_back({syspath,action}); + dq.push_back({syspath,action,0}); } void custom_log(const char *format, ...) { @@ -124,8 +126,12 @@ void daemonize(int argc, char *argv[]) dup(0); } -void invoke_ade(const char* path){ +void invoke_ade(const char* path,std::deque&dq){ ade_status = AdeStatus::ADE_RUNNING; + //update counter in dq + for(auto item = dq.begin(); item!=dq.end(); item++){ + item->ade_attempt_count+=1; + } pid_t pAde = fork(); if(pAde==0){ // in case of child process. @@ -174,7 +180,6 @@ int is_device_crypted_from_syspath(const char* syspath){ udev = udev_new(); struct udev_device* dev = udev_device_new_from_syspath(udev,syspath); const char* fs_usage = udev_device_get_property_value(dev,"ID_FS_USAGE"); - custom_log("get_dev_fsUsage_from_syspath: syspath %s usage status is %s",syspath, fs_usage); if(fs_usage!=NULL && strcmp(fs_usage,"crypto")==0) ret = 1; udev_device_unref(dev); udev_unref(udev); @@ -191,12 +196,21 @@ bool is_devnode_added(std::deque&dq, const char* syspath, const char* ac void cleanCryptedDevFromList(std::deque&dq){ using itdeque=std::deque::iterator; std::vector cryptedDevices; - //removing crypted changed devices, + //removing crypted changed devices, or attempt count is more than + //ADE_MAX_ATTEMPT_FOR_DEVICE for(itdeque it=dq.begin(); it!=dq.end(); it++){ if( it->action =="change" && is_device_crypted_from_syspath(it->syspath.c_str())){ + custom_log("[removed] change to crypt, syspath %s",it->syspath.c_str()); cryptedDevices.push_back(it); } + else if(it->ade_attempt_count>=ADE_MAX_ATTEMPT_FOR_DEVICE){ + cryptedDevices.push_back(it); + custom_log("[removed] ade attempt count %d is >= %d, syspath %s",it->ade_attempt_count,ADE_MAX_ATTEMPT_FOR_DEVICE,it->syspath.c_str()); + } + else{ + //do nothing + } } //remove previously add crypted devices, which are mounted now. for(itdeque it=dq.begin(); it!=dq.end(); it++){ @@ -244,8 +258,8 @@ int main(int argc, char *argv[]) { } char current_working_directory[1024]; - custom_log("current working directory %s\n",getcwd(current_working_directory,1024)); - + getcwd(current_working_directory,1024) + if (daemon_mode) { daemonize(argc, argv); } @@ -309,26 +323,22 @@ int main(int argc, char *argv[]) { struct udev_device *dev; dev = udev_monitor_receive_device(mon); - custom_log("A new udev monitoring event is received!"); - - const char *action = udev_device_get_action(dev); - custom_log("Action: %s", action); + custom_log("*******************A new udev monitoring event is received!*******************"); + const char *devnode = udev_device_get_devnode(dev); + custom_log("Device node: %s", devnode); const char *devtype = udev_device_get_devtype(dev); - custom_log("Device type: %s", devtype); const char *subsystem = udev_device_get_subsystem(dev); - custom_log("Subsystem: %s", subsystem); + custom_log("Device type: %s, Subsystem: %s",devtype,subsystem); + const char *action = udev_device_get_action(dev); + const char *fsType = udev_device_get_property_value(dev, "ID_FS_TYPE"); + const char *fsUsage = udev_device_get_property_value(dev, "ID_FS_USAGE"); + custom_log("Action: %s, Filesystem type: %s, Filesystem Usage: %s", action,fsType,fsUsage); const char *devpath = udev_device_get_devpath(dev); custom_log("Device path: %s", devpath); - const char *devnode = udev_device_get_devnode(dev); - custom_log("Device node: %s", devnode); int is_initialized = udev_device_get_is_initialized(dev); custom_log("is_initialized: %d", is_initialized); - const char *fsType = udev_device_get_property_value(dev, "ID_FS_TYPE"); - custom_log("Filesystem type: %s", fsType); - const char *fsUsage = udev_device_get_property_value(dev, "ID_FS_USAGE"); - custom_log("Filesystem Usage: %s", fsUsage); const char* syspath = udev_device_get_syspath(dev); - custom_log("Syspath : %s", syspath); + //custom_log("Syspath : %s", syspath); if ( action != NULL && (strcmp(action, "change") == 0 || @@ -359,25 +369,26 @@ int main(int argc, char *argv[]) { if (dev_node_count >= ADE_EVENT_THRESHOLD){ custom_log("dev node count %d max to trigger %d for running ADE!" ,dev_node_count,ADE_EVENT_THRESHOLD); - invoke_ade(current_working_directory); + invoke_ade(current_working_directory,dq); ade_invoked=true; }else if(diff_for_ade_loop>=ADE_WAIT_TIME_SEC){ custom_log("running ADE in every %d sec, last ade run was at %s, diff: %d, dev nodes in list %d" ,ADE_WAIT_TIME_SEC,ctime(&ade_finished),diff_for_ade_loop,dev_node_count); custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); - invoke_ade(current_working_directory); + invoke_ade(current_working_directory,dq); ade_invoked=true; }else if(dev_node_count>0 && diff_for_dev_nodes>ADE_COUNT_WAIT_TIME_SEC){ custom_log("running ADE, dev nodes in list %d, last ade run was at %s, diff: %d" ,dev_node_count,ctime(&first_dev_node),diff_for_dev_nodes); custom_log("diff_for_ade_loop: %d, diff_for_dev_nodes: %d",diff_for_ade_loop,diff_for_dev_nodes); - invoke_ade(current_working_directory); + invoke_ade(current_working_directory,dq); ade_invoked=true; }else{ printf("..."); } if(ade_invoked){ first_dev_node = time(NULL); + cleanCryptedDevFromList(dq); } }