diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-03-18 14:06:13 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-03-18 14:18:41 +1100 |
commit | 55c45110e6994fe95867f4df3243c6829116e093 (patch) | |
tree | 246cee1b14d0ecf49bb8f105ee53b3d2e9eedf16 /source4/param | |
parent | 752b2206cbb411e98e88efcfd1df9876a79d4a3d (diff) | |
download | samba-55c45110e6994fe95867f4df3243c6829116e093.tar.gz samba-55c45110e6994fe95867f4df3243c6829116e093.tar.bz2 samba-55c45110e6994fe95867f4df3243c6829116e093.zip |
charset: fixed a problem with the global use of the iconv_convenience structure
We had a crash bug where a cached copy of a iconv convenience pointer
was used after being freed when loadparm asked for iconv to
reload. This could happen if a python module used a iconv based
function before loadparm was completed.
The fix is to ensure that any use of this pointer remains valid, by
reusing the pointer itself when it has already been initialised, but
filling in the child elements with the updated values.
Diffstat (limited to 'source4/param')
-rw-r--r-- | source4/param/loadparm.c | 12 | ||||
-rw-r--r-- | source4/param/param.h | 5 | ||||
-rw-r--r-- | source4/param/util.c | 12 |
3 files changed, 18 insertions, 11 deletions
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 46bbceb862..2bee0fbd86 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -2692,8 +2692,8 @@ struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_c if (lp_ctx == NULL) { static struct smb_iconv_convenience *fallback_ic = NULL; if (fallback_ic == NULL) - fallback_ic = smb_iconv_convenience_init(talloc_autofree_context(), - "CP850", "UTF8", true); + fallback_ic = smb_iconv_convenience_reinit(talloc_autofree_context(), + "CP850", "UTF8", true, NULL); return fallback_ic; } return lp_ctx->iconv_convenience; @@ -2701,8 +2701,12 @@ struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_c _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx) { - talloc_unlink(lp_ctx, lp_ctx->iconv_convenience); - global_iconv_convenience = lp_ctx->iconv_convenience = smb_iconv_convenience_init_lp(lp_ctx, lp_ctx); + struct smb_iconv_convenience *old_ic = lp_ctx->iconv_convenience; + if (old_ic == NULL) { + old_ic = global_iconv_convenience; + } + lp_ctx->iconv_convenience = smb_iconv_convenience_reinit_lp(lp_ctx, lp_ctx, old_ic); + global_iconv_convenience = lp_ctx->iconv_convenience; } void lp_smbcli_options(struct loadparm_context *lp_ctx, diff --git a/source4/param/param.h b/source4/param/param.h index f72fa76174..5435941f2b 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -438,8 +438,9 @@ bool run_init_functions(init_module_fn *fns); init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem); const char *lp_messaging_path(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); -struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx); +struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct smb_iconv_convenience *old_ic); const char *lp_sam_name(struct loadparm_context *lp_ctx); diff --git a/source4/param/util.c b/source4/param/util.c index d9d4eb5e2b..bbe4c87293 100644 --- a/source4/param/util.c +++ b/source4/param/util.c @@ -299,12 +299,14 @@ const char *lp_messaging_path(TALLOC_CTX *mem_ctx, return smbd_tmp_path(mem_ctx, lp_ctx, "messaging"); } -struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx) +struct smb_iconv_convenience *smb_iconv_convenience_reinit_lp(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct smb_iconv_convenience *old_ic) { - return smb_iconv_convenience_init(mem_ctx, lp_dos_charset(lp_ctx), - lp_unix_charset(lp_ctx), - lp_parm_bool(lp_ctx, NULL, "iconv", "native", true)); + return smb_iconv_convenience_reinit(mem_ctx, lp_dos_charset(lp_ctx), + lp_unix_charset(lp_ctx), + lp_parm_bool(lp_ctx, NULL, "iconv", "native", true), + old_ic); } |