Skip to content

Commit

Permalink
gcore: Fix the invalid struct size failure of pid_link on 4.19 and ne…
Browse files Browse the repository at this point in the history
…wer kernel.

On 4.19 and newer kernel, gcore command fails as following:

===========================================================
    gcore: invalid structure size: pid_link
           FILE: libgcore/gcore_coredump_table.c  LINE: 423  FUNCTION: pid_alive()

    [./crash] error trace: 7f4a7a6762b8 => 7f4a7a676e0f => 53b391 => 53b316

      53b316: SIZE_verify.part.31+70
      53b391: SIZE_verify+49

    gcore: invalid structure size: pid_link
           FILE: libgcore/gcore_coredump_table.c  LINE: 423  FUNCTION: pid_alive()

    Failed.
===========================================================

That is because struct pid_link is removed and struct pid array is added to
struct signal_struct by commit 2c4704756cab ("pids: Move the pgrp and session
pid pointers from task_struct to signal_struct").

Get the pointer of struct pid from task_struct->thread_pid or
signal_struct->pids[] to fix the failure.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1722726

Signed-off-by: Masayoshi Mizuma <[email protected]>
  • Loading branch information
HATAYAMA Daisuke authored and d-hatayama committed Jan 22, 2021
1 parent a03d5a5 commit 0370012
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/gcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ static void gcore_offset_table_init(void)
GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_fpsimd_state, "thread_struct", "uw.fpsimd_state");
GCORE_ANON_MEMBER_OFFSET_INIT(thread_struct_tp_value, "thread_struct", "uw.tp_value");
}
if (MEMBER_EXISTS("task_struct", "thread_pid"))
GCORE_MEMBER_OFFSET_INIT(task_struct_thread_pid, "task_struct", "thread_pid");
if (MEMBER_EXISTS("signal_struct", "pids"))
GCORE_MEMBER_OFFSET_INIT(signal_struct_pids, "signal_struct", "pids");
}

static void gcore_size_table_init(void)
Expand Down
48 changes: 40 additions & 8 deletions src/libgcore/gcore_coredump_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ __task_pid_nr_ns(ulong task, enum pid_type type)
sizeof(ns), "__task_pid_nr_ns: ns", gcore_verbose_error_handle());

if (pid_alive(task)) {
ulong pids_type_pid;
ulong pids_type_pid, signal;

if (type != PIDTYPE_PID)
readmem(task + MEMBER_OFFSET("task_struct",
Expand All @@ -233,10 +233,34 @@ __task_pid_nr_ns(ulong task, enum pid_type type)
"__task_pid_nr_ns: group_leader",
gcore_verbose_error_handle());

readmem(task + OFFSET(task_struct_pids) + type * SIZE(pid_link)
+ OFFSET(pid_link_pid), KVADDR, &pids_type_pid,
sizeof(pids_type_pid),
"__task_pid_nr_ns: pids_type_pid", gcore_verbose_error_handle());
if (VALID_MEMBER(task_struct_pids))
readmem(task + OFFSET(task_struct_pids) +
type * SIZE(pid_link) + OFFSET(pid_link_pid),
KVADDR, &pids_type_pid,
sizeof(pids_type_pid),
"__task_pid_nr_ns: pids_type_pid",
gcore_verbose_error_handle());
else
if (type == PIDTYPE_PID)
readmem(task + GCORE_OFFSET(task_struct_thread_pid),
KVADDR, &pids_type_pid,
sizeof(pids_type_pid),
"__task_pid_nr_ns: pids_type_pid",
gcore_verbose_error_handle());
else {
readmem(task + OFFSET(task_struct_signal),
KVADDR, &signal,
sizeof(signal),
"__task_pid_nr_ns: signal",
gcore_verbose_error_handle());

readmem(signal + GCORE_OFFSET(signal_struct_pids) +
type * sizeof(void *),
KVADDR, &pids_type_pid,
sizeof(pids_type_pid),
"__task_pid_nr_ns: pids_type_pid",
gcore_verbose_error_handle());
}

nr = pid_nr_ns(pids_type_pid, ns);
}
Expand Down Expand Up @@ -420,9 +444,17 @@ pid_alive(ulong task)
{
pid_t pid;

readmem(task + OFFSET(task_struct_pids) + PIDTYPE_PID * SIZE(pid_link)
+ OFFSET(pid_link_pid), KVADDR, &pid, sizeof(pid), "pid_alive",
gcore_verbose_error_handle());
if (VALID_MEMBER(task_struct_pids))
readmem(task + OFFSET(task_struct_pids) +
PIDTYPE_PID * SIZE(pid_link) + OFFSET(pid_link_pid),
KVADDR, &pid, sizeof(pid),
"pid_alive",
gcore_verbose_error_handle());
else
readmem(task + GCORE_OFFSET(task_struct_thread_pid),
KVADDR, &pid, sizeof(pid),
"task_struct.thread_pid",
gcore_verbose_error_handle());

return !!pid;
}
2 changes: 2 additions & 0 deletions src/libgcore/gcore_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@ struct gcore_offset_table
long sched_entity_sum_exec_runtime;
long signal_struct_cutime;
long signal_struct_pgrp;
long signal_struct_pids;
long signal_struct_session;
long signal_struct_stime;
long signal_struct_sum_sched_runtime;
Expand All @@ -1090,6 +1091,7 @@ struct gcore_offset_table
long task_struct_static_prio;
long task_struct_uid;
long task_struct_used_math;
long task_struct_thread_pid;
long thread_info_status;
long thread_info_fpstate;
long thread_info_vfpstate;
Expand Down

0 comments on commit 0370012

Please sign in to comment.