|
|
e7a346 |
From fe704e0f997444d74966aa7c5bfca484ce54f6a4 Mon Sep 17 00:00:00 2001
|
|
|
e7a346 |
From: Amar Tumballi <amarts@redhat.com>
|
|
|
e7a346 |
Date: Thu, 27 Sep 2018 09:55:19 +0530
|
|
|
e7a346 |
Subject: [PATCH 389/399] server: don't allow '/' in basename
|
|
|
e7a346 |
|
|
|
e7a346 |
Server stack needs to have all the sort of validation, assuming
|
|
|
e7a346 |
clients can be compromized. It is possible for a compromized
|
|
|
e7a346 |
client to send basenames with paths with '/', and with that
|
|
|
e7a346 |
create files without permission on server. By sanitizing the basename,
|
|
|
e7a346 |
and not allowing anything other than actual directory as the parent
|
|
|
e7a346 |
for any entry creation, we can mitigate the effects of clients
|
|
|
e7a346 |
not able to exploit the server.
|
|
|
e7a346 |
|
|
|
e7a346 |
Fixes: CVE-2018-14651
|
|
|
e7a346 |
|
|
|
e7a346 |
BUG: 1633013
|
|
|
e7a346 |
Change-Id: I98d042a9f8e300161fbc3ee5b6e8de755c9765f9
|
|
|
e7a346 |
Signed-off-by: Amar Tumballi <amarts@redhat.com>
|
|
|
e7a346 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/151169
|
|
|
e7a346 |
Reviewed-by: Xavi Hernandez <xhernandez@redhat.com>
|
|
|
e7a346 |
Reviewed-by: Shyam Ranganathan <srangana@redhat.com>
|
|
|
e7a346 |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
e7a346 |
---
|
|
|
e7a346 |
xlators/protocol/server/src/server-resolve.c | 31 ++++++++++++++++++++--------
|
|
|
e7a346 |
xlators/storage/posix/src/posix-handle.h | 5 +++--
|
|
|
e7a346 |
2 files changed, 25 insertions(+), 11 deletions(-)
|
|
|
e7a346 |
|
|
|
e7a346 |
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
|
|
|
e7a346 |
index b3eda0e..25db43f 100644
|
|
|
e7a346 |
--- a/xlators/protocol/server/src/server-resolve.c
|
|
|
e7a346 |
+++ b/xlators/protocol/server/src/server-resolve.c
|
|
|
e7a346 |
@@ -307,22 +307,35 @@ resolve_entry_simple (call_frame_t *frame)
|
|
|
e7a346 |
ret = 1;
|
|
|
e7a346 |
goto out;
|
|
|
e7a346 |
}
|
|
|
e7a346 |
-
|
|
|
e7a346 |
- /* expected @parent was found from the inode cache */
|
|
|
e7a346 |
- gf_uuid_copy (state->loc_now->pargfid, resolve->pargfid);
|
|
|
e7a346 |
- state->loc_now->parent = inode_ref (parent);
|
|
|
e7a346 |
-
|
|
|
e7a346 |
- if (strstr (resolve->bname, "../")) {
|
|
|
e7a346 |
- /* Resolving outside the parent's tree is not allowed */
|
|
|
e7a346 |
+ if (parent->ia_type != IA_IFDIR) {
|
|
|
e7a346 |
+ /* Parent type should be 'directory', and nothing else */
|
|
|
e7a346 |
gf_msg (this->name, GF_LOG_ERROR, EPERM,
|
|
|
e7a346 |
PS_MSG_GFID_RESOLVE_FAILED,
|
|
|
e7a346 |
- "%s: path sent by client not allowed",
|
|
|
e7a346 |
- resolve->bname);
|
|
|
e7a346 |
+ "%s: parent type not directory (%d)",
|
|
|
e7a346 |
+ uuid_utoa (parent->gfid), parent->ia_type);
|
|
|
e7a346 |
resolve->op_ret = -1;
|
|
|
e7a346 |
resolve->op_errno = EPERM;
|
|
|
e7a346 |
ret = 1;
|
|
|
e7a346 |
goto out;
|
|
|
e7a346 |
}
|
|
|
e7a346 |
+
|
|
|
e7a346 |
+ /* expected @parent was found from the inode cache */
|
|
|
e7a346 |
+ gf_uuid_copy (state->loc_now->pargfid, resolve->pargfid);
|
|
|
e7a346 |
+ state->loc_now->parent = inode_ref (parent);
|
|
|
e7a346 |
+
|
|
|
e7a346 |
+ if (strchr (resolve->bname, '/')) {
|
|
|
e7a346 |
+ /* basename should be a string (without '/') in a directory,
|
|
|
e7a346 |
+ it can't span multiple levels. This can also lead to
|
|
|
e7a346 |
+ resolving outside the parent's tree, which is not allowed */
|
|
|
e7a346 |
+ gf_msg (this->name, GF_LOG_ERROR, EPERM,
|
|
|
e7a346 |
+ PS_MSG_GFID_RESOLVE_FAILED,
|
|
|
e7a346 |
+ "%s: basename sent by client not allowed",
|
|
|
e7a346 |
+ resolve->bname);
|
|
|
e7a346 |
+ resolve->op_ret = -1;
|
|
|
e7a346 |
+ resolve->op_errno = EPERM;
|
|
|
e7a346 |
+ ret = 1;
|
|
|
e7a346 |
+ goto out;
|
|
|
e7a346 |
+ }
|
|
|
e7a346 |
state->loc_now->name = resolve->bname;
|
|
|
e7a346 |
|
|
|
e7a346 |
inode = inode_grep (state->itable, parent, resolve->bname);
|
|
|
e7a346 |
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h
|
|
|
e7a346 |
index a0f82ec..45ca1d1 100644
|
|
|
e7a346 |
--- a/xlators/storage/posix/src/posix-handle.h
|
|
|
e7a346 |
+++ b/xlators/storage/posix/src/posix-handle.h
|
|
|
e7a346 |
@@ -223,9 +223,10 @@
|
|
|
e7a346 |
break; \
|
|
|
e7a346 |
} \
|
|
|
e7a346 |
\
|
|
|
e7a346 |
- if (strstr (loc->name, "../")) { \
|
|
|
e7a346 |
+ if (strchr (loc->name, '/')) { \
|
|
|
e7a346 |
gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_ENTRY_HANDLE_CREATE, \
|
|
|
e7a346 |
- "'../' in name not allowed: (%s)", loc->name); \
|
|
|
e7a346 |
+ "'/' in name not allowed: (%s)", loc->name); \
|
|
|
e7a346 |
+ op_ret = -1; \
|
|
|
e7a346 |
break; \
|
|
|
e7a346 |
} \
|
|
|
e7a346 |
if (LOC_HAS_ABSPATH (loc)) { \
|
|
|
e7a346 |
--
|
|
|
e7a346 |
1.8.3.1
|
|
|
e7a346 |
|