summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/protocol/server/src/server-resolve.c21
-rw-r--r--xlators/storage/posix/src/posix-handle.h4
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; \
} \