diff options
author | Alex Elder <aelder@sgi.com> | 2011-03-01 12:50:00 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-03-01 22:21:13 -0500 |
commit | af24ee9ea8d532e16883251a6684dfa1be8eec29 (patch) | |
tree | 0c6da066dd656121c077ba6b595503e0b6a41180 /fs | |
parent | dd9c1549edef02290edced639f67b54a25abbe0e (diff) |
xfs: zero proper structure size for geometry calls
Commit 493f3358cb289ccf716c5a14fa5bb52ab75943e5 added this call to
xfs_fs_geometry() in order to avoid passing kernel stack data back
to user space:
+ memset(geo, 0, sizeof(*geo));
Unfortunately, one of the callers of that function passes the
address of a smaller data type, cast to fit the type that
xfs_fs_geometry() requires. As a result, this can happen:
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted
in: f87aca93
Pid: 262, comm: xfs_fsr Not tainted 2.6.38-rc6-493f3358cb2+ #1
Call Trace:
[<c12991ac>] ? panic+0x50/0x150
[<c102ed71>] ? __stack_chk_fail+0x10/0x18
[<f87aca93>] ? xfs_ioc_fsgeometry_v1+0x56/0x5d [xfs]
Fix this by fixing that one caller to pass the right type and then
copy out the subset it is interested in.
Note: This patch is an alternative to one originally proposed by
Eric Sandeen.
Reported-by: Jeffrey Hundstad <jeffrey.hundstad@mnsu.edu>
Signed-off-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Tested-by: Jeffrey Hundstad <jeffrey.hundstad@mnsu.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index f5e2a19e0f8e..0ca0e3c024d7 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -695,14 +695,19 @@ xfs_ioc_fsgeometry_v1( | |||
695 | xfs_mount_t *mp, | 695 | xfs_mount_t *mp, |
696 | void __user *arg) | 696 | void __user *arg) |
697 | { | 697 | { |
698 | xfs_fsop_geom_v1_t fsgeo; | 698 | xfs_fsop_geom_t fsgeo; |
699 | int error; | 699 | int error; |
700 | 700 | ||
701 | error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3); | 701 | error = xfs_fs_geometry(mp, &fsgeo, 3); |
702 | if (error) | 702 | if (error) |
703 | return -error; | 703 | return -error; |
704 | 704 | ||
705 | if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) | 705 | /* |
706 | * Caller should have passed an argument of type | ||
707 | * xfs_fsop_geom_v1_t. This is a proper subset of the | ||
708 | * xfs_fsop_geom_t that xfs_fs_geometry() fills in. | ||
709 | */ | ||
710 | if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) | ||
706 | return -XFS_ERROR(EFAULT); | 711 | return -XFS_ERROR(EFAULT); |
707 | return 0; | 712 | return 0; |
708 | } | 713 | } |