[PATCH, V3 (sort of)] xfs: zero proper structure size for geometry calls
Alex Elder
aelder at sgi.com
Tue Mar 1 11:50:00 CST 2011
I'm sorry to muddy the waters with this. But I think the
proposed patch fixes the wrong problem. Having xfs_fs_geometry()
zero its argument is fine--it defines an interface and honors
it. The real problem lies in xfs_ioc_fsgeometry_v1(), which
violates that interface by passing the address of an object
that's not the right size. So below is an alternative to
Eric's solution which just fixes this one caller instead.
Eric has already told me this makes more sense. It would
be nice if Jeffrey would re-test this fix, and Dan would
sign off on it as well.
-Alex
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 at mnsu.edu>
Signed-off-by: Alex Elder <aelder at sgi.com>
---
fs/xfs/linux-2.6/xfs_ioctl.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
Index: b/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- 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(
xfs_mount_t *mp,
void __user *arg)
{
- xfs_fsop_geom_v1_t fsgeo;
+ xfs_fsop_geom_t fsgeo;
int error;
- error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3);
+ error = xfs_fs_geometry(mp, &fsgeo, 3);
if (error)
return -error;
- if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
+ /*
+ * Caller should have passed an argument of type
+ * xfs_fsop_geom_v1_t. This is a proper subset of the
+ * xfs_fsop_geom_t that xfs_fs_geometry() fills in.
+ */
+ if (copy_to_user(arg, &fsgeo, sizeof (xfs_fsop_geom_v1_t)))
return -XFS_ERROR(EFAULT);
return 0;
}
More information about the xfs
mailing list