From: Andreas Schneider Date: Mon, 15 May 2017 09:05:59 +0000 (+0200) Subject: lib:util: Make probing of modules more secure X-Git-Tag: ldb-1.1.31~159 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91ef234a0ad0edfdefeb38cf0ad1de3b3e548f1e;p=thirdparty%2Fsamba.git lib:util: Make probing of modules more secure BUG: https://bugzilla.samba.org/show_bug.cgi?id=12780 Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison --- diff --git a/lib/util/modules.c b/lib/util/modules.c index e8a86c47fdf..978053e367b 100644 --- a/lib/util/modules.c +++ b/lib/util/modules.c @@ -261,9 +261,73 @@ int smb_load_all_modules_absoute_path(const char **modules) return success; } +/** + * @brief Check if a module exist and load it. + * + * @param[in] subsystem The name of the subsystem the module belongs too. + * + * @param[in] module The name of the module + * + * @return A NTSTATUS code + */ NTSTATUS smb_probe_module(const char *subsystem, const char *module) { - return do_smb_load_module(subsystem, module, true); + NTSTATUS status; + char *module_path = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + if (subsystem == NULL) { + status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + if (module == NULL) { + status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + if (strchr(module, '/')) { + status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + module_path = talloc_asprintf(tmp_ctx, + "%s/%s.%s", + modules_path(tmp_ctx, subsystem), + module, + shlib_ext()); + if (module_path == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + status = load_module_absolute_path(module_path, true); + +done: + TALLOC_FREE(tmp_ctx); + return status; +} + +/** + * @brief Check if a module exist and load it. + * + * Warning: Using this function can have security implecations! + * + * @param[in] subsystem The name of the subsystem the module belongs too. + * + * @param[in] module Load a module using an abolute path. + * + * @return A NTSTATUS code + */ +NTSTATUS smb_probe_module_absolute_path(const char *module) +{ + if (module == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + if (module[0] != '/') { + return NT_STATUS_INVALID_PARAMETER; + } + + return load_module_absolute_path(module, true); } NTSTATUS smb_load_module(const char *subsystem, const char *module) diff --git a/lib/util/samba_modules.h b/lib/util/samba_modules.h index d7a452159ab..c6986910c38 100644 --- a/lib/util/samba_modules.h +++ b/lib/util/samba_modules.h @@ -55,6 +55,7 @@ init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem); int smb_load_all_modules_absoute_path(const char **modules); NTSTATUS smb_probe_module(const char *subsystem, const char *module); +NTSTATUS smb_probe_module_absolute_path(const char *module); NTSTATUS smb_load_module(const char *subsystem, const char *module); #endif /* _SAMBA_MODULES_H */ diff --git a/source3/smbd/perfcount.c b/source3/smbd/perfcount.c index a7c268a2fef..1555ea24b64 100644 --- a/source3/smbd/perfcount.c +++ b/source3/smbd/perfcount.c @@ -144,7 +144,7 @@ static bool smb_load_perfcount_module(const char *name) /* load the perfcounter module */ if((entry = smb_perfcount_find_module(module_name)) || - (NT_STATUS_IS_OK(smb_probe_module("perfcount", module_path)) && + (NT_STATUS_IS_OK(smb_probe_module_absolute_path(module_path)) && (entry = smb_perfcount_find_module(module_name)))) { DEBUG(3,("Successfully loaded perfcounter module [%s] \n", name));