| From 66bba2339a6b1df781996c7f788e7b90be401578 Mon Sep 17 00:00:00 2001 |
| From: David Howells <dhowells@redhat.com> |
| Date: Wed, 1 May 2019 15:58:24 +0100 |
| Subject: afs: Fix getting the afs.fid xattr |
| |
| [ Upstream commit a2f611a3dc317d8ea1c98ad6c54b911cf7f93193 ] |
| |
| The AFS3 FID is three 32-bit unsigned numbers and is represented as three |
| up-to-8-hex-digit numbers separated by colons to the afs.fid xattr. |
| However, with the advent of support for YFS, the FID is now a 64-bit volume |
| number, a 96-bit vnode/inode number and a 32-bit uniquifier (as before). |
| Whilst the sprintf in afs_xattr_get_fid() has been partially updated (it |
| currently ignores the upper 32 bits of the 96-bit vnode number), the size |
| of the stack-based buffer has not been increased to match, thereby allowing |
| stack corruption to occur. |
| |
| Fix this by increasing the buffer size appropriately and conditionally |
| including the upper part of the vnode number if it is non-zero. The latter |
| requires the lower part to be zero-padded if the upper part is non-zero. |
| |
| Fixes: 3b6492df4153 ("afs: Increase to 64-bit volume ID and 96-bit vnode ID for YFS") |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/afs/xattr.c | 15 ++++++++++++--- |
| 1 file changed, 12 insertions(+), 3 deletions(-) |
| |
| diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c |
| index a2cdf25573e24..706801c6c4c4c 100644 |
| --- a/fs/afs/xattr.c |
| +++ b/fs/afs/xattr.c |
| @@ -69,11 +69,20 @@ static int afs_xattr_get_fid(const struct xattr_handler *handler, |
| void *buffer, size_t size) |
| { |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| - char text[8 + 1 + 8 + 1 + 8 + 1]; |
| + char text[16 + 1 + 24 + 1 + 8 + 1]; |
| size_t len; |
| |
| - len = sprintf(text, "%llx:%llx:%x", |
| - vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); |
| + /* The volume ID is 64-bit, the vnode ID is 96-bit and the |
| + * uniquifier is 32-bit. |
| + */ |
| + len = sprintf(text, "%llx:", vnode->fid.vid); |
| + if (vnode->fid.vnode_hi) |
| + len += sprintf(text + len, "%x%016llx", |
| + vnode->fid.vnode_hi, vnode->fid.vnode); |
| + else |
| + len += sprintf(text + len, "%llx", vnode->fid.vnode); |
| + len += sprintf(text + len, ":%x", vnode->fid.unique); |
| + |
| if (size == 0) |
| return len; |
| if (len > size) |
| -- |
| 2.20.1 |
| |