summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiels de Vos <ndevos@redhat.com>2016-09-13 09:03:56 +0200
committerNiels de Vos <ndevos@redhat.com>2016-10-11 00:14:00 -0700
commit85e959052148ec481823d55c8b91cdee36da2b43 (patch)
tree18c1d1c977912a58a6b9dbfe9ec99325ae262d40
parent2e23c62cc50037c8e61bcd9c04348409e7627181 (diff)
gfapi: warn when glfs_realpath() returned malloc'd memory
glfs_realpath() may return memory allocated with malloc(). Depending on the memory allocator that the application uses, calling free() on the returned string can cause segmentation faults or other problems. Functions that allocate memory, need to match the free'ing of the same memory allocator and memory accounting. glibc/malloc and jemalloc/free do not match together (other allocators could probably trigger these problems as well). Applications need to provide a pre-allocated buffer, or in case glfs_realpath() allocates the memory, glfs_free() should be used to free it. Change-Id: I5d721a7425674aa700db8a7a436cbedb95a5927f BUG: 1370931 Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/15332 CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
-rw-r--r--api/src/gfapi.aliases3
-rw-r--r--api/src/gfapi.map5
-rw-r--r--api/src/glfs-fops.c47
-rw-r--r--api/src/glfs-mem-types.h1
-rw-r--r--api/src/glfs.h4
5 files changed, 50 insertions, 10 deletions
diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases
index ac89d35df6b..74ef4d3442d 100644
--- a/api/src/gfapi.aliases
+++ b/api/src/gfapi.aliases
@@ -82,7 +82,7 @@ _pub_glfs_fremovexattr _glfs_fremovexattr$GFAPI_3.4.0
_pub_glfs_getcwd _glfs_getcwd$GFAPI_3.4.0
_pub_glfs_chdir _glfs_chdir$GFAPI_3.4.0
_pub_glfs_fchdir _glfs_fchdir$GFAPI_3.4.0
-_pub_glfs_realpath _glfs_realpath$GFAPI_3.4.0
+_pub_glfs_realpath34 _glfs_realpath$GFAPI_3.4.0
_pub_glfs_posix_lock _glfs_posix_lock$GFAPI_3.4.0
_pub_glfs_dup _glfs_dup$GFAPI_3.4.0
@@ -153,5 +153,6 @@ _pub_glfs_upcall_inode_get_pobject _glfs_upcall_inode_get_pobject$GFAPI_3.7.16
_pub_glfs_upcall_inode_get_pstat _glfs_upcall_inode_get_pstat$GFAPI_3.7.16
_pub_glfs_upcall_inode_get_oldpobject _glfs_upcall_inode_get_oldpobject$GFAPI_3.7.16
_pub_glfs_upcall_inode_get_oldpstat _glfs_upcall_inode_get_oldpstat$GFAPI_3.7.16
+_pub_glfs_realpath _glfs_realpath$GFAPI_3.7.17
_pub_glfs_ipc _glfs_ipc$GFAPI_4.0.0
diff --git a/api/src/gfapi.map b/api/src/gfapi.map
index bd7ff13fe41..1ae6d4665fc 100644
--- a/api/src/gfapi.map
+++ b/api/src/gfapi.map
@@ -188,6 +188,11 @@ GFAPI_3.7.16 {
glfs_upcall_inode_get_oldpstat;
} GFAPI_3.7.15;
+GFAPI_3.7.17 {
+ global:
+ glfs_realpath;
+} GFAPI_3.7.16;
+
GFAPI_4.0.0 {
global:
glfs_ipc;
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
index bbbf61dddfc..0a59a8dcf1c 100644
--- a/api/src/glfs-fops.c
+++ b/api/src/glfs-fops.c
@@ -4071,9 +4071,11 @@ invalid_fs:
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0);
+static gf_boolean_t warn_realpath = _gf_true; /* log once */
-char *
-pub_glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
+static char *
+glfs_realpath_common (struct glfs *fs, const char *path, char *resolved_path,
+ gf_boolean_t warn_deprecated)
{
int ret = -1;
char *retpath = NULL;
@@ -4088,8 +4090,20 @@ pub_glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
if (resolved_path)
retpath = resolved_path;
- else
- retpath = allocpath = malloc (PATH_MAX + 1);
+ else if (warn_deprecated) {
+ retpath = allocpath = malloc (PATH_MAX + 1);
+ if (warn_realpath) {
+ warn_realpath = _gf_false;
+ gf_log (THIS->name, GF_LOG_WARNING, "this application "
+ "is compiled against an old version of "
+ "libgfapi, it should use glfs_free() to "
+ "release the path returned by "
+ "glfs_realpath()");
+ }
+ } else {
+ retpath = allocpath = GF_CALLOC (1, PATH_MAX + 1,
+ glfs_mt_realpath_t);
+ }
if (!retpath) {
ret = -1;
@@ -4120,9 +4134,11 @@ out:
loc_wipe (&loc);
if (ret == -1) {
- if (allocpath)
- free (allocpath);
- retpath = NULL;
+ if (warn_deprecated && allocpath)
+ free (allocpath);
+ else if (allocpath)
+ GF_FREE (allocpath);
+ retpath = NULL;
}
glfs_subvol_done (fs, subvol);
@@ -4133,7 +4149,22 @@ invalid_fs:
return retpath;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.4.0);
+
+char *
+pub_glfs_realpath34 (struct glfs *fs, const char *path, char *resolved_path)
+{
+ return glfs_realpath_common (fs, path, resolved_path, _gf_true);
+}
+
+GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0);
+
+char *
+pub_glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
+{
+ return glfs_realpath_common (fs, path, resolved_path, _gf_false);
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17);
char *
diff --git a/api/src/glfs-mem-types.h b/api/src/glfs-mem-types.h
index d32d63f0f13..52033360853 100644
--- a/api/src/glfs-mem-types.h
+++ b/api/src/glfs-mem-types.h
@@ -28,6 +28,7 @@ enum glfs_mem_types_ {
glfs_mt_upcall_entry_t,
glfs_mt_acl_t,
glfs_mt_upcall_inode_t,
+ glfs_mt_realpath_t,
glfs_mt_end
};
#endif
diff --git a/api/src/glfs.h b/api/src/glfs.h
index 30600a79c32..c81b7cc5d0b 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -755,9 +755,11 @@ int glfs_chdir (glfs_t *fs, const char *path) __THROW
int glfs_fchdir (glfs_fd_t *fd) __THROW
GFAPI_PUBLIC(glfs_fchdir, 3.4.0);
-char *glfs_realpath (glfs_t *fs, const char *path, char *resolved_path) __THROW
+char *glfs_realpath34 (glfs_t *fs, const char *path, char *resolved_path) __THROW
GFAPI_PUBLIC(glfs_realpath, 3.4.0);
+char *glfs_realpath (glfs_t *fs, const char *path, char *resolved_path) __THROW
+ GFAPI_PUBLIC(glfs_realpath, 3.7.17);
/*
* @cmd and @flock are as specified in man fcntl(2).
*/