From 080112e5cf0a6918d3f133bb785b9f26dae2129a Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 22 May 2024 13:05:04 -0700 Subject: [PATCH] Don't map systemcfg on Power in checkpoint mode On Power `omrtime_current_time_millis` and `omrtime_hires_clock` can use the timebase register to very quickly get the current time. This requires mmapping the special `/proc/ppc64/systemcfg` file. Some security modules (e.g. SELinux) prevent systemcfg from being mapped by user processes. If we take a checkpoint in an environment that that allows systemcfg to be mapped it will not be restorable in an environment that forbids it. This patch disables the mapping of systemcfg in checkpoint mode, which will force the omrtime functions to fall back to conventional Linux time APIs. Signed-off-by: Younes Manton --- port/linuxppc64/omrtime.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/port/linuxppc64/omrtime.c b/port/linuxppc64/omrtime.c index 667fa22a1b3..fe6b69ce0e3 100644 --- a/port/linuxppc64/omrtime.c +++ b/port/linuxppc64/omrtime.c @@ -265,14 +265,28 @@ omrtime_startup(struct OMRPortLibrary *portLibrary) #if !__GLIBC_PREREQ(2,4) systemcfgP_millis = systemcfg_init(); #else - int procfd; + /* Avoid mapping systemcfg if a checkpoint is possible because we may be prevented from + * restoring it in some environments by a security module (e.g. SELinux). If we're currently + * running in an environment that doesn't prevent us from mapping systemcfg, and the + * process is later checkpointed, it can only be restored in an environment that allows + * systemcfg to be mapped. In order to improve portability we'll only map systemcfg if + * no further checkpoints are possible. + */ +#if defined(PPG_criuSupportFlags) + if (OMR_ARE_NO_BITS_SET(PPG_criuSupportFlags, OMRPORT_CRIU_SUPPORT_ENABLED) + || OMR_ARE_ANY_BITS_SET(PPG_criuSupportFlags, OMRPORT_CRIU_SUPPORT_FINAL_RESTORE) + ) +#endif /* defined(PPG_criuSupportFlags) */ + { + int procfd; - procfd = open("/proc/ppc64/systemcfg", O_RDONLY); - if (-1 != procfd) { - systemcfgP_millis = mmap(0, sizeof(struct vdso_data), PROT_READ, MAP_SHARED, procfd, 0); - close(procfd); - if (MAP_FAILED == systemcfgP_millis) { - systemcfgP_millis = NULL; + procfd = open("/proc/ppc64/systemcfg", O_RDONLY); + if (-1 != procfd) { + systemcfgP_millis = mmap(0, sizeof(struct vdso_data), PROT_READ, MAP_SHARED, procfd, 0); + close(procfd); + if (MAP_FAILED == systemcfgP_millis) { + systemcfgP_millis = NULL; + } } } #endif