Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Procmon for linux #1427

Merged
merged 3 commits into from
Apr 22, 2022
Merged

Procmon for linux #1427

merged 3 commits into from
Apr 22, 2022

Conversation

delvinru
Copy link
Contributor

Hi, I have added support for linux systems for the procmon plugin.
The plugin was tested on the following system:

Linux ubuntu 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal

I note that this plugin will not work on kernel versions below 5.9, because the plugin is based on do_execveat_common to which all sys_execve calls come in newer version.
I also upgrade the linux_get_process_name function, which can now output the full name of the process, and therefore also improves the filetracer plugin. Now, instead of the short comm name, the full name of the process is printed.

As an example, the output of the plugin:

{
    "Plugin": "procmon",
    "TimeStamp": "1650485324.685135",
    "PID": 1203,
    "TID": 1203,
    "PPID": 1078,
    "ProcessName": "/usr/bin/bash",
    "ThreadName": "bash",
    "Method": "do_execveat_common.isra.0",
    "NewPid": 1291,
    "NewTid": 1291,
    "CommandLine": "ls --color=auto -la",
    "ImagePathName": "/usr/bin/ls"
}

@drakvuf-jenkins
Copy link
Collaborator

Can one of the admins verify this patch?

@tklengyel
Copy link
Owner

@drakvuf-jenkins Test this please

@tklengyel
Copy link
Owner

Fantastic addition, thanks for sending the PR.

@delvinru
Copy link
Contributor Author

Sorry, my bad, i fixed problems🙈

@tklengyel
Copy link
Owner

@drakvuf-jenkins Test this please

@delvinru
Copy link
Contributor Author

delvinru commented Apr 22, 2022

After researching the error for which the pipeline does not pass, I came to the following conclusion:

  1. In different kernel versions, the suffix isra.0 can be added, as for example in ubuntu 20.04 due to an additional flag when compiling the kernel. More information: click.
    Kernel symbols comparisons on ubuntu 20.04 and debian 11:
// Ubuntu 20.04
"do_execveat_common.isra.0": {
    "type": {
        "kind": "base",
        "name": "void"
      },
      "address": 281472849310624
}

// Debian 11
"do_execveat_common": {
      "type": {
        "kind": "base",
        "name": "void"
      },
      "address": 281472848932752
},

As you can see the name is different.

  1. Job DRAKVUF-debian-stretch in ci is running an old version of debian with a kernel that is not suitable for this plugin. (wrote about the limitations above).

As addition, debian 11 can't just be installed in xen, like ubuntu, for example (more information, Debian Installer section). With the default installation approach or using xen-tools or something else, drakvuf will not be able to initialize correctly, even if you adjust the default config.
We'll have to tweak the iso a little and then everything will be set as needed and drakvuf will work. Great guide: https://lists.debian.org/debian-user/2021/08/msg01339.html

Tested Debian version:

Linux debian 5.10.0-13-amd64 #1 SMP Debian 5.10.106-1 (2022-03-17) x86_64 GNU/Linux

Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye

@tklengyel
Copy link
Owner

The plugin should just print a debug message that an old unsupported kernel is detected and exit out gracefully instead of erroring.

@tklengyel
Copy link
Owner

@drakvuf-jenkins Test this please

@tklengyel
Copy link
Owner

LGTM

@tklengyel tklengyel merged commit 6ca7956 into tklengyel:master Apr 22, 2022
@tklengyel
Copy link
Owner

** CID 392391:  Null pointer dereferences  (NULL_RETURNS)
/src/plugins/procmon/linux.cpp: 288 in do_execveat_common_cb(drakvuf *, drakvuf_trap_info *)()


________________________________________________________________________________________________________
*** CID 392391:  Null pointer dereferences  (NULL_RETURNS)
/src/plugins/procmon/linux.cpp: 288 in do_execveat_common_cb(drakvuf *, drakvuf_trap_info *)()
282         if (!ret_addr)
283             return VMI_EVENT_RESPONSE_NONE;
284     
285         linux_procmon* procmon = (linux_procmon*)info->trap->data;
286     
287         linux_wrapper* lw = new (std::nothrow) linux_wrapper;
>>>     CID 392391:  Null pointer dereferences  (NULL_RETURNS)
>>>     Dereferencing "lw", which is known to be "nullptr".
288         lw->procmon = procmon;
289         lw->new_pid = info->proc_data.pid;
290         lw->new_tid = info->proc_data.tid;
291         lw->rsp = ret_addr;
292     
293         char* image_path_name = get_image_path_name(drakvuf, info);

** CID 392390:    (UNINIT_CTOR)
/src/plugins/procmon/linux.cpp: 408 in linux_procmon::linux_procmon(drakvuf *, output_format_t)()
/src/plugins/procmon/linux.cpp: 411 in linux_procmon::linux_procmon(drakvuf *, output_format_t)()


________________________________________________________________________________________________________
*** CID 392390:    (UNINIT_CTOR)
/src/plugins/procmon/linux.cpp: 408 in linux_procmon::linux_procmon(drakvuf *, output_format_t)()
402     
403         if (!register_trap(drakvuf, "do_execveat_common.isra.0", &trap[0], do_execveat_common_cb))
404         {
405             if (!register_trap(drakvuf, "do_execveat_common", &trap[0], do_execveat_common_cb))
406             {
407                 PRINT_DEBUG("[PROCMON] Method do_execveat_common not found. You are probably using an older kernel version below 5.9\n");
>>>     CID 392390:    (UNINIT_CTOR)
>>>     Non-static class member "os" is not initialized in this constructor nor in any functions that it calls.
408                 return;
409             }
410         }
/src/plugins/procmon/linux.cpp: 411 in linux_procmon::linux_procmon(drakvuf *, output_format_t)()
405             if (!register_trap(drakvuf, "do_execveat_common", &trap[0], do_execveat_common_cb))
406             {
407                 PRINT_DEBUG("[PROCMON] Method do_execveat_common not found. You are probably using an older kernel version below 5.9\n");
408                 return;
409             }
410         }
>>>     CID 392390:    (UNINIT_CTOR)
>>>     Non-static class member "os" is not initialized in this constructor nor in any functions that it calls.

** CID 392389:    (UNINIT_CTOR)
/src/plugins/procmon/procmon.cpp: 115 in procmon::procmon(drakvuf *, output_format_t)()
/src/plugins/procmon/procmon.cpp: 115 in procmon::procmon(drakvuf *, output_format_t)()


________________________________________________________________________________________________________
*** CID 392389:    (UNINIT_CTOR)
/src/plugins/procmon/procmon.cpp: 115 in procmon::procmon(drakvuf *, output_format_t)()
109     procmon::procmon(drakvuf_t drakvuf, output_format_t output) : pluginex(drakvuf, output), os(drakvuf_get_os_type(drakvuf))
110     {
111         if (this->os == VMI_OS_WINDOWS)
112             this->wp = new win_procmon(drakvuf, output);
113         else
114             this->lp = new linux_procmon(drakvuf, output);
>>>     CID 392389:    (UNINIT_CTOR)
>>>     Non-static class member "lp" is not initialized in this constructor nor in any functions that it calls.
115     }
116     
117     procmon::~procmon()
118     {
119         if (this->os == VMI_OS_WINDOWS)
120             delete this->wp;
/src/plugins/procmon/procmon.cpp: 115 in procmon::procmon(drakvuf *, output_format_t)()
109     procmon::procmon(drakvuf_t drakvuf, output_format_t output) : pluginex(drakvuf, output), os(drakvuf_get_os_type(drakvuf))
110     {
111         if (this->os == VMI_OS_WINDOWS)
112             this->wp = new win_procmon(drakvuf, output);
113         else
114             this->lp = new linux_procmon(drakvuf, output);
>>>     CID 392389:    (UNINIT_CTOR)
>>>     Non-static class member "wp" is not initialized in this constructor nor in any functions that it calls.
115     }
116     
117     procmon::~procmon()
118     {
119         if (this->os == VMI_OS_WINDOWS)
120             delete this->wp;

** CID 392388:  Resource leaks  (RESOURCE_LEAK)
/src/libdrakvuf/linux-processes.c: 303 in d_path()


________________________________________________________________________________________________________
*** CID 392388:  Resource leaks  (RESOURCE_LEAK)
/src/libdrakvuf/linux-processes.c: 303 in d_path()
297     static GString* d_path(drakvuf_t drakvuf, addr_t process_base, addr_t path)
298     {
299         GString* b = g_string_new("");
300     
301         addr_t root;
302         if (!get_fs_root_rcu(drakvuf, process_base, &root))
>>>     CID 392388:  Resource leaks  (RESOURCE_LEAK)
>>>     Variable "b" going out of scope leaks the storage it points to.
303             return NULL;
304     
305         prepend_path(drakvuf, path, root, b);
306         return b;
307     }
308     

@delvinru delvinru deleted the linux_procmon branch July 26, 2023 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants