diff --git a/configure.ac b/configure.ac index b329b4ea7..76f2e1026 100644 --- a/configure.ac +++ b/configure.ac @@ -629,7 +629,7 @@ AC_CHECK_DECLS([PR_SET_NO_NEW_PRIVS], [], [], [#include ]) AC_CHECK_DECLS([PR_GET_NO_NEW_PRIVS], [], [], [#include ]) # Check for some headers -AC_CHECK_HEADERS([pty.h sys/memfd.h sys/personality.h sys/resource.h sys/signalfd.h sys/timerfd.h utmpx.h]) +AC_CHECK_HEADERS([pty.h sys/memfd.h sys/personality.h sys/resource.h sys/signalfd.h sys/timerfd.h utmpx.h threads.h]) AC_CHECK_HEADER([ifaddrs.h], AM_CONDITIONAL(HAVE_IFADDRS_H, true) diff --git a/src/lxc/compiler.h b/src/lxc/compiler.h index 5d45955d0..353677a5e 100644 --- a/src/lxc/compiler.h +++ b/src/lxc/compiler.h @@ -12,14 +12,23 @@ #include "config.h" -#ifndef thread_local -#if __STDC_VERSION__ >= 201112L && \ - !(defined(__STDC_NO_THREADS__) || \ - (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) -#define thread_local _Thread_local +#if defined(HAVE_THREADS_H) + #include + #define THREAD_LOCAL_STORAGE_SUPPORTED +#elif defined(thread_local) + #define THREAD_LOCAL_STORAGE_SUPPORTED #else -#define thread_local __thread -#endif + #if __STDC_VERSION__ >= 201112L && \ + !(defined(__STDC_NO_THREADS__) || \ + (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) + #define thread_local _Thread_local + + #define THREAD_LOCAL_STORAGE_SUPPORTED + #else + #define thread_local __thread + + #define THREAD_LOCAL_STORAGE_SUPPORTED + #endif #endif #if __GNUC__ >= 7 diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 5c133bbb1..bceb2cebc 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -36,6 +36,7 @@ #include "af_unix.h" #include "caps.h" #include "cgroups/cgroup.h" +#include "compiler.h" #include "conf.h" #include "config.h" #include "confile.h" @@ -99,11 +100,14 @@ lxc_log_define(conf, lxc); -/* The lxc_conf of the container currently being worked on in an API call. +/* + * The lxc_conf of the container currently being worked on in an API call. * This is used in the error calls. */ -#ifdef HAVE_TLS +#if defined(THREAD_LOCAL_STORAGE_SUPPORTED) thread_local struct lxc_conf *current_config; +#elif defined(ENFORCE_THREAD_SAFETY) +#error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed due to missing TLS #else struct lxc_conf *current_config; #endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h index b93c65276..939e47d75 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -474,10 +474,12 @@ struct lxc_conf { __hidden extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, size_t buf_size) __access_r(3, 4); -#ifdef HAVE_TLS +#if defined(THREAD_LOCAL_STORAGE_SUPPORTED) extern thread_local struct lxc_conf *current_config; +#elif defined(ENFORCE_THREAD_SAFETY) +#error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed due to missing TLS #else -extern struct lxc_conf *current_config; +struct lxc_conf *current_config; #endif __hidden extern int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, char *argv[]); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 59fc5704d..5a0cf31be 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -170,114 +170,114 @@ lxc_config_define(proc); * has to be placed above lxc.ab. */ static struct lxc_config_t config_jump_table[] = { - { "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, }, - { "lxc.apparmor.profile", set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, }, - { "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, }, - { "lxc.apparmor.allow_nesting", set_config_apparmor_allow_nesting, get_config_apparmor_allow_nesting, clr_config_apparmor_allow_nesting, }, - { "lxc.apparmor.raw", set_config_apparmor_raw, get_config_apparmor_raw, clr_config_apparmor_raw, }, - { "lxc.autodev.tmpfs.size", set_config_autodev_tmpfs_size, get_config_autodev_tmpfs_size, clr_config_autodev_tmpfs_size, }, - { "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, }, - { "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, }, - { "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, }, - { "lxc.cgroup2", set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, }, - { "lxc.cgroup.dir.monitor.pivot", set_config_cgroup_monitor_pivot_dir, get_config_cgroup_monitor_pivot_dir, clr_config_cgroup_monitor_pivot_dir, }, - { "lxc.cgroup.dir.monitor", set_config_cgroup_monitor_dir, get_config_cgroup_monitor_dir, clr_config_cgroup_monitor_dir, }, - { "lxc.cgroup.dir.container.inner", set_config_cgroup_container_inner_dir, get_config_cgroup_container_inner_dir, clr_config_cgroup_container_inner_dir, }, - { "lxc.cgroup.dir.container", set_config_cgroup_container_dir, get_config_cgroup_container_dir, clr_config_cgroup_container_dir, }, - { "lxc.cgroup.dir", set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, }, - { "lxc.cgroup.relative", set_config_cgroup_relative, get_config_cgroup_relative, clr_config_cgroup_relative, }, - { "lxc.cgroup", set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, }, - { "lxc.console.buffer.size", set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, }, - { "lxc.console.logfile", set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, }, - { "lxc.console.path", set_config_console_path, get_config_console_path, clr_config_console_path, }, - { "lxc.console.rotate", set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, }, - { "lxc.console.size", set_config_console_size, get_config_console_size, clr_config_console_size, }, - { "lxc.environment", set_config_environment, get_config_environment, clr_config_environment, }, - { "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, }, - { "lxc.execute.cmd", set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, }, - { "lxc.group", set_config_group, get_config_group, clr_config_group, }, - { "lxc.hook.autodev", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.clone", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.destroy", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.mount", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.post-stop", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.pre-mount", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.pre-start", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.start", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.start-host", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.stop", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.version", set_config_hooks_version, get_config_hooks_version, clr_config_hooks_version, }, - { "lxc.hook", set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.idmap", set_config_idmaps, get_config_idmaps, clr_config_idmaps, }, - { "lxc.include", set_config_includefiles, get_config_includefiles, clr_config_includefiles, }, - { "lxc.init.cmd", set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, }, - { "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, }, - { "lxc.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, - { "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, }, - { "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, }, - { "lxc.keyring.session", set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session }, - { "lxc.log.file", set_config_log_file, get_config_log_file, clr_config_log_file, }, - { "lxc.log.level", set_config_log_level, get_config_log_level, clr_config_log_level, }, - { "lxc.log.syslog", set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, }, - { "lxc.monitor.unshare", set_config_monitor, get_config_monitor, clr_config_monitor, }, - { "lxc.monitor.signal.pdeath", set_config_monitor_signal_pdeath, get_config_monitor_signal_pdeath, clr_config_monitor_signal_pdeath, }, - { "lxc.mount.auto", set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, }, - { "lxc.mount.entry", set_config_mount, get_config_mount, clr_config_mount, }, - { "lxc.mount.fstab", set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, }, - { "lxc.namespace.clone", set_config_namespace_clone, get_config_namespace_clone, clr_config_namespace_clone, }, - { "lxc.namespace.keep", set_config_namespace_keep, get_config_namespace_keep, clr_config_namespace_keep, }, - { "lxc.namespace.share", set_config_namespace_share, get_config_namespace_share, clr_config_namespace_share, }, - { "lxc.time.offset.boot", set_config_time_offset_boot, get_config_time_offset_boot, clr_config_time_offset_boot, }, - { "lxc.time.offset.monotonic", set_config_time_offset_monotonic, get_config_time_offset_monotonic, clr_config_time_offset_monotonic, }, - { "lxc.net.flags", set_config_net_flags, get_config_net_flags, clr_config_net_flags, }, - { "lxc.net.hwaddr", set_config_net_hwaddr, get_config_net_hwaddr, clr_config_net_hwaddr, }, - { "lxc.net.ipv4.address", set_config_net_ipv4_address, get_config_net_ipv4_address, clr_config_net_ipv4_address, }, - { "lxc.net.ipv4.gateway", set_config_net_ipv4_gateway, get_config_net_ipv4_gateway, clr_config_net_ipv4_gateway, }, - { "lxc.net.ipv6.address", set_config_net_ipv6_address, get_config_net_ipv6_address, clr_config_net_ipv6_address, }, - { "lxc.net.ipv6.gateway", set_config_net_ipv6_gateway, get_config_net_ipv6_gateway, clr_config_net_ipv6_gateway, }, - { "lxc.net.link", set_config_net_link, get_config_net_link, clr_config_net_link, }, - { "lxc.net.l2proxy", set_config_net_l2proxy, get_config_net_l2proxy, clr_config_net_l2proxy, }, - { "lxc.net.macvlan.mode", set_config_net_macvlan_mode, get_config_net_macvlan_mode, clr_config_net_macvlan_mode, }, - { "lxc.net.ipvlan.mode", set_config_net_ipvlan_mode, get_config_net_ipvlan_mode, clr_config_net_ipvlan_mode, }, - { "lxc.net.ipvlan.isolation", set_config_net_ipvlan_isolation, get_config_net_ipvlan_isolation, clr_config_net_ipvlan_isolation, }, - { "lxc.net.mtu", set_config_net_mtu, get_config_net_mtu, clr_config_net_mtu, }, - { "lxc.net.name", set_config_net_name, get_config_net_name, clr_config_net_name, }, - { "lxc.net.script.down", set_config_net_script_down, get_config_net_script_down, clr_config_net_script_down, }, - { "lxc.net.script.up", set_config_net_script_up, get_config_net_script_up, clr_config_net_script_up, }, - { "lxc.net.type", set_config_net_type, get_config_net_type, clr_config_net_type, }, - { "lxc.net.vlan.id", set_config_net_vlan_id, get_config_net_vlan_id, clr_config_net_vlan_id, }, - { "lxc.net.veth.mode", set_config_net_veth_mode, get_config_net_veth_mode, clr_config_net_veth_mode, }, - { "lxc.net.veth.pair", set_config_net_veth_pair, get_config_net_veth_pair, clr_config_net_veth_pair, }, - { "lxc.net.veth.ipv4.route", set_config_net_veth_ipv4_route, get_config_net_veth_ipv4_route, clr_config_net_veth_ipv4_route, }, - { "lxc.net.veth.ipv6.route", set_config_net_veth_ipv6_route, get_config_net_veth_ipv6_route, clr_config_net_veth_ipv6_route, }, - { "lxc.net.veth.vlan.id", set_config_net_veth_vlan_id, get_config_net_veth_vlan_id, clr_config_net_veth_vlan_id, }, - { "lxc.net.veth.vlan.tagged.id", set_config_net_veth_vlan_tagged_id, get_config_net_veth_vlan_tagged_id, clr_config_net_veth_vlan_tagged_id, }, - { "lxc.net.", set_config_net_nic, get_config_net_nic, clr_config_net_nic, }, - { "lxc.net", set_config_net, get_config_net, clr_config_net, }, - { "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, }, - { "lxc.prlimit", set_config_prlimit, get_config_prlimit, clr_config_prlimit, }, - { "lxc.pty.max", set_config_pty_max, get_config_pty_max, clr_config_pty_max, }, - { "lxc.rootfs.managed", set_config_rootfs_managed, get_config_rootfs_managed, clr_config_rootfs_managed, }, - { "lxc.rootfs.mount", set_config_rootfs_mount, get_config_rootfs_mount, clr_config_rootfs_mount, }, - { "lxc.rootfs.options", set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, }, - { "lxc.rootfs.path", set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, }, - { "lxc.seccomp.allow_nesting", set_config_seccomp_allow_nesting, get_config_seccomp_allow_nesting, clr_config_seccomp_allow_nesting, }, - { "lxc.seccomp.notify.cookie", set_config_seccomp_notify_cookie, get_config_seccomp_notify_cookie, clr_config_seccomp_notify_cookie, }, - { "lxc.seccomp.notify.proxy", set_config_seccomp_notify_proxy, get_config_seccomp_notify_proxy, clr_config_seccomp_notify_proxy, }, - { "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, }, - { "lxc.selinux.context.keyring", set_config_selinux_context_keyring, get_config_selinux_context_keyring, clr_config_selinux_context_keyring }, - { "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, }, - { "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, }, - { "lxc.signal.reboot", set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, }, - { "lxc.signal.stop", set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, }, - { "lxc.start.auto", set_config_start, get_config_start, clr_config_start, }, - { "lxc.start.delay", set_config_start, get_config_start, clr_config_start, }, - { "lxc.start.order", set_config_start, get_config_start, clr_config_start, }, - { "lxc.tty.dir", set_config_tty_dir, get_config_tty_dir, clr_config_tty_dir, }, - { "lxc.tty.max", set_config_tty_max, get_config_tty_max, clr_config_tty_max, }, - { "lxc.uts.name", set_config_uts_name, get_config_uts_name, clr_config_uts_name, }, - { "lxc.sysctl", set_config_sysctl, get_config_sysctl, clr_config_sysctl, }, - { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, + { "lxc.arch", true, set_config_personality, get_config_personality, clr_config_personality, }, + { "lxc.apparmor.profile", true, set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, }, + { "lxc.apparmor.allow_incomplete", true, set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, }, + { "lxc.apparmor.allow_nesting", true, set_config_apparmor_allow_nesting, get_config_apparmor_allow_nesting, clr_config_apparmor_allow_nesting, }, + { "lxc.apparmor.raw", true, set_config_apparmor_raw, get_config_apparmor_raw, clr_config_apparmor_raw, }, + { "lxc.autodev.tmpfs.size", true, set_config_autodev_tmpfs_size, get_config_autodev_tmpfs_size, clr_config_autodev_tmpfs_size, }, + { "lxc.autodev", true, set_config_autodev, get_config_autodev, clr_config_autodev, }, + { "lxc.cap.drop", true, set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, }, + { "lxc.cap.keep", true, set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, }, + { "lxc.cgroup2", false, set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, }, + { "lxc.cgroup.dir.monitor.pivot", true, set_config_cgroup_monitor_pivot_dir, get_config_cgroup_monitor_pivot_dir, clr_config_cgroup_monitor_pivot_dir, }, + { "lxc.cgroup.dir.monitor", true, set_config_cgroup_monitor_dir, get_config_cgroup_monitor_dir, clr_config_cgroup_monitor_dir, }, + { "lxc.cgroup.dir.container.inner", true, set_config_cgroup_container_inner_dir, get_config_cgroup_container_inner_dir, clr_config_cgroup_container_inner_dir, }, + { "lxc.cgroup.dir.container", true, set_config_cgroup_container_dir, get_config_cgroup_container_dir, clr_config_cgroup_container_dir, }, + { "lxc.cgroup.dir", true, set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, }, + { "lxc.cgroup.relative", true, set_config_cgroup_relative, get_config_cgroup_relative, clr_config_cgroup_relative, }, + { "lxc.cgroup", false, set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, }, + { "lxc.console.buffer.size", true, set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, }, + { "lxc.console.logfile", true, set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, }, + { "lxc.console.path", true, set_config_console_path, get_config_console_path, clr_config_console_path, }, + { "lxc.console.rotate", true, set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, }, + { "lxc.console.size", true, set_config_console_size, get_config_console_size, clr_config_console_size, }, + { "lxc.environment", true, set_config_environment, get_config_environment, clr_config_environment, }, + { "lxc.ephemeral", true, set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, }, + { "lxc.execute.cmd", true, set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, }, + { "lxc.group", true, set_config_group, get_config_group, clr_config_group, }, + { "lxc.hook.autodev", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.clone", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.destroy", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.mount", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.post-stop", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.pre-mount", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.pre-start", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.start", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.start-host", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.stop", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.version", true, set_config_hooks_version, get_config_hooks_version, clr_config_hooks_version, }, + { "lxc.hook", true, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.idmap", true, set_config_idmaps, get_config_idmaps, clr_config_idmaps, }, + { "lxc.include", true, set_config_includefiles, get_config_includefiles, clr_config_includefiles, }, + { "lxc.init.cmd", true, set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, }, + { "lxc.init.gid", true, set_config_init_gid, get_config_init_gid, clr_config_init_gid, }, + { "lxc.init.groups", true, set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, + { "lxc.init.uid", true, set_config_init_uid, get_config_init_uid, clr_config_init_uid, }, + { "lxc.init.cwd", true, set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, }, + { "lxc.keyring.session", true, set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session }, + { "lxc.log.file", true, set_config_log_file, get_config_log_file, clr_config_log_file, }, + { "lxc.log.level", true, set_config_log_level, get_config_log_level, clr_config_log_level, }, + { "lxc.log.syslog", true, set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, }, + { "lxc.monitor.unshare", true, set_config_monitor, get_config_monitor, clr_config_monitor, }, + { "lxc.monitor.signal.pdeath", true, set_config_monitor_signal_pdeath, get_config_monitor_signal_pdeath, clr_config_monitor_signal_pdeath, }, + { "lxc.mount.auto", true, set_config_mount_auto, get_config_mount_auto, clr_config_mount_auto, }, + { "lxc.mount.entry", true, set_config_mount, get_config_mount, clr_config_mount, }, + { "lxc.mount.fstab", true, set_config_mount_fstab, get_config_mount_fstab, clr_config_mount_fstab, }, + { "lxc.namespace.clone", true, set_config_namespace_clone, get_config_namespace_clone, clr_config_namespace_clone, }, + { "lxc.namespace.keep", true, set_config_namespace_keep, get_config_namespace_keep, clr_config_namespace_keep, }, + { "lxc.namespace.share", true, set_config_namespace_share, get_config_namespace_share, clr_config_namespace_share, }, + { "lxc.time.offset.boot", true, set_config_time_offset_boot, get_config_time_offset_boot, clr_config_time_offset_boot, }, + { "lxc.time.offset.monotonic", true, set_config_time_offset_monotonic, get_config_time_offset_monotonic, clr_config_time_offset_monotonic, }, + { "lxc.net.flags", true, set_config_net_flags, get_config_net_flags, clr_config_net_flags, }, + { "lxc.net.hwaddr", true, set_config_net_hwaddr, get_config_net_hwaddr, clr_config_net_hwaddr, }, + { "lxc.net.ipv4.address", true, set_config_net_ipv4_address, get_config_net_ipv4_address, clr_config_net_ipv4_address, }, + { "lxc.net.ipv4.gateway", true, set_config_net_ipv4_gateway, get_config_net_ipv4_gateway, clr_config_net_ipv4_gateway, }, + { "lxc.net.ipv6.address", true, set_config_net_ipv6_address, get_config_net_ipv6_address, clr_config_net_ipv6_address, }, + { "lxc.net.ipv6.gateway", true, set_config_net_ipv6_gateway, get_config_net_ipv6_gateway, clr_config_net_ipv6_gateway, }, + { "lxc.net.link", true, set_config_net_link, get_config_net_link, clr_config_net_link, }, + { "lxc.net.l2proxy", true, set_config_net_l2proxy, get_config_net_l2proxy, clr_config_net_l2proxy, }, + { "lxc.net.macvlan.mode", true, set_config_net_macvlan_mode, get_config_net_macvlan_mode, clr_config_net_macvlan_mode, }, + { "lxc.net.ipvlan.mode", true, set_config_net_ipvlan_mode, get_config_net_ipvlan_mode, clr_config_net_ipvlan_mode, }, + { "lxc.net.ipvlan.isolation", true, set_config_net_ipvlan_isolation, get_config_net_ipvlan_isolation, clr_config_net_ipvlan_isolation, }, + { "lxc.net.mtu", true, set_config_net_mtu, get_config_net_mtu, clr_config_net_mtu, }, + { "lxc.net.name", true, set_config_net_name, get_config_net_name, clr_config_net_name, }, + { "lxc.net.script.down", true, set_config_net_script_down, get_config_net_script_down, clr_config_net_script_down, }, + { "lxc.net.script.up", true, set_config_net_script_up, get_config_net_script_up, clr_config_net_script_up, }, + { "lxc.net.type", true, set_config_net_type, get_config_net_type, clr_config_net_type, }, + { "lxc.net.vlan.id", true, set_config_net_vlan_id, get_config_net_vlan_id, clr_config_net_vlan_id, }, + { "lxc.net.veth.mode", true, set_config_net_veth_mode, get_config_net_veth_mode, clr_config_net_veth_mode, }, + { "lxc.net.veth.pair", true, set_config_net_veth_pair, get_config_net_veth_pair, clr_config_net_veth_pair, }, + { "lxc.net.veth.ipv4.route", true, set_config_net_veth_ipv4_route, get_config_net_veth_ipv4_route, clr_config_net_veth_ipv4_route, }, + { "lxc.net.veth.ipv6.route", true, set_config_net_veth_ipv6_route, get_config_net_veth_ipv6_route, clr_config_net_veth_ipv6_route, }, + { "lxc.net.veth.vlan.id", true, set_config_net_veth_vlan_id, get_config_net_veth_vlan_id, clr_config_net_veth_vlan_id, }, + { "lxc.net.veth.vlan.tagged.id", true, set_config_net_veth_vlan_tagged_id, get_config_net_veth_vlan_tagged_id, clr_config_net_veth_vlan_tagged_id, }, + { "lxc.net.", false, set_config_net_nic, get_config_net_nic, clr_config_net_nic, }, + { "lxc.net", true, set_config_net, get_config_net, clr_config_net, }, + { "lxc.no_new_privs", true, set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, }, + { "lxc.prlimit", false, set_config_prlimit, get_config_prlimit, clr_config_prlimit, }, + { "lxc.pty.max", true, set_config_pty_max, get_config_pty_max, clr_config_pty_max, }, + { "lxc.rootfs.managed", true, set_config_rootfs_managed, get_config_rootfs_managed, clr_config_rootfs_managed, }, + { "lxc.rootfs.mount", true, set_config_rootfs_mount, get_config_rootfs_mount, clr_config_rootfs_mount, }, + { "lxc.rootfs.options", true, set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, }, + { "lxc.rootfs.path", true, set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, }, + { "lxc.seccomp.allow_nesting", true, set_config_seccomp_allow_nesting, get_config_seccomp_allow_nesting, clr_config_seccomp_allow_nesting, }, + { "lxc.seccomp.notify.cookie", true, set_config_seccomp_notify_cookie, get_config_seccomp_notify_cookie, clr_config_seccomp_notify_cookie, }, + { "lxc.seccomp.notify.proxy", true, set_config_seccomp_notify_proxy, get_config_seccomp_notify_proxy, clr_config_seccomp_notify_proxy, }, + { "lxc.seccomp.profile", true, set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, }, + { "lxc.selinux.context.keyring", true, set_config_selinux_context_keyring, get_config_selinux_context_keyring, clr_config_selinux_context_keyring }, + { "lxc.selinux.context", true, set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, }, + { "lxc.signal.halt", true, set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, }, + { "lxc.signal.reboot", true, set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, }, + { "lxc.signal.stop", true, set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, }, + { "lxc.start.auto", true, set_config_start, get_config_start, clr_config_start, }, + { "lxc.start.delay", true, set_config_start, get_config_start, clr_config_start, }, + { "lxc.start.order", true, set_config_start, get_config_start, clr_config_start, }, + { "lxc.tty.dir", true, set_config_tty_dir, get_config_tty_dir, clr_config_tty_dir, }, + { "lxc.tty.max", true, set_config_tty_max, get_config_tty_max, clr_config_tty_max, }, + { "lxc.uts.name", true, set_config_uts_name, get_config_uts_name, clr_config_uts_name, }, + { "lxc.sysctl", false, set_config_sysctl, get_config_sysctl, clr_config_sysctl, }, + { "lxc.proc", false, set_config_proc, get_config_proc, clr_config_proc, }, }; static const size_t config_jump_table_size = sizeof(config_jump_table) / sizeof(struct lxc_config_t); @@ -298,9 +298,20 @@ struct lxc_config_t *lxc_get_config(const char *key) { size_t i; - for (i = 0; i < config_jump_table_size; i++) - if (strnequal(config_jump_table[i].name, key, strlen(config_jump_table[i].name))) - return &config_jump_table[i]; + for (i = 0; i < config_jump_table_size; i++) { + struct lxc_config_t *cur = &config_jump_table[i]; + bool match; + + if (cur->strict) + match = strequal(cur->name, key); + else + match = strnequal(config_jump_table[i].name, key, + strlen(config_jump_table[i].name)); + if (!match) + continue; + + return cur; + } return NULL; } @@ -324,8 +335,9 @@ static int set_config_net_type(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_type(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_type(key, lxc_conf, data); + return 0; if (strequal(value, "veth")) { netdev->type = LXC_NET_VETH; @@ -648,16 +660,15 @@ static int set_config_net_hwaddr(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_hwaddr(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_hwaddr(key, lxc_conf, data); + return 0; new_value = strdup(value); if (!new_value) return ret_errno(ENOMEM); rand_complete_hwaddr(new_value); - - free_disarm(netdev->hwaddr); if (!lxc_config_value_empty(new_value)) netdev->hwaddr = move_ptr(new_value); @@ -694,8 +705,9 @@ static int set_config_net_mtu(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_mtu(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_mtu(key, lxc_conf, data); + return 0; return set_config_string_item(&netdev->mtu, value); } @@ -787,10 +799,9 @@ static int set_config_net_ipv4_gateway(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_ipv4_gateway(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_ipv4_gateway(key, lxc_conf, data); - - free(netdev->ipv4_gateway); + return 0; if (strequal(value, "auto")) { netdev->ipv4_gateway = NULL; @@ -936,10 +947,9 @@ static int set_config_net_ipv6_gateway(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_ipv6_gateway(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_ipv6_gateway(key, lxc_conf, data); - - free(netdev->ipv6_gateway); + return 0; if (strequal(value, "auto")) { netdev->ipv6_gateway = NULL; @@ -1034,8 +1044,9 @@ static int set_config_net_script_up(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_script_up(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_script_up(key, lxc_conf, data); + return 0; return set_config_string_item(&netdev->upscript, value); } @@ -1048,8 +1059,9 @@ static int set_config_net_script_down(const char *key, const char *value, if (!netdev) return ret_errno(EINVAL); + clr_config_net_script_down(key, lxc_conf, data); if (lxc_config_value_empty(value)) - return clr_config_net_script_down(key, lxc_conf, data); + return 0; return set_config_string_item(&netdev->downscript, value); } @@ -5332,7 +5344,7 @@ static int clr_config_net_type(const char *key, struct lxc_conf *lxc_conf, if (!netdev) return ret_errno(EINVAL); - netdev->type = -1; + lxc_clear_netdev(netdev); return 0; } diff --git a/src/lxc/confile.h b/src/lxc/confile.h index f182dfaf4..b04252b8f 100644 --- a/src/lxc/confile.h +++ b/src/lxc/confile.h @@ -34,6 +34,7 @@ typedef int (*config_clr_cb)(const char *key, struct lxc_conf *conf, struct lxc_config_t { char *name; + bool strict; config_set_cb set; config_get_cb get; config_clr_cb clr; diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index 06b4869ce..4d52d044d 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -403,26 +403,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) } } -static void lxc_free_netdev(struct lxc_netdev *netdev) +void lxc_clear_netdev(struct lxc_netdev *netdev) { struct lxc_list *cur, *next; + ssize_t idx; if (!netdev) return; - free(netdev->upscript); - free(netdev->downscript); - free(netdev->hwaddr); - free(netdev->mtu); + idx = netdev->idx; - free(netdev->ipv4_gateway); + free_disarm(netdev->upscript); + free_disarm(netdev->downscript); + free_disarm(netdev->hwaddr); + free_disarm(netdev->mtu); + + free_disarm(netdev->ipv4_gateway); lxc_list_for_each_safe(cur, &netdev->ipv4, next) { lxc_list_del(cur); free(cur->elem); free(cur); } - free(netdev->ipv6_gateway); + free_disarm(netdev->ipv6_gateway); lxc_list_for_each_safe(cur, &netdev->ipv6, next) { lxc_list_del(cur); free(cur->elem); @@ -448,7 +451,19 @@ static void lxc_free_netdev(struct lxc_netdev *netdev) } } - free(netdev); + memset(netdev, 0, sizeof(struct lxc_netdev)); + lxc_list_init(&netdev->ipv4); + lxc_list_init(&netdev->ipv6); + netdev->type = -1; + netdev->idx = idx; +} + +static void lxc_free_netdev(struct lxc_netdev *netdev) +{ + if (netdev) { + lxc_clear_netdev(netdev); + free(netdev); + } } bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx) diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h index 670f3894b..f675ac176 100644 --- a/src/lxc/confile_utils.h +++ b/src/lxc/confile_utils.h @@ -37,6 +37,7 @@ __hidden extern struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf, __hidden extern void lxc_log_configured_netdevs(const struct lxc_conf *conf); __hidden extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx); __hidden extern void lxc_free_networks(struct lxc_list *networks); +__hidden extern void lxc_clear_netdev(struct lxc_netdev *netdev); __hidden extern int lxc_veth_mode_to_flag(int *mode, const char *value); __hidden extern char *lxc_veth_flag_to_mode(int mode); __hidden extern int lxc_macvlan_mode_to_flag(int *mode, const char *value); diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c index 4a0aa41db..c6206bff5 100644 --- a/src/lxc/initutils.c +++ b/src/lxc/initutils.c @@ -54,8 +54,10 @@ const char *lxc_global_config_value(const char *option_name) }; /* placed in the thread local storage pool for non-bionic targets */ -#ifdef HAVE_TLS +#if defined(THREAD_LOCAL_STORAGE_SUPPORTED) static thread_local const char *values[sizeof(options) / sizeof(options[0])] = {0}; +#elif defined(ENFORCE_THREAD_SAFETY) + #error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed due to missing TLS #else static const char *values[sizeof(options) / sizeof(options[0])] = {0}; #endif diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 5d43815c7..ec54a96eb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2315,6 +2315,9 @@ static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, static char** get_from_array(char ***names, char *cname, int size) { + if (!*names) + return NULL; + return (char **)bsearch(&cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp); } diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c index 0fa129500..8b5b1b0d2 100644 --- a/src/tests/parse_config_file.c +++ b/src/tests/parse_config_file.c @@ -877,15 +877,13 @@ int main(int argc, char *argv[]) goto non_test_error; } - ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "2", tmpf, true); - if (ret == 0) { - lxc_error("%s\n", "lxc.hook.version"); + if (c->set_config_item(c, "lxc.hook.version", "2")) { + lxc_error("%s\n", "Managed to set to set invalid config item \"lxc.hook.version\" to \"2\""); goto non_test_error; } - ret = set_get_compare_clear_save_load(c, "lxc.monitor.signal.pdeath", "SIGKILL", tmpf, true); - if (ret == 0) { - lxc_error("%s\n", "lxc.hook.version"); + if (!c->set_config_item(c, "lxc.monitor.signal.pdeath", "SIGKILL")) { + lxc_error("%s\n", "Failed to set to set invalid config item \"lxc.monitor.signal.pdeath\" to \"SIGKILL\""); goto non_test_error; } @@ -904,6 +902,11 @@ int main(int argc, char *argv[]) return -1; } + if (c->set_config_item(c, "lxc.hook.versionasdfsadfsadf", "1")) { + lxc_error("%s\n", "Managed to set to set invalid config item \"lxc.hook.versionasdfsadfsadf\" to \"2\""); + goto non_test_error; + } + fret = EXIT_SUCCESS; non_test_error: