From ff1dd9885ff99a9d185f4efe5613c7c5f387d2f0 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Fri, 29 May 2015 13:50:09 +0530 Subject: storage/posix: Prevent malformed internal link creations Change-Id: Ia3408f795dcfac143fe898fc5f4d31d2c6f236c1 BUG: 1212110 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/10999 Tested-by: NetBSD Build System Tested-by: Gluster Build System Reviewed-by: Raghavendra Bhat --- xlators/storage/posix/src/posix-handle.c | 76 ++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'xlators/storage/posix') diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index f67389dcc0f..331f7212614 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -232,6 +232,42 @@ posix_handle_relpath (xlator_t *this, uuid_t gfid, const char *basename, /* TODO: explain how this pump fixes ELOOP */ +gf_boolean_t +posix_is_malformed_link (xlator_t *this, char *base_str, char *linkname, + size_t len) +{ + if ((len == 8) && strcmp (linkname, "../../..")) /*for root*/ + goto err; + + if (len < 50 || len >= 512) + goto err; + + if (memcmp (linkname, "../../", 6) != 0) + goto err; + + if ((linkname[2] != '/') || + (linkname[5] != '/') || + (linkname[8] != '/') || + (linkname[11] != '/') || + (linkname[48] != '/')) { + goto err; + } + + if ((linkname[20] != '-') || + (linkname[25] != '-') || + (linkname[30] != '-') || + (linkname[35] != '-')) { + goto err; + } + + return _gf_false; + +err: + gf_log_callingfn (this->name, GF_LOG_ERROR, "malformed internal link " + "%s for %s", linkname, base_str); + return _gf_true; +} + int posix_handle_pump (xlator_t *this, char *buf, int len, int maxlen, char *base_str, int base_len, int pfx_len) @@ -262,40 +298,8 @@ posix_handle_pump (xlator_t *this, char *buf, int len, int maxlen, goto out; } - if (ret < 50 || ret >= 512) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_LINK_FAILED, - "malformed internal link %s for %s", - linkname, base_str); + if (posix_is_malformed_link (this, base_str, linkname, ret)) goto err; - } - - if (memcmp (linkname, "../../", 6) != 0) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_HANDLEPATH_FAILED, - "malformed internal link %s for %s", - linkname, base_str); - goto err; - } - - if ((linkname[2] != '/') || - (linkname[5] != '/') || - (linkname[8] != '/') || - (linkname[11] != '/') || - (linkname[48] != '/')) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_HANDLEPATH_FAILED, - "malformed internal link %s for %s", - linkname, base_str); - goto err; - } - - if ((linkname[20] != '-') || - (linkname[25] != '-') || - (linkname[30] != '-') || - (linkname[35] != '-')) { - gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_HANDLEPATH_FAILED, - "malformed internal link %s for %s", - linkname, base_str); - goto err; - } blen = link_len - 48; @@ -774,6 +778,12 @@ posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc, } if (ret == -1 && errno == ENOENT) { + if (posix_is_malformed_link (this, newpath, oldpath, + strlen (oldpath))) { + GF_ASSERT (!"Malformed link"); + errno = EINVAL; + return -1; + } ret = posix_handle_mkdir_hashes (this, newpath); if (ret) { gf_msg (this->name, GF_LOG_WARNING, errno, -- cgit