static bool can_use_sys_cpu;
static bool has_versioned_opts;
static bool memory_is_cgroupv2;
+static __u32 host_personality;
static volatile sig_atomic_t reload_successful;
return memory_is_cgroupv2;
}
+__u32 liblxcfs_personality(void)
+{
+ return host_personality;
+}
+
/* Define pivot_root() if missing from the C library */
#ifndef HAVE_PIVOT_ROOT
static int pivot_root(const char *new_root, const char *put_old)
goto broken_upgrade;
}
+ if (get_task_personality(getpid(), &host_personality) < 0) {
+ lxcfs_info("Failed to retrieve host personality");
+ goto broken_upgrade;
+ }
+
reload_successful = 1;
return;
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
+#include <sys/personality.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
return total_len;
}
+static int proc_read_with_personality(int (*do_proc_read)(char *, size_t, off_t,
+ struct fuse_file_info *), char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ struct fuse_context *fc = fuse_get_context();
+ __u32 host_personality = liblxcfs_personality(), caller_personality;
+ bool change_personality;
+ int ret, read_ret;
+
+ if (get_task_personality(fc->pid, &caller_personality) < 0)
+ return log_error(0, "Failed to get caller process (pid: %d) personality", fc->pid);
+
+ /* do we need to change thread personality? */
+ change_personality = host_personality != caller_personality;
+
+ if (change_personality) {
+ ret = personality(caller_personality);
+ if (ret == -1)
+ return log_error(0, "Call to personality(%d) failed: %s\n",
+ caller_personality, strerror(errno));
+
+ lxcfs_debug("task (tid: %d) personality was changed %d -> %d\n",
+ (int)syscall(SYS_gettid), ret, caller_personality);
+ }
+
+ read_ret = do_proc_read(buf, size, offset, fi);
+
+ if (change_personality) {
+ ret = personality(host_personality);
+ if (ret == -1)
+ return log_error(0, "Call to personality(%d) failed: %s\n",
+ host_personality, strerror(errno));
+
+ lxcfs_debug("task (tid: %d) personality was restored %d -> %d\n",
+ (int)syscall(SYS_gettid), ret, host_personality);
+ }
+
+ return read_ret;
+}
+
__lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
buf, size, offset, f);
case LXC_TYPE_PROC_CPUINFO:
if (liblxcfs_functional())
- return proc_cpuinfo_read(buf, size, offset, fi);
+ return proc_read_with_personality(&proc_cpuinfo_read, buf, size, offset, fi);
return read_file_fuse_with_offset(LXC_TYPE_PROC_CPUINFO_PATH,
buf, size, offset, f);