diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2015-05-29 13:50:09 +0530 |
---|---|---|
committer | Raghavendra Bhat <raghavendra@redhat.com> | 2015-09-01 23:07:59 -0700 |
commit | ff1dd9885ff99a9d185f4efe5613c7c5f387d2f0 (patch) | |
tree | e437b923fb910aa1e5a2a18c9fd347572216191f | |
parent | 1ad184978892bc7368c5da11c59ec4fad73cb1df (diff) |
storage/posix: Prevent malformed internal link creations
Change-Id: Ia3408f795dcfac143fe898fc5f4d31d2c6f236c1
BUG: 1212110
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/10999
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
-rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 76 |
1 files changed, 43 insertions, 33 deletions
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, |