Skip to content

Commit

Permalink
y2038: elfcore: Use __kernel_old_timeval for process times
Browse files Browse the repository at this point in the history
We store elapsed time for a crashed process in struct elf_prstatus using
'timeval' structures. Once glibc starts using 64-bit time_t, this becomes
incompatible with the kernel's idea of timeval since the structure layout
no longer matches on 32-bit architectures.

This changes the definition of the elf_prstatus structure to use
__kernel_old_timeval instead, which is hardcoded to the currently used
binary layout. There is no risk of overflow in y2038 though, because
the time values are all relative times, and can store up to 68 years
of process elapsed time.

There is a risk of applications breaking at build time when they
use the new kernel headers and expect the type to be exactly 'timeval'
rather than a structure that has the same fields as before. Those
applications have to be modified to deal with 64-bit time_t anyway.

Signed-off-by: Arnd Bergmann <[email protected]>
  • Loading branch information
arndb committed Nov 15, 2019
1 parent 693737b commit e2bb80d
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 22 deletions.
4 changes: 2 additions & 2 deletions arch/mips/kernel/binfmt_elfn32.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value)
#undef TASK_SIZE
#define TASK_SIZE TASK_SIZE32

#undef ns_to_timeval
#define ns_to_timeval ns_to_old_timeval32
#undef ns_to_kernel_old_timeval
#define ns_to_kernel_old_timeval ns_to_old_timeval32

#include "../../../fs/binfmt_elf.c"
4 changes: 2 additions & 2 deletions arch/mips/kernel/binfmt_elfo32.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value)
#undef TASK_SIZE
#define TASK_SIZE TASK_SIZE32

#undef ns_to_timeval
#define ns_to_timeval ns_to_old_timeval32
#undef ns_to_kernel_old_timeval
#define ns_to_kernel_old_timeval ns_to_old_timeval32

#include "../../../fs/binfmt_elf.c"
12 changes: 6 additions & 6 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1489,18 +1489,18 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
* group-wide total, not its individual thread total.
*/
thread_group_cputime(p, &cputime);
prstatus->pr_utime = ns_to_timeval(cputime.utime);
prstatus->pr_stime = ns_to_timeval(cputime.stime);
prstatus->pr_utime = ns_to_kernel_old_timeval(cputime.utime);
prstatus->pr_stime = ns_to_kernel_old_timeval(cputime.stime);
} else {
u64 utime, stime;

task_cputime(p, &utime, &stime);
prstatus->pr_utime = ns_to_timeval(utime);
prstatus->pr_stime = ns_to_timeval(stime);
prstatus->pr_utime = ns_to_kernel_old_timeval(utime);
prstatus->pr_stime = ns_to_kernel_old_timeval(stime);
}

prstatus->pr_cutime = ns_to_timeval(p->signal->cutime);
prstatus->pr_cstime = ns_to_timeval(p->signal->cstime);
prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
}

static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
Expand Down
12 changes: 6 additions & 6 deletions fs/binfmt_elf_fdpic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,17 +1359,17 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
* group-wide total, not its individual thread total.
*/
thread_group_cputime(p, &cputime);
prstatus->pr_utime = ns_to_timeval(cputime.utime);
prstatus->pr_stime = ns_to_timeval(cputime.stime);
prstatus->pr_utime = ns_to_kernel_old_timeval(cputime.utime);
prstatus->pr_stime = ns_to_kernel_old_timeval(cputime.stime);
} else {
u64 utime, stime;

task_cputime(p, &utime, &stime);
prstatus->pr_utime = ns_to_timeval(utime);
prstatus->pr_stime = ns_to_timeval(stime);
prstatus->pr_utime = ns_to_kernel_old_timeval(utime);
prstatus->pr_stime = ns_to_kernel_old_timeval(stime);
}
prstatus->pr_cutime = ns_to_timeval(p->signal->cutime);
prstatus->pr_cstime = ns_to_timeval(p->signal->cstime);
prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);

prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
Expand Down
4 changes: 2 additions & 2 deletions fs/compat_binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
#define elf_prstatus compat_elf_prstatus
#define elf_prpsinfo compat_elf_prpsinfo

#undef ns_to_timeval
#define ns_to_timeval ns_to_old_timeval32
#undef ns_to_kernel_old_timeval
#define ns_to_kernel_old_timeval ns_to_old_timeval32

/*
* To use this file, asm/elf.h must define compat_elf_check_arch.
Expand Down
8 changes: 4 additions & 4 deletions include/uapi/linux/elfcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ struct elf_prstatus
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct timeval pr_utime; /* User time */
struct timeval pr_stime; /* System time */
struct timeval pr_cutime; /* Cumulative user time */
struct timeval pr_cstime; /* Cumulative system time */
struct __kernel_old_timeval pr_utime; /* User time */
struct __kernel_old_timeval pr_stime; /* System time */
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
#if 0
long pr_instr; /* Current instruction */
#endif
Expand Down

0 comments on commit e2bb80d

Please sign in to comment.