From 4973b6c54e0887f260e2b7507dcc1ac76a36a612 Mon Sep 17 00:00:00 2001 From: Emmanuel Dreyfus Date: Fri, 28 Nov 2014 17:49:25 +0100 Subject: posix: Fix buffer overrun in _handle_list_xattr() In _handle_list_xattr() we test remaining_size > 0 to check that we do not overrun the buffer, but since that variable was unsigned (size_t), the condition would let us go beyond end of buffer if remaining_size became negative. This could happen if attribute list grew between the first sys_llistxattr() call that gets the size and the second sys_llistxattr() call that get the data. We fix the problem by making remaining_size signed (ssize_t). This also matches sys_llistxattr() return type. While there, we use the size returned by the second sys_llistxattr() call to parse the buffser, as it may also be smaller than the size obtained from first call, if attribute list shrank. This fixes a spurious crash in tests/basic/afr/resolve.t backport of: Ifc5884dd0f39a50bf88aa51fefca8e2fa22ea913 BUG: 1138897 Change-Id: I37d4816b9cb246e34c92994cb969dc2be80be20d Signed-off-by: Emmanuel Dreyfus Reviewed-on: http://review.gluster.org/9215 Tested-by: Gluster Build System Reviewed-by: Raghavendra Bhat --- xlators/storage/posix/src/posix-helpers.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 81edb93d7d0..7fa1d496a3a 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -580,7 +580,7 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, ssize_t size = 0; char *list = NULL; int32_t list_offset = 0; - size_t remaining_size = 0; + ssize_t remaining_size = 0; char *key = NULL; if (!real_path) @@ -594,11 +594,10 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, if (!list) goto out; - size = sys_llistxattr (real_path, list, size); - if (size <= 0) + remaining_size = sys_llistxattr (real_path, list, size); + if (remaining_size <= 0) goto out; - remaining_size = size; list_offset = 0; while (remaining_size > 0) { key = list + list_offset; -- cgit