diff options
-rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 21 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-handle.h | 4 |
2 files changed, 19 insertions, 6 deletions
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index ba4d2f16a93..26260a5ee2c 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -294,19 +294,32 @@ resolve_entry_simple(call_frame_t *frame) goto out; } + if (parent->ia_type != IA_IFDIR) { + /* Parent type should be 'directory', and nothing else */ + gf_msg(this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED, + "%s: parent type not directory (%d)", uuid_utoa(parent->gfid), + parent->ia_type); + resolve->op_ret = -1; + resolve->op_errno = EPERM; + ret = 1; + goto out; + } + /* expected @parent was found from the inode cache */ gf_uuid_copy(state->loc_now->pargfid, resolve->pargfid); state->loc_now->parent = inode_ref(parent); - - if (strstr(resolve->bname, "../")) { - /* Resolving outside the parent's tree is not allowed */ + if (strchr(resolve->bname, '/')) { + /* basename should be a string (without '/') in a directory, + it can't span multiple levels. This can also lead to + resolving outside the parent's tree, which is not allowed */ gf_msg(this->name, GF_LOG_ERROR, EPERM, PS_MSG_GFID_RESOLVE_FAILED, - "%s: path sent by client not allowed", resolve->bname); + "%s: basename sent by client not allowed", resolve->bname); resolve->op_ret = -1; resolve->op_errno = EPERM; ret = 1; goto out; } + state->loc_now->name = resolve->bname; inode = inode_grep(state->itable, parent, resolve->bname); diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h index 7c79b569128..c4d7cb14503 100644 --- a/xlators/storage/posix/src/posix-handle.h +++ b/xlators/storage/posix/src/posix-handle.h @@ -150,9 +150,9 @@ break; \ } \ \ - if (strstr(loc->name, "../")) { \ + if (strchr(loc->name, '/')) { \ gf_msg(this->name, GF_LOG_ERROR, 0, P_MSG_ENTRY_HANDLE_CREATE, \ - "'../' in name not allowed: (%s)", loc->name); \ + "'/' in name not allowed: (%s)", loc->name); \ op_ret = -1; \ break; \ } \ |