summaryrefslogtreecommitdiff
path: root/lib/util/charset/charcnv.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-03-18 14:06:13 +1100
committerAndrew Tridgell <tridge@samba.org>2010-03-18 14:18:41 +1100
commit55c45110e6994fe95867f4df3243c6829116e093 (patch)
tree246cee1b14d0ecf49bb8f105ee53b3d2e9eedf16 /lib/util/charset/charcnv.c
parent752b2206cbb411e98e88efcfd1df9876a79d4a3d (diff)
downloadsamba-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 'lib/util/charset/charcnv.c')
-rw-r--r--lib/util/charset/charcnv.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c
index a479f44426..efdb3ed2b3 100644
--- a/lib/util/charset/charcnv.c
+++ b/lib/util/charset/charcnv.c
@@ -39,6 +39,7 @@
*/
struct smb_iconv_convenience {
+ TALLOC_CTX *child_ctx;
const char *unix_charset;
const char *dos_charset;
bool native_iconv;
@@ -83,22 +84,45 @@ static int close_iconv_convenience(struct smb_iconv_convenience *data)
return 0;
}
-_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_init(TALLOC_CTX *mem_ctx,
- const char *dos_charset,
- const char *unix_charset,
- bool native_iconv)
+/*
+ the old_ic is passed in here as the smb_iconv_convenience structure
+ is used as a global pointer in some places (eg. python modules). We
+ don't want to invalidate those global pointers, but we do want to
+ update them with the right charset information when loadparm
+ runs. To do that we need to re-use the structure pointer, but
+ re-fill the elements in the structure with the updated values
+ */
+_PUBLIC_ struct smb_iconv_convenience *smb_iconv_convenience_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool native_iconv,
+ struct smb_iconv_convenience *old_ic)
{
- struct smb_iconv_convenience *ret = talloc_zero(mem_ctx,
- struct smb_iconv_convenience);
+ struct smb_iconv_convenience *ret;
+ if (old_ic != NULL) {
+ ret = old_ic;
+ close_iconv_convenience(ret);
+ talloc_free(ret->child_ctx);
+ ZERO_STRUCTP(ret);
+ } else {
+ ret = talloc_zero(mem_ctx, struct smb_iconv_convenience);
+ }
if (ret == NULL) {
return NULL;
}
+ /* we use a child context to allow us to free all ptrs without
+ freeing the structure itself */
+ ret->child_ctx = talloc_new(ret);
+ if (ret->child_ctx == NULL) {
+ return NULL;
+ }
+
talloc_set_destructor(ret, close_iconv_convenience);
- ret->dos_charset = talloc_strdup(ret, dos_charset);
- ret->unix_charset = talloc_strdup(ret, unix_charset);
+ ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset);
+ ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset);
ret->native_iconv = native_iconv;
return ret;