Hi Lianbo,
-----Original Message-----
> Does this need further input from my site to get merged? Lianbo acked an
> earlier version[1], so this should be fine as is?
Sorry for the delay. Thanks for your patch, Mathias.
as you commented after the ack, I thought you would check the new
version
again. Can I merge the v3 patch?
Sure. The v3 looks good.
Acked-by: Lianbo Jiang <lijiang(a)redhat.com>
Thanks.
Lianbo
Thanks,
Kazu
>
> Thanks,
> Mathias
>
> [1]
https://www.redhat.com/archives/crash-utility/2020-August/msg00021.html
>
> Am 25.08.20 um 04:09 schrieb HAGIO KAZUHITO(萩尾 一仁):
>> -----Original Message-----
>>> PaX and grsecurity kernels split module memory into dedicated r/x and
>>> r/w mappings using '*_rw' and '*_rx' named member variables
in 'struct
>>> module'. To add basic support for such kernels detect the split layout
>>> by testing for the corresponding structure members and use these
>>> instead.
>>>
>>> So far we limit ourself to only track module code mappings for such
>>> kernels as adding support for separate data mappings violates lots of
>>> invariants in the rest of our code base, thereby would require a major
>>> rework. However, with that patch applied, module code references can be
>>> resolved in backtraces, memory and code dumps, which makes it already
>>> very useful for analyzing such kernels.
>>>
>>> Signed-off-by: Mathias Krause <minipli(a)grsecurity.net>
>>> ---
>>> v3:
>>> - dump offsets unconditional
>>> - fix indention of 'module_init_size' offset dump
>>
>> Thanks for the update. The v3 patch looks good to me.
>>
>> Acked-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
>>
>> Thanks,
>> Kazu
>>
>>>
>>> v2:
>>> - add members to end of struct offset_table
>>> - add offsets to dump_offset_table()
>>>
>>> defs.h | 13 +++++++++++
>>> kernel.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++----
>>> symbols.c | 38 ++++++++++++++++++++++---------
>>> 3 files changed, 103 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/defs.h b/defs.h
>>> index 17e98763362b..ae860448ab15 100644
>>> --- a/defs.h
>>> +++ b/defs.h
>>> @@ -654,12 +654,15 @@ struct new_utsname {
>>> #define TIMER_BASES (0x20ULL)
>>> #define IRQ_DESC_TREE_RADIX (0x40ULL)
>>> #define IRQ_DESC_TREE_XARRAY (0x80ULL)
>>> +#define KMOD_PAX (0x100ULL)
>>>
>>> #define XEN() (kt->flags & ARCH_XEN)
>>> #define OPENVZ() (kt->flags & ARCH_OPENVZ)
>>> #define PVOPS() (kt->flags & ARCH_PVOPS)
>>> #define PVOPS_XEN() (kt->flags & ARCH_PVOPS_XEN)
>>>
>>> +#define PAX_MODULE_SPLIT() (kt->flags2 & KMOD_PAX)
>>> +
>>> #define XEN_MACHINE_TO_MFN(m) ((ulonglong)(m) >> PAGESHIFT())
>>> #define XEN_PFN_TO_PSEUDO(p) ((ulonglong)(p) << PAGESHIFT())
>>>
>>> @@ -2089,6 +2092,14 @@ struct offset_table { /* stash of
commonly-used offsets */
>>> long size_class_size;
>>> long gendisk_private_data;
>>> long zram_table_entry;
>>> + long module_core_size_rw;
>>> + long module_core_size_rx;
>>> + long module_init_size_rw;
>>> + long module_init_size_rx;
>>> + long module_module_core_rw;
>>> + long module_module_core_rx;
>>> + long module_module_init_rw;
>>> + long module_module_init_rx;
>>> };
>>>
>>> struct size_table { /* stash of commonly-used sizes */
>>> @@ -2313,6 +2324,8 @@ struct array_table {
>>> * in the offset table, size table or array_table.
>>> */
>>> #define OFFSET(X) (OFFSET_verify(offset_table.X, (char *)__FUNCTION__,
__FILE__, __LINE__,
> #X))
>>> +#define MODULE_OFFSET(X,Y) (PAX_MODULE_SPLIT() ? OFFSET(Y) : OFFSET(X))
>>> +#define MODULE_OFFSET2(X,T) MODULE_OFFSET(X, X##_##T)
>>> #define SIZE(X) (SIZE_verify(size_table.X, (char *)__FUNCTION__,
__FILE__, __LINE__, #X))
>>> #define INVALID_OFFSET (-1)
>>> #define INVALID_MEMBER(X) (offset_table.X == INVALID_OFFSET)
>>> diff --git a/kernel.c b/kernel.c
>>> index f179375f2d3d..f0268adccd4a 100644
>>> --- a/kernel.c
>>> +++ b/kernel.c
>>> @@ -3540,6 +3540,62 @@ module_init(void)
>>> "module_core");
>>> MEMBER_OFFSET_INIT(module_module_init, "module",
>>> "module_init");
>>> + } else if (MEMBER_EXISTS("module", "module_core_rx"))
{
>>> + if (CRASHDEBUG(1))
>>> + error(INFO, "PaX module layout detected.\n");
>>> + kt->flags2 |= KMOD_PAX;
>>> +
>>> + MEMBER_OFFSET_INIT(module_core_size_rw, "module",
>>> + "core_size_rw");
>>> + MEMBER_OFFSET_INIT(module_core_size_rx, "module",
>>> + "core_size_rx");
>>> +
>>> + MEMBER_OFFSET_INIT(module_init_size_rw, "module",
>>> + "init_size_rw");
>>> + MEMBER_OFFSET_INIT(module_init_size_rx, "module",
>>> + "init_size_rx");
>>> +
>>> + MEMBER_OFFSET_INIT(module_module_core_rw, "module",
>>> + "module_core_rw");
>>> + MEMBER_OFFSET_INIT(module_module_core_rx, "module",
>>> + "module_core_rx");
>>> +
>>> + MEMBER_OFFSET_INIT(module_module_init_rw, "module",
>>> + "module_init_rw");
>>> + MEMBER_OFFSET_INIT(module_module_init_rx, "module",
>>> + "module_init_rx");
>>> + } else if (MEMBER_EXISTS("module_layout", "base_rx"))
{
>>> + if (CRASHDEBUG(1))
>>> + error(INFO, "PaX module layout detected.\n");
>>> + kt->flags2 |= KMOD_PAX;
>>> +
>>> + ASSIGN_OFFSET(module_core_size_rw) =
>>> + MEMBER_OFFSET("module", "core_layout") +
>>> + MEMBER_OFFSET("module_layout", "size_rw");
>>> + ASSIGN_OFFSET(module_core_size_rx) =
>>> + MEMBER_OFFSET("module", "core_layout") +
>>> + MEMBER_OFFSET("module_layout", "size_rx");
>>> +
>>> + ASSIGN_OFFSET(module_init_size_rw) =
>>> + MEMBER_OFFSET("module", "init_layout") +
>>> + MEMBER_OFFSET("module_layout", "size_rw");
>>> + ASSIGN_OFFSET(module_init_size_rx) =
>>> + MEMBER_OFFSET("module", "init_layout") +
>>> + MEMBER_OFFSET("module_layout", "size_rx");
>>> +
>>> + ASSIGN_OFFSET(module_module_core_rw) =
>>> + MEMBER_OFFSET("module", "core_layout") +
>>> + MEMBER_OFFSET("module_layout", "base_rw");
>>> + ASSIGN_OFFSET(module_module_core_rx) =
>>> + MEMBER_OFFSET("module", "core_layout") +
>>> + MEMBER_OFFSET("module_layout", "base_rx");
>>> +
>>> + ASSIGN_OFFSET(module_module_init_rw) =
>>> + MEMBER_OFFSET("module", "init_layout") +
>>> + MEMBER_OFFSET("module_layout", "base_rw");
>>> + ASSIGN_OFFSET(module_module_init_rx) =
>>> + MEMBER_OFFSET("module", "init_layout") +
>>> + MEMBER_OFFSET("module_layout", "base_rx");
>>> } else {
>>> ASSIGN_OFFSET(module_core_size) =
>>> MEMBER_OFFSET("module", "core_layout") +
>>> @@ -3682,10 +3738,10 @@ module_init(void)
>>> case KALLSYMS_V2:
>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
>>> numksyms = UINT(modbuf + OFFSET(module_num_symtab));
>>> - size = UINT(modbuf + OFFSET(module_core_size));
>>> + size = UINT(modbuf + MODULE_OFFSET2(module_core_size, rx));
>>> } else {
>>> numksyms = ULONG(modbuf + OFFSET(module_num_symtab));
>>> - size = ULONG(modbuf + OFFSET(module_core_size));
>>> + size = ULONG(modbuf + MODULE_OFFSET2(module_core_size, rx));
>>> }
>>>
>>> if (!size) {
>>> @@ -3792,7 +3848,7 @@ verify_modules(void)
>>> break;
>>> case KMOD_V2:
>>> mod_base = ULONG(modbuf +
>>> - OFFSET(module_module_core));
>>> + MODULE_OFFSET2(module_module_core, rx));
>>> break;
>>> }
>>>
>>> @@ -3816,10 +3872,10 @@ verify_modules(void)
>>> OFFSET(module_name);
>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27))
>>> mod_size = UINT(modbuf +
>>> - OFFSET(module_core_size));
>>> + MODULE_OFFSET2(module_core_size, rx));
>>> else
>>> mod_size = ULONG(modbuf +
>>> - OFFSET(module_core_size));
>>> + MODULE_OFFSET2(module_core_size, rx));
>>> if (strlen(module_name) < MAX_MOD_NAME)
>>> strcpy(buf, module_name);
>>> else
>>> @@ -5997,6 +6053,8 @@ dump_kernel_table(int verbose)
>>> fprintf(fp, "%sIRQ_DESC_TREE_RADIX", others++ ? "|" :
"");
>>> if (kt->flags2 & IRQ_DESC_TREE_XARRAY)
>>> fprintf(fp, "%sIRQ_DESC_TREE_XARRAY", others++ ? "|" :
"");
>>> + if (kt->flags2 & KMOD_PAX)
>>> + fprintf(fp, "%sKMOD_PAX", others++ ? "|" :
"");
>>> fprintf(fp, ")\n");
>>>
>>> fprintf(fp, " stext: %lx\n", kt->stext);
>>> diff --git a/symbols.c b/symbols.c
>>> index 2fecaee093a2..311fdb7df29e 100644
>>> --- a/symbols.c
>>> +++ b/symbols.c
>>> @@ -1766,17 +1766,17 @@ store_module_symbols_v2(ulong total, int
mods_installed)
>>>
>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
>>> nksyms = UINT(modbuf + OFFSET(module_num_symtab));
>>> - size = UINT(modbuf + OFFSET(module_core_size));
>>> + size = UINT(modbuf + MODULE_OFFSET2(module_core_size, rx));
>>> } else {
>>> nksyms = ULONG(modbuf + OFFSET(module_num_symtab));
>>> - size = ULONG(modbuf + OFFSET(module_core_size));
>>> + size = ULONG(modbuf + MODULE_OFFSET2(module_core_size, rx));
>>> }
>>>
>>> mod_name = modbuf + OFFSET(module_name);
>>>
>>> lm = &st->load_modules[m++];
>>> BZERO(lm, sizeof(struct load_module));
>>> - lm->mod_base = ULONG(modbuf + OFFSET(module_module_core));
>>> + lm->mod_base = ULONG(modbuf + MODULE_OFFSET2(module_module_core, rx));
>>> lm->module_struct = mod;
>>> lm->mod_size = size;
>>> if (strlen(mod_name) < MAX_MOD_NAME)
>>> @@ -1795,23 +1795,23 @@ store_module_symbols_v2(ulong total, int
mods_installed)
>>> lm->mod_flags = MOD_EXT_SYMS;
>>> lm->mod_ext_symcnt = mcnt;
>>> lm->mod_init_module_ptr = ULONG(modbuf +
>>> - OFFSET(module_module_init));
>>> + MODULE_OFFSET2(module_module_init, rx));
>>> if (VALID_MEMBER(module_percpu))
>>> lm->mod_percpu = ULONG(modbuf + OFFSET(module_percpu));
>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
>>> lm->mod_etext_guess = lm->mod_base +
>>> - UINT(modbuf + OFFSET(module_core_text_size));
>>> + UINT(modbuf + MODULE_OFFSET(module_core_text_size,
module_core_size_rx));
>>> lm->mod_init_size =
>>> - UINT(modbuf + OFFSET(module_init_size));
>>> + UINT(modbuf + MODULE_OFFSET2(module_init_size, rx));
>>> lm->mod_init_text_size =
>>> - UINT(modbuf + OFFSET(module_init_text_size));
>>> + UINT(modbuf + MODULE_OFFSET(module_init_text_size,
module_init_size_rx));
>>> } else {
>>> lm->mod_etext_guess = lm->mod_base +
>>> - ULONG(modbuf + OFFSET(module_core_text_size));
>>> + ULONG(modbuf + MODULE_OFFSET(module_core_text_size,
module_core_size_rx));
>>> lm->mod_init_size =
>>> - ULONG(modbuf + OFFSET(module_init_size));
>>> + ULONG(modbuf + MODULE_OFFSET2(module_init_size, rx));
>>> lm->mod_init_text_size =
>>> - ULONG(modbuf + OFFSET(module_init_text_size));
>>> + ULONG(modbuf + MODULE_OFFSET(module_init_text_size,
module_init_size_rx));
>>> }
>>> lm->mod_text_start = lm->mod_base;
>>>
>>> @@ -9119,12 +9119,28 @@ dump_offset_table(char *spec, ulong makestruct)
>>> OFFSET(module_core_size));
>>> fprintf(fp, " module_core_text_size: %ld\n",
>>> OFFSET(module_core_text_size));
>>> - fprintf(fp, " module_init_size: %ld\n",
>>> + fprintf(fp, " module_init_size: %ld\n",
>>> OFFSET(module_init_size));
>>> fprintf(fp, " module_init_text_size: %ld\n",
>>> OFFSET(module_init_text_size));
>>> fprintf(fp, " module_module_init: %ld\n",
>>> OFFSET(module_module_init));
>>> + fprintf(fp, " module_module_core_rx: %ld\n",
>>> + OFFSET(module_module_core_rx));
>>> + fprintf(fp, " module_module_core_rw: %ld\n",
>>> + OFFSET(module_module_core_rw));
>>> + fprintf(fp, " module_core_size_rx: %ld\n",
>>> + OFFSET(module_core_size_rx));
>>> + fprintf(fp, " module_core_size_rw: %ld\n",
>>> + OFFSET(module_core_size_rw));
>>> + fprintf(fp, " module_module_init_rx: %ld\n",
>>> + OFFSET(module_module_init_rx));
>>> + fprintf(fp, " module_module_init_rw: %ld\n",
>>> + OFFSET(module_module_init_rw));
>>> + fprintf(fp, " module_init_size_rx: %ld\n",
>>> + OFFSET(module_init_size_rx));
>>> + fprintf(fp, " module_init_size_rw: %ld\n",
>>> + OFFSET(module_init_size_rw));
>>> fprintf(fp, " module_num_symtab: %ld\n",
>>> OFFSET(module_num_symtab));
>>> fprintf(fp, " module_symtab: %ld\n",
>>> --
>>> 2.20.1
>>>
>>>
>>> --
>>> Crash-utility mailing list
>>> Crash-utility(a)redhat.com
>>>
https://www.redhat.com/mailman/listinfo/crash-utility
>>
>>
>> --
>> Crash-utility mailing list
>> Crash-utility(a)redhat.com
>>
https://www.redhat.com/mailman/listinfo/crash-utility
>>