diff options
author | Harshavardhana <harsha@harshavardhana.net> | 2014-07-12 02:15:14 -0700 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2014-07-18 18:37:10 -0700 |
commit | d30c3dcf1137a0a94c0be0d0c57de86aadad2a33 (patch) | |
tree | b61672bdff3dc2ce6750cceeb55abaebd1469a0f /xlators/mount | |
parent | f548db88ad78c24124befef9473792a574f7e157 (diff) |
fuse: fuse_readlink_cbk() - linkname NULL termination unnecessary
op_ret incremented to compensate for NULL terminating character
leads to self referential loop where OSXFUSE which would reply
on a same READLINK() over and over again
~~~
[2014-07-12 08:41:29.815473]
T [fuse-bridge.c:1372:fuse_readlink_cbk] 0-glusterfs-fuse:
1: /a/b/1 => ../../1
[2014-07-12 08:41:29.815820]
T [fuse-bridge.c:1372:fuse_readlink_cbk] 0-glusterfs-fuse:
0: /a/b/1 => ../../1
[2014-07-12 08:41:29.816165]
T [fuse-bridge.c:1372:fuse_readlink_cbk] 0-glusterfs-fuse:
1: /a/b/1 => ../../1
~~~
It happens due to the problem being (op_ret + 1) > strlen(linkname),
for some odd reason this isn't an issue on Linux where there are odd
safegaurds on these things - Example of following code
~~~
((char *)linkname)[op_ret] = '\0';
send_fuse_data (this, finh, (void *)linkname, op_ret + 2048); <---- Here!
~~~
This behaves normally with no issue, the reasoning i have is that
internally 'readlink()' is verified with strlen() again or perhaps the size
is re-adjusted to the strlen() of `linkname`
This isn't the case on OSX, one needs to make sure that
~~~
strlen(linkname) == op_ret
~~~
Otherwise you would get READLINK() loops as shown above.
This patch fixes the problem.
Many thanks to Anand Avati for helping me out on this.
Change-Id: Ia35818de78a5e4d89bad03ab06e2c5ed6e6753a4
BUG: 1095525
Signed-off-by: Harshavardhana <harsha@harshavardhana.net>
Reviewed-on: http://review.gluster.org/8300
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/mount')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 473911a2cb0..0aadb649fbd 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -1365,13 +1365,10 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, uuid_utoa (state->loc.gfid)); if (op_ret > 0) { - ((char *)linkname)[op_ret] = '\0'; - gf_log ("glusterfs-fuse", GF_LOG_TRACE, - "%"PRIu64": %s => %s", frame->root->unique, - state->loc.path, linkname); - - send_fuse_data (this, finh, (void *)linkname, op_ret + 1); + "%"PRIu64": %s => %s (size:%d)", frame->root->unique, + state->loc.path, linkname, op_ret); + send_fuse_data (this, finh, (void *)linkname, op_ret); } else { gf_log ("glusterfs-fuse", GF_LOG_WARNING, "%"PRIu64": %s => -1 (%s)", frame->root->unique, |