diff options
| author | Emmanuel Dreyfus <manu@netbsd.org> | 2014-11-28 17:49:25 +0100 | 
|---|---|---|
| committer | Raghavendra Bhat <raghavendra@redhat.com> | 2014-12-20 01:39:39 -0800 | 
| commit | 4973b6c54e0887f260e2b7507dcc1ac76a36a612 (patch) | |
| tree | b0ee7cfd00ac1f9531f3e1c199ee2139d8fb39bf | |
| parent | 211b8a8dc8cd146e509d0c822ce1151d5614524e (diff) | |
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 <manu@netbsd.org>
Reviewed-on: http://review.gluster.org/9215
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
| -rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 7 | 
1 files 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;  | 
