Changeset View
Standalone View
libexec/rtld-elf/rtld.c
| Show First 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | |||||
| static void unload_object(Obj_Entry *, RtldLockState *lockstate); | static void unload_object(Obj_Entry *, RtldLockState *lockstate); | ||||
| static void unref_dag(Obj_Entry *); | static void unref_dag(Obj_Entry *); | ||||
| static void ref_dag(Obj_Entry *); | static void ref_dag(Obj_Entry *); | ||||
| static char *origin_subst_one(Obj_Entry *, char *, const char *, const char *, | static char *origin_subst_one(Obj_Entry *, char *, const char *, const char *, | ||||
| bool); | bool); | ||||
| static char *origin_subst(Obj_Entry *, const char *); | static char *origin_subst(Obj_Entry *, const char *); | ||||
| static bool obj_resolve_origin(Obj_Entry *obj); | static bool obj_resolve_origin(Obj_Entry *obj); | ||||
| static void preinit_main(void); | static void preinit_main(void); | ||||
| static void rtld_recalc_bind_not(void); | |||||
| static void rtld_recalc_dangerous_ld_env(void); | |||||
| static void rtld_recalc_debug(const char *); | |||||
| static void rtld_recalc_path_rpath(const char *); | |||||
| static int rtld_verify_versions(const Objlist *); | static int rtld_verify_versions(const Objlist *); | ||||
| static int rtld_verify_object_versions(Obj_Entry *); | static int rtld_verify_object_versions(Obj_Entry *); | ||||
| static void object_add_name(Obj_Entry *, const char *); | static void object_add_name(Obj_Entry *, const char *); | ||||
| static int object_match_name(const Obj_Entry *, const char *); | static int object_match_name(const Obj_Entry *, const char *); | ||||
| static void ld_utrace_log(int, void *, void *, size_t, int, const char *); | static void ld_utrace_log(int, void *, void *, size_t, int, const char *); | ||||
| static void rtld_fill_dl_phdr_info(const Obj_Entry *obj, | static void rtld_fill_dl_phdr_info(const Obj_Entry *obj, | ||||
| struct dl_phdr_info *phdr_info); | struct dl_phdr_info *phdr_info); | ||||
| static uint32_t gnu_hash(const char *); | static uint32_t gnu_hash(const char *); | ||||
| static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *, | static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *, | ||||
| const unsigned long); | const unsigned long); | ||||
| struct ld_env_var_desc; | |||||
| static void rtld_set_var_bind_not(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_bind_now(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_debug(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_dynamic_weak(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_libmap_disable(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_library_path(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_library_path_fds(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_library_path_rpath(struct ld_env_var_desc *lvd); | |||||
| static void rtld_set_var_loadfltr(struct ld_env_var_desc *lvd); | |||||
| void r_debug_state(struct r_debug *, struct link_map *) __noinline __exported; | void r_debug_state(struct r_debug *, struct link_map *) __noinline __exported; | ||||
| void _r_debug_postinit(struct link_map *) __noinline __exported; | void _r_debug_postinit(struct link_map *) __noinline __exported; | ||||
| int __sys_openat(int, const char *, int, ...); | int __sys_openat(int, const char *, int, ...); | ||||
| /* | /* | ||||
| * Data declarations. | * Data declarations. | ||||
| */ | */ | ||||
| struct r_debug r_debug __exported; /* for GDB; */ | struct r_debug r_debug __exported; /* for GDB; */ | ||||
| static bool libmap_disable; /* Disable libmap */ | static bool libmap_disable; /* Disable libmap */ | ||||
| static bool ld_loadfltr; /* Immediate filters processing */ | static bool ld_loadfltr; /* Immediate filters processing */ | ||||
| static const char *libmap_override; /* Maps to use in addition to libmap.conf */ | static const char *libmap_override; /* Maps to use in addition to libmap.conf */ | ||||
| static bool trust; /* False for setuid and setgid programs */ | static bool trust; /* False for setuid and setgid programs */ | ||||
| static bool dangerous_ld_env; /* True if environment variables have been | static bool dangerous_ld_env; /* True if environment variables have been | ||||
| used to affect the libraries loaded */ | used to affect the libraries loaded */ | ||||
| bool ld_bind_not; /* Disable PLT update */ | bool ld_bind_not; /* Disable PLT update */ | ||||
| static const char *ld_bind_now; /* Environment variable for immediate binding */ | static const char *ld_bind_now; /* Environment variable for immediate binding */ | ||||
| static const char *ld_debug; /* Environment variable for debugging */ | |||||
| static bool ld_dynamic_weak = true; /* True if non-weak definition overrides | static bool ld_dynamic_weak = true; /* True if non-weak definition overrides | ||||
| weak definition */ | weak definition */ | ||||
| static const char *ld_library_path; /* Environment variable for search path */ | static const char *ld_library_path; /* Environment variable for search path */ | ||||
| static const char | static const char | ||||
| *ld_library_dirs; /* Environment variable for library descriptors */ | *ld_library_dirs; /* Environment variable for library descriptors */ | ||||
| static const char *ld_preload; /* Environment variable for libraries to | static const char *ld_preload; /* Environment variable for libraries to | ||||
| load first */ | load first */ | ||||
| static const char *ld_preload_fds; /* Environment variable for libraries | static const char *ld_preload_fds; /* Environment variable for libraries | ||||
| ▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | ld_utrace_log(int event, void *handle, void *mapbase, size_t mapsize, | ||||
| utrace(&ut, sizeof(ut)); | utrace(&ut, sizeof(ut)); | ||||
| } | } | ||||
| struct ld_env_var_desc { | struct ld_env_var_desc { | ||||
| const char *const n; | const char *const n; | ||||
| const char *val; | const char *val; | ||||
| const bool unsecure : 1; | const bool unsecure : 1; | ||||
| const bool can_update : 1; | const bool can_update : 1; | ||||
| const bool debug : 1; | |||||
| bool owned : 1; | bool owned : 1; | ||||
| void (*const on_update)(struct ld_env_var_desc *); | |||||
| }; | }; | ||||
| #define LD_ENV_DESC(var, unsec, ...) \ | #define LD_ENV_DESC(var, unsec, ...) \ | ||||
| [LD_##var] = { .n = #var, .unsecure = unsec, __VA_ARGS__ } | [LD_##var] = { .n = #var, .unsecure = unsec, __VA_ARGS__ } | ||||
| static struct ld_env_var_desc ld_env_vars[] = { | static struct ld_env_var_desc ld_env_vars[] = { | ||||
| LD_ENV_DESC(BIND_NOW, false), | LD_ENV_DESC(BIND_NOW, false, .can_update = true, | ||||
| .on_update = rtld_set_var_bind_now), | |||||
emaste: This means that some variables e.g. `BIND_NOW` can now be updated, right? I think those should… | |||||
| LD_ENV_DESC(PRELOAD, true), | LD_ENV_DESC(PRELOAD, true), | ||||
| LD_ENV_DESC(LIBMAP, true), | LD_ENV_DESC(LIBMAP, true), | ||||
| LD_ENV_DESC(LIBRARY_PATH, true, .can_update = true), | LD_ENV_DESC(LIBRARY_PATH, true, .can_update = true, | ||||
| LD_ENV_DESC(LIBRARY_PATH_FDS, true, .can_update = true), | .on_update = rtld_set_var_library_path), | ||||
| LD_ENV_DESC(LIBMAP_DISABLE, true), | LD_ENV_DESC(LIBRARY_PATH_FDS, true, .can_update = true, | ||||
| LD_ENV_DESC(BIND_NOT, true), | .on_update = rtld_set_var_library_path_fds), | ||||
| LD_ENV_DESC(DEBUG, true, .can_update = true, .debug = true), | LD_ENV_DESC(LIBMAP_DISABLE, true, .can_update = true, | ||||
| .on_update = rtld_set_var_libmap_disable), | |||||
| LD_ENV_DESC(BIND_NOT, true, .can_update = true, | |||||
| .on_update = rtld_set_var_bind_not), | |||||
| LD_ENV_DESC(DEBUG, true, .can_update = true, | |||||
| .on_update = rtld_set_var_debug), | |||||
| LD_ENV_DESC(ELF_HINTS_PATH, true), | LD_ENV_DESC(ELF_HINTS_PATH, true), | ||||
| LD_ENV_DESC(LOADFLTR, true), | LD_ENV_DESC(LOADFLTR, true, .can_update = true, | ||||
| LD_ENV_DESC(LIBRARY_PATH_RPATH, true, .can_update = true), | .on_update = rtld_set_var_loadfltr), | ||||
| LD_ENV_DESC(LIBRARY_PATH_RPATH, true, .can_update = true, | |||||
| .on_update = rtld_set_var_library_path_rpath), | |||||
| LD_ENV_DESC(PRELOAD_FDS, true), | LD_ENV_DESC(PRELOAD_FDS, true), | ||||
| LD_ENV_DESC(DYNAMIC_WEAK, true, .can_update = true), | LD_ENV_DESC(DYNAMIC_WEAK, true, .can_update = true, | ||||
| .on_update = rtld_set_var_dynamic_weak), | |||||
| LD_ENV_DESC(TRACE_LOADED_OBJECTS, false), | LD_ENV_DESC(TRACE_LOADED_OBJECTS, false), | ||||
| LD_ENV_DESC(UTRACE, false, .can_update = true), | LD_ENV_DESC(UTRACE, false, .can_update = true), | ||||
| LD_ENV_DESC(DUMP_REL_PRE, false, .can_update = true), | LD_ENV_DESC(DUMP_REL_PRE, false, .can_update = true), | ||||
| LD_ENV_DESC(DUMP_REL_POST, false, .can_update = true), | LD_ENV_DESC(DUMP_REL_POST, false, .can_update = true), | ||||
| LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false), | LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false), | ||||
| LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false), | LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false), | ||||
| LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false), | LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false), | ||||
| LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false), | LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false), | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) | ||||
| Objlist_Entry *entry; | Objlist_Entry *entry; | ||||
| Obj_Entry *last_interposer, *obj, *preload_tail; | Obj_Entry *last_interposer, *obj, *preload_tail; | ||||
| const Elf_Phdr *phdr; | const Elf_Phdr *phdr; | ||||
| Objlist initlist; | Objlist initlist; | ||||
| RtldLockState lockstate; | RtldLockState lockstate; | ||||
| struct stat st; | struct stat st; | ||||
| Elf_Addr *argcp; | Elf_Addr *argcp; | ||||
| char **argv, **env, **envp, *kexecpath; | char **argv, **env, **envp, *kexecpath; | ||||
| const char *argv0, *binpath, *library_path_rpath, *static_tls_extra; | const char *argv0, *binpath, *static_tls_extra; | ||||
| struct ld_env_var_desc *lvd; | struct ld_env_var_desc *lvd; | ||||
| caddr_t imgentry; | caddr_t imgentry; | ||||
| char buf[MAXPATHLEN]; | char buf[MAXPATHLEN]; | ||||
| int argc, fd, i, mib[4], old_osrel, osrel, phnum, rtld_argc; | int argc, fd, i, mib[4], old_osrel, osrel, phnum, rtld_argc; | ||||
| size_t sz; | size_t sz; | ||||
| bool dir_enable, dir_ignore, direct_exec, explicit_fd, search_in_path; | bool dir_enable, dir_ignore, direct_exec, explicit_fd, search_in_path; | ||||
| /* | /* | ||||
| ▲ Show 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) | ||||
| if (!trust) { | if (!trust) { | ||||
| for (i = 0; i < (int)nitems(ld_env_vars); i++) { | for (i = 0; i < (int)nitems(ld_env_vars); i++) { | ||||
| lvd = &ld_env_vars[i]; | lvd = &ld_env_vars[i]; | ||||
| if (lvd->unsecure) | if (lvd->unsecure) | ||||
| lvd->val = NULL; | lvd->val = NULL; | ||||
| } | } | ||||
| } | } | ||||
| ld_debug = ld_get_env_var(LD_DEBUG); | rtld_recalc_debug(ld_get_env_var(LD_DEBUG)); | ||||
| if (ld_bind_now == NULL) | rtld_recalc_bind_not(); | ||||
| ld_bind_not = ld_get_env_var(LD_BIND_NOT) != NULL; | |||||
| ld_dynamic_weak = ld_get_env_var(LD_DYNAMIC_WEAK) == NULL; | ld_dynamic_weak = ld_get_env_var(LD_DYNAMIC_WEAK) == NULL; | ||||
| libmap_disable = ld_get_env_var(LD_LIBMAP_DISABLE) != NULL; | libmap_disable = ld_get_env_var(LD_LIBMAP_DISABLE) != NULL; | ||||
| libmap_override = ld_get_env_var(LD_LIBMAP); | libmap_override = ld_get_env_var(LD_LIBMAP); | ||||
| ld_library_path = ld_get_env_var(LD_LIBRARY_PATH); | ld_library_path = ld_get_env_var(LD_LIBRARY_PATH); | ||||
| ld_library_dirs = ld_get_env_var(LD_LIBRARY_PATH_FDS); | ld_library_dirs = ld_get_env_var(LD_LIBRARY_PATH_FDS); | ||||
| ld_preload = ld_get_env_var(LD_PRELOAD); | ld_preload = ld_get_env_var(LD_PRELOAD); | ||||
| ld_preload_fds = ld_get_env_var(LD_PRELOAD_FDS); | ld_preload_fds = ld_get_env_var(LD_PRELOAD_FDS); | ||||
| ld_elf_hints_path = ld_get_env_var(LD_ELF_HINTS_PATH); | ld_elf_hints_path = ld_get_env_var(LD_ELF_HINTS_PATH); | ||||
| ld_loadfltr = ld_get_env_var(LD_LOADFLTR) != NULL; | ld_loadfltr = ld_get_env_var(LD_LOADFLTR) != NULL; | ||||
| library_path_rpath = ld_get_env_var(LD_LIBRARY_PATH_RPATH); | rtld_recalc_path_rpath(ld_get_env_var(LD_LIBRARY_PATH_RPATH)); | ||||
| if (library_path_rpath != NULL) { | |||||
| if (library_path_rpath[0] == 'y' || | |||||
| library_path_rpath[0] == 'Y' || | |||||
| library_path_rpath[0] == '1') | |||||
| ld_library_path_rpath = true; | |||||
| else | |||||
| ld_library_path_rpath = false; | |||||
| } | |||||
| static_tls_extra = ld_get_env_var(LD_STATIC_TLS_EXTRA); | static_tls_extra = ld_get_env_var(LD_STATIC_TLS_EXTRA); | ||||
| if (static_tls_extra != NULL && static_tls_extra[0] != '\0') { | if (static_tls_extra != NULL && static_tls_extra[0] != '\0') { | ||||
| sz = parse_integer(static_tls_extra); | sz = parse_integer(static_tls_extra); | ||||
| if (sz >= RTLD_STATIC_TLS_EXTRA && sz <= SIZE_T_MAX) | if (sz >= RTLD_STATIC_TLS_EXTRA && sz <= SIZE_T_MAX) | ||||
| ld_static_tls_extra = sz; | ld_static_tls_extra = sz; | ||||
| } | } | ||||
| dangerous_ld_env = libmap_disable || libmap_override != NULL || | rtld_recalc_dangerous_ld_env(); | ||||
| ld_library_path != NULL || ld_preload != NULL || | |||||
| ld_elf_hints_path != NULL || ld_loadfltr || !ld_dynamic_weak || | |||||
| static_tls_extra != NULL; | |||||
| ld_tracing = ld_get_env_var(LD_TRACE_LOADED_OBJECTS); | ld_tracing = ld_get_env_var(LD_TRACE_LOADED_OBJECTS); | ||||
| ld_utrace = ld_get_env_var(LD_UTRACE); | ld_utrace = ld_get_env_var(LD_UTRACE); | ||||
| set_ld_elf_hints_path(); | set_ld_elf_hints_path(); | ||||
| if (ld_debug != NULL && *ld_debug != '\0') | |||||
| debug = 1; | |||||
| dbg("%s is initialized, base address = %p", __progname, | dbg("%s is initialized, base address = %p", __progname, | ||||
| (caddr_t)aux_info[AT_BASE]->a_un.a_ptr); | (caddr_t)aux_info[AT_BASE]->a_un.a_ptr); | ||||
| dbg("RTLD dynamic = %p", obj_rtld.dynamic); | dbg("RTLD dynamic = %p", obj_rtld.dynamic); | ||||
| dbg("RTLD pltgot = %p", obj_rtld.pltgot); | dbg("RTLD pltgot = %p", obj_rtld.pltgot); | ||||
| dbg("initializing thread locks"); | dbg("initializing thread locks"); | ||||
| lockdflt_init(); | lockdflt_init(); | ||||
| ▲ Show 20 Lines • Show All 5,837 Lines • ▼ Show 20 Lines | rtld_get_var(const char *name) | ||||
| for (i = 0; i < nitems(ld_env_vars); i++) { | for (i = 0; i < nitems(ld_env_vars); i++) { | ||||
| lvd = &ld_env_vars[i]; | lvd = &ld_env_vars[i]; | ||||
| if (strcmp(lvd->n, name) == 0) | if (strcmp(lvd->n, name) == 0) | ||||
| return (lvd->val); | return (lvd->val); | ||||
| } | } | ||||
| return (NULL); | return (NULL); | ||||
| } | } | ||||
| static void | |||||
| rtld_recalc_dangerous_ld_env(void) | |||||
| { | |||||
| dangerous_ld_env |= libmap_disable || libmap_override != NULL || | |||||
Done Inline ActionsDoes ld_debug need to be a global variable? markj: Does `ld_debug` need to be a global variable? | |||||
Done Inline ActionsI removed ld_debug altogether. kib: I removed ld_debug altogether. | |||||
markjUnsubmitted Not Done Inline Actions|= looks wrong. markj: `|=` looks wrong. | |||||
kibAuthorUnsubmitted Done Inline ActionsCould you please explain why? I want to never flip it true->false. kib: Could you please explain why? I want to never flip it true->false. | |||||
markjUnsubmitted Done Inline ActionsI wasn't sure why it should never flip true -> false, but after thinking some more it seems reasonable if one reads the description of the dangerous_ld_env variable. Maybe some short comment would be good to have. markj: I wasn't sure why it should never flip true -> false, but after thinking some more it seems… | |||||
| ld_library_path != NULL || ld_preload != NULL || | |||||
| ld_elf_hints_path != NULL || ld_loadfltr || !ld_dynamic_weak || | |||||
| ld_get_env_var(LD_STATIC_TLS_EXTRA) != NULL; | |||||
| } | |||||
| static void | |||||
| rtld_recalc_debug(const char *ld_debug) | |||||
| { | |||||
| if (ld_debug != NULL && *ld_debug != '\0') | |||||
| debug = 1; | |||||
| } | |||||
| static void | |||||
| rtld_set_var_debug(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| rtld_recalc_debug(lvd->val); | |||||
| } | |||||
| static void | |||||
| rtld_set_var_library_path(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| ld_library_path = lvd->val; | |||||
| } | |||||
| static void | |||||
Done Inline ActionsShouldn't we set it to false if the value is NULL? markj: Shouldn't we set it to false if the value is NULL? | |||||
Done Inline ActionsI am not sure, but lets do it. kib: I am not sure, but lets do it. | |||||
| rtld_set_var_library_path_fds(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| ld_library_dirs = lvd->val; | |||||
| } | |||||
| static void | |||||
| rtld_recalc_path_rpath(const char *library_path_rpath) | |||||
| { | |||||
| if (library_path_rpath != NULL) { | |||||
| if (library_path_rpath[0] == 'y' || | |||||
| library_path_rpath[0] == 'Y' || | |||||
| library_path_rpath[0] == '1') | |||||
Done Inline ActionsShould ld_bind_not be updated here if lvd->val is NULL? That's what happens during image activation time. markj: Should ld_bind_not be updated here if lvd->val is NULL? That's what happens during image… | |||||
| ld_library_path_rpath = true; | |||||
| else | |||||
| ld_library_path_rpath = false; | |||||
| } else { | |||||
| ld_library_path_rpath = false; | |||||
| } | |||||
| } | |||||
| static void | |||||
| rtld_set_var_library_path_rpath(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| rtld_recalc_path_rpath(lvd->val); | |||||
| } | |||||
| static void | |||||
| rtld_recalc_bind_not(void) | |||||
| { | |||||
| if (ld_bind_now == NULL) | |||||
| ld_bind_not = ld_get_env_var(LD_BIND_NOT) != NULL; | |||||
| } | |||||
| static void | |||||
| rtld_set_var_bind_now(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| ld_bind_now = lvd->val; | |||||
Done Inline ActionsShould dangerous_ld_env be recalculated if this variable (and some others) are toggled? markj: Should dangerous_ld_env be recalculated if this variable (and some others) are toggled? | |||||
Done Inline ActionsI decided to never reset dangerous_ld_env back to false is it ever set to true. kib: I decided to never reset dangerous_ld_env back to false is it ever set to true. | |||||
| rtld_recalc_bind_not(); | |||||
| } | |||||
| static void | |||||
| rtld_set_var_bind_not(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| if (ld_bind_now == NULL) | |||||
| ld_bind_not = lvd->val != NULL; | |||||
markjUnsubmitted Done Inline ActionsUse rtld_recalc_bind_not()? markj: Use rtld_recalc_bind_not()? | |||||
| } | |||||
| static void | |||||
| rtld_set_var_dynamic_weak(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| ld_dynamic_weak = lvd->val == NULL; | |||||
| } | |||||
| static void | |||||
| rtld_set_var_loadfltr(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| ld_loadfltr = lvd->val != NULL; | |||||
| } | |||||
| static void | |||||
| rtld_set_var_libmap_disable(struct ld_env_var_desc *lvd) | |||||
| { | |||||
| libmap_disable = lvd->val != NULL; | |||||
| } | |||||
| int | int | ||||
| rtld_set_var(const char *name, const char *val) | rtld_set_var(const char *name, const char *val) | ||||
| { | { | ||||
| RtldLockState lockstate; | |||||
| struct ld_env_var_desc *lvd; | struct ld_env_var_desc *lvd; | ||||
| u_int i; | u_int i; | ||||
| int error; | |||||
| error = ENOENT; | |||||
| wlock_acquire(rtld_bind_lock, &lockstate); | |||||
| for (i = 0; i < nitems(ld_env_vars); i++) { | for (i = 0; i < nitems(ld_env_vars); i++) { | ||||
| lvd = &ld_env_vars[i]; | lvd = &ld_env_vars[i]; | ||||
| if (strcmp(lvd->n, name) != 0) | if (strcmp(lvd->n, name) != 0) | ||||
| continue; | continue; | ||||
| if (!lvd->can_update || (lvd->unsecure && !trust)) | if (!lvd->can_update || (lvd->unsecure && !trust)) { | ||||
| return (EPERM); | error = EPERM; | ||||
| break; | |||||
| } | |||||
Done Inline ActionsIs this missing the on_update call? markj: Is this missing the on_update call? | |||||
| if (lvd->owned) | if (lvd->owned) | ||||
| free(__DECONST(char *, lvd->val)); | free(__DECONST(char *, lvd->val)); | ||||
| if (val != NULL) | if (val != NULL) | ||||
| lvd->val = xstrdup(val); | lvd->val = xstrdup(val); | ||||
| else | else | ||||
| lvd->val = NULL; | lvd->val = NULL; | ||||
| lvd->owned = true; | lvd->owned = true; | ||||
| if (lvd->debug) | if (lvd->on_update != NULL) | ||||
| debug = lvd->val != NULL && *lvd->val != '\0'; | lvd->on_update(lvd); | ||||
| return (0); | error = 0; | ||||
| break; | |||||
| } | } | ||||
| return (ENOENT); | if (error == 0) | ||||
| rtld_recalc_dangerous_ld_env(); | |||||
| lock_release(rtld_bind_lock, &lockstate); | |||||
| return (error); | |||||
| } | } | ||||
| /* | /* | ||||
| * Overrides for libc_pic-provided functions. | * Overrides for libc_pic-provided functions. | ||||
| */ | */ | ||||
| int | int | ||||
| __getosreldate(void) | __getosreldate(void) | ||||
| ▲ Show 20 Lines • Show All 65 Lines • Show Last 20 Lines | |||||
This means that some variables e.g. BIND_NOW can now be updated, right? I think those should be noted in the commit message too.