From dec2674685da30d6cef157748bcf52454ec97208 Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Sat, 16 May 2009 04:28:40 +0200 Subject: make getxattr fail with ERANGE if reply is bigger than what was requested Edited by avati: make the function signature of fuse_xattr_reply_buf() use 'const char *value' instead of 'char *value' Signed-off-by: Anand V. Avati --- xlators/mount/fuse/src/fuse-bridge.c | 56 ++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'xlators/mount') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 297744cd6..2a5c0cc29 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -1919,6 +1919,24 @@ fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name, return; } +static void +fuse_reply_xattr_buf(fuse_state_t *state, fuse_req_t req, const char *value, + size_t ret) +{ + /* linux kernel limits the size of xattr value to 64k */ + if (ret > GLUSTERFS_XATTR_LEN_MAX) + fuse_reply_err (req, E2BIG); + else if (state->size) { + /* if callback for getxattr and asks for value */ + if (ret > state->size) + /* reply would be bigger than + * what was asked by kernel */ + fuse_reply_err (req, ERANGE); + else + fuse_reply_buf (req, value, ret); + } else + fuse_reply_xattr (req, ret); +} static int fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -1981,16 +1999,8 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ret = value_data->len; /* Don't return the value for '\0' */ value = value_data->data; - /* linux kernel limits the size of xattr value to 64k */ - if (ret > GLUSTERFS_XATTR_LEN_MAX) { - fuse_reply_err (req, E2BIG); - } else if (state->size) { - /* if callback for getxattr and asks for value */ - fuse_reply_buf (req, value, ret); - } else { - /* if callback for getxattr and asks for value length only */ - fuse_reply_xattr (req, ret); - } /* if(ret >...)...else if...else */ + fuse_reply_xattr_buf (state, req, value, ret); + /* if(ret >...)...else if...else */ } else if (!strcmp (state->name, "user.glusterfs-booster-volfile")) { if (!priv->volfile) { memset (&st, 0, sizeof (st)); @@ -2011,21 +2021,11 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } } - if (priv->volfile_size > GLUSTERFS_XATTR_LEN_MAX) { - fuse_reply_err (req, E2BIG); - } else if (state->size) { - /* if callback for getxattr and asks for value */ - fuse_reply_buf (req, priv->volfile, priv->volfile_size); - } else { - /* if callback for getxattr and asks for value length only */ - fuse_reply_xattr (req, priv->volfile_size); - } /* if(ret >...)...else if...else */ + fuse_reply_xattr_buf (state, req, priv->volfile, priv->volfile_size); + /* if(ret >...)...else if...else */ } else if (!strcmp (state->name, "user.glusterfs-booster-path")) { - if (state->size) { - fuse_reply_buf (req, state->loc.path, strlen (state->loc.path) + 1); - } else { - fuse_reply_xattr (req, strlen (state->loc.path) + 1); - } + fuse_reply_xattr_buf (state, req, state->loc.path, + strlen(state->loc.path) + 1); } else { fuse_reply_err (req, ENODATA); } /* if(value_data)...else */ @@ -2046,13 +2046,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, len += strlen (trav->key) + 1; trav = trav->next; } /* while(trav) */ - if (state->size) { - /* if callback for listxattr and asks for list of keys */ - fuse_reply_buf (req, value, len); - } else { - /* if callback for listxattr and asks for length of keys only */ - fuse_reply_xattr (req, len); - } /* if(state->size)...else */ + fuse_reply_xattr_buf (state, req, value, len); } /* if(state->name)...else */ } else { /* if failure - no need to check if listxattr or getxattr */ -- cgit