From 00c090b093c147a95bfb8fce93f08303993e1995 Mon Sep 17 00:00:00 2001 From: Xavi Hernandez Date: Fri, 20 Dec 2019 14:14:32 +0100 Subject: multiple: fix bad type cast When using inode_ctx_get() or inode_ctx_set(), a 'uint64_t *' is expected. In many cases, the value to retrieve or store is a pointer, which will be of smaller size in some architectures (for example 32-bits). In this case, directly passing the address of the pointer casted to an 'uint64_t *' is wrong and can cause memory corruption. Change-Id: Iae616da9dda528df6743fa2f65ae5cff5ad23258 Signed-off-by: Xavi Hernandez Fixes: bz#1785611 --- xlators/features/shard/src/shard.c | 3 +- xlators/performance/io-cache/src/io-cache.c | 8 ++--- xlators/performance/nl-cache/src/nl-cache-helper.c | 11 +++++-- .../performance/readdir-ahead/src/readdir-ahead.c | 3 +- xlators/storage/posix/src/posix-helpers.c | 3 +- xlators/storage/posix/src/posix-metadata.c | 35 +++++++++++++++------- 6 files changed, 42 insertions(+), 21 deletions(-) (limited to 'xlators') diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 0e96a45768a..c59e244429a 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -80,7 +80,8 @@ __shard_inode_ctx_get(inode_t *inode, xlator_t *this, shard_inode_ctx_t **ctx) INIT_LIST_HEAD(&ctx_p->ilist); INIT_LIST_HEAD(&ctx_p->to_fsync_list); - ret = __inode_ctx_set(inode, this, (uint64_t *)&ctx_p); + ctx_uint = (uint64_t)(uintptr_t)ctx_p; + ret = __inode_ctx_set(inode, this, &ctx_uint); if (ret < 0) { GF_FREE(ctx_p); return ret; diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 821ed65bd05..c007e0a355d 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -381,14 +381,12 @@ ioc_forget(xlator_t *this, inode_t *inode) static int32_t ioc_invalidate(xlator_t *this, inode_t *inode) { - uint64_t ioc_addr = 0; - ioc_inode_t *ioc_inode = NULL; + uint64_t ioc_inode = 0; - inode_ctx_get(inode, this, (uint64_t *)&ioc_addr); - ioc_inode = (void *)(uintptr_t)ioc_addr; + inode_ctx_get(inode, this, &ioc_inode); if (ioc_inode) - ioc_inode_flush(ioc_inode); + ioc_inode_flush((ioc_inode_t *)(uintptr_t)ioc_inode); return 0; } diff --git a/xlators/performance/nl-cache/src/nl-cache-helper.c b/xlators/performance/nl-cache/src/nl-cache-helper.c index 4314038dcd9..03dedf8ea08 100644 --- a/xlators/performance/nl-cache/src/nl-cache-helper.c +++ b/xlators/performance/nl-cache/src/nl-cache-helper.c @@ -164,16 +164,19 @@ static int nlc_inode_ctx_set(xlator_t *this, inode_t *inode, nlc_ctx_t *nlc_ctx, nlc_pe_t *nlc_pe_p) { + uint64_t ctx1, ctx2; int ret = -1; + ctx1 = (uint64_t)(uintptr_t)nlc_ctx; + ctx2 = (uint64_t)(uintptr_t)nlc_pe_p; + /* The caller may choose to set one of the ctxs, hence check * if the ctx1/2 is non zero and then send the address. If we * blindly send the address of both the ctxs, it may reset the * ctx the caller had sent NULL(intended as leave untouched) for.*/ LOCK(&inode->lock); { - ret = __inode_ctx_set2(inode, this, nlc_ctx ? (uint64_t *)&nlc_ctx : 0, - nlc_pe_p ? (uint64_t *)&nlc_pe_p : 0); + ret = __inode_ctx_set2(inode, this, ctx1 ? &ctx1 : 0, ctx2 ? &ctx2 : 0); } UNLOCK(&inode->lock); return ret; @@ -285,6 +288,7 @@ out: static nlc_ctx_t * nlc_inode_ctx_get_set(xlator_t *this, inode_t *inode, nlc_ctx_t **nlc_ctx_p) { + uint64_t ctx; int ret = 0; nlc_ctx_t *nlc_ctx = NULL; nlc_conf_t *conf = NULL; @@ -315,7 +319,8 @@ nlc_inode_ctx_get_set(xlator_t *this, inode_t *inode, nlc_ctx_t **nlc_ctx_p) goto unlock; } - ret = __inode_ctx_set2(inode, this, (uint64_t *)&nlc_ctx, NULL); + ctx = (uint64_t)(uintptr_t)nlc_ctx; + ret = __inode_ctx_set2(inode, this, &ctx, NULL); if (ret) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, NLC_MSG_NO_MEMORY, "inode ctx set failed"); diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.c b/xlators/performance/readdir-ahead/src/readdir-ahead.c index 933941d8a92..4ba7ee7077a 100644 --- a/xlators/performance/readdir-ahead/src/readdir-ahead.c +++ b/xlators/performance/readdir-ahead/src/readdir-ahead.c @@ -98,7 +98,8 @@ __rda_inode_ctx_get(inode_t *inode, xlator_t *this) GF_ATOMIC_INIT(ctx_p->generation, 0); - ret = __inode_ctx_set1(inode, this, (uint64_t *)&ctx_p); + ctx_uint = (uint64_t)(uintptr_t)ctx_p; + ret = __inode_ctx_set1(inode, this, &ctx_uint); if (ret < 0) { GF_FREE(ctx_p); return NULL; diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index ef3c3284636..cbc271481a6 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2858,7 +2858,8 @@ __posix_inode_ctx_get(inode_t *inode, xlator_t *this) pthread_mutex_init(&ctx_p->write_atomic_lock, NULL); pthread_mutex_init(&ctx_p->pgfid_lock, NULL); - ret = __inode_ctx_set(inode, this, (uint64_t *)&ctx_p); + ctx_uint = (uint64_t)(uintptr_t)ctx_p; + ret = __inode_ctx_set(inode, this, &ctx_uint); if (ret < 0) { pthread_mutex_destroy(&ctx_p->xattrop_lock); pthread_mutex_destroy(&ctx_p->write_atomic_lock); diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c index 6e324c8e608..b1889052f11 100644 --- a/xlators/storage/posix/src/posix-metadata.c +++ b/xlators/storage/posix/src/posix-metadata.c @@ -256,6 +256,7 @@ int __posix_get_mdata_xattr(xlator_t *this, const char *real_path, int _fd, inode_t *inode, struct iatt *stbuf) { + uint64_t ctx; posix_mdata_t *mdata = NULL; int ret = -1; int op_errno = 0; @@ -263,7 +264,10 @@ __posix_get_mdata_xattr(xlator_t *this, const char *real_path, int _fd, /* Handle readdirp: inode might be null, time attributes should be served * from xattr not from backend's file attributes */ if (inode) { - ret = __inode_ctx_get1(inode, this, (uint64_t *)&mdata); + ret = __inode_ctx_get1(inode, this, &ctx); + if (ret == 0) { + mdata = (posix_mdata_t *)(uintptr_t)ctx; + } } else { ret = -1; } @@ -288,7 +292,8 @@ __posix_get_mdata_xattr(xlator_t *this, const char *real_path, int _fd, * down scenario */ if (inode) { - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + ctx = (uint64_t)(uintptr_t)mdata; + __inode_ctx_set1(inode, this, &ctx); } } else { /* Failed to get mdata from disk, xattr missing. @@ -370,6 +375,7 @@ posix_set_mdata_xattr_legacy_files(xlator_t *this, inode_t *inode, const char *realpath, struct mdata_iatt *mdata_iatt, int *op_errno) { + uint64_t ctx; posix_mdata_t *mdata = NULL; posix_mdata_t imdata = { 0, @@ -382,10 +388,11 @@ posix_set_mdata_xattr_legacy_files(xlator_t *this, inode_t *inode, LOCK(&inode->lock); { - ret = __inode_ctx_get1(inode, this, (uint64_t *)&mdata); - if (ret == 0 && mdata) { + ret = __inode_ctx_get1(inode, this, &ctx); + if (ret == 0 && ctx) { + mdata = (posix_mdata_t *)(uintptr_t)ctx; mdata_already_set = _gf_true; - } else if (ret == -1 || !mdata) { + } else { mdata = GF_CALLOC(1, sizeof(posix_mdata_t), gf_posix_mt_mdata_attr); if (!mdata) { gf_msg(this->name, GF_LOG_ERROR, ENOMEM, P_MSG_NOMEM, @@ -402,7 +409,8 @@ posix_set_mdata_xattr_legacy_files(xlator_t *this, inode_t *inode, /* Got mdata from disk. This is a race, another client * has healed the xattr during lookup. So set it in inode * ctx */ - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + ctx = (uint64_t)(uintptr_t)mdata; + __inode_ctx_set1(inode, this, &ctx); mdata_already_set = _gf_true; } else { *op_errno = 0; @@ -415,7 +423,8 @@ posix_set_mdata_xattr_legacy_files(xlator_t *this, inode_t *inode, mdata->mtime.tv_sec = mdata_iatt->ia_mtime; mdata->mtime.tv_nsec = mdata_iatt->ia_mtime_nsec; - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + ctx = (uint64_t)(uintptr_t)mdata; + __inode_ctx_set1(inode, this, &ctx); } } @@ -464,6 +473,7 @@ posix_set_mdata_xattr(xlator_t *this, const char *real_path, int fd, struct iatt *stbuf, posix_mdata_flag_t *flag, gf_boolean_t update_utime) { + uint64_t ctx; posix_mdata_t *mdata = NULL; int ret = -1; int op_errno = 0; @@ -479,7 +489,10 @@ posix_set_mdata_xattr(xlator_t *this, const char *real_path, int fd, LOCK(&inode->lock); { - ret = __inode_ctx_get1(inode, this, (uint64_t *)&mdata); + ret = __inode_ctx_get1(inode, this, &ctx); + if (ret == 0) { + mdata = (posix_mdata_t *)(uintptr_t)ctx; + } if (ret == -1 || !mdata) { /* * Do we need to fetch the data from xattr @@ -502,7 +515,8 @@ posix_set_mdata_xattr(xlator_t *this, const char *real_path, int fd, * is hit when in-memory status is lost due to brick * down scenario */ - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + ctx = (uint64_t)(uintptr_t)mdata; + __inode_ctx_set1(inode, this, &ctx); } else { /* * This is the first time creating the time attr. This happens @@ -536,7 +550,8 @@ posix_set_mdata_xattr(xlator_t *this, const char *real_path, int fd, mdata->mtime.tv_sec = time->tv_sec; mdata->mtime.tv_nsec = time->tv_nsec; - __inode_ctx_set1(inode, this, (uint64_t *)&mdata); + ctx = (uint64_t)(uintptr_t)mdata; + __inode_ctx_set1(inode, this, &ctx); } } -- cgit