Message ID | 20181215012259.28358-4-nbowler@draconx.ca (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
Series | Fixing xfs ioctls on x32 | expand |
On Fri, Dec 14, 2018 at 08:22:59PM -0500, Nick Bowler wrote: > Several ioctl structs change size between native 32-bit (ia32) and x32 > applications, because x32 follows the native 64-bit (amd64) integer > alignment rules and uses 64-bit time_t. In these instances, the ioctl > number changes so userspace simply gets -ENOTTY. This scenario can be > handled by simply adding more cases. > > Looking at the different ioctls implemented here: > > - All the ones marked 'No size or alignment issue on any arch' should > presumably all be fine. > > - All the ones under BROKEN_X86_ALIGNMENT are different under integer > alignment rules. Since x32 matches amd64 here, we just need both > sets of cases handled. > > - XFS_IOC_SWAPEXT has both integer alignment differences and time_t > differences. Since x32 matches amd64 here, we need to add a case > which calls the native implementation. > > - The remaining ioctls have neither 64-bit integers nor time_t, so > x32 matches ia32 here and no change is required at this level. The > bulkstat ioctl implementations have some pointer chasing which is > handled separately. > > Signed-off-by: Nick Bowler <nbowler@draconx.ca> Looks mostly ok to me, provided they don't drop x32 this release. (It doesn't sound to me like that's going to happen any time soon...) Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> (Will try to test all this... /me flexes his cross-arch muscles...) --D > --- > fs/xfs/xfs_ioctl32.c | 18 +++++++++++++++--- > 1 file changed, 15 insertions(+), 3 deletions(-) > > diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c > index 1cdc75dca779..bd9ffad0f65e 100644 > --- a/fs/xfs/xfs_ioctl32.c > +++ b/fs/xfs/xfs_ioctl32.c > @@ -579,8 +579,12 @@ xfs_file_compat_ioctl( > case FS_IOC_GETFSMAP: > case XFS_IOC_SCRUB_METADATA: > return xfs_file_ioctl(filp, cmd, p); > -#ifndef BROKEN_X86_ALIGNMENT > - /* These are handled fine if no alignment issues */ > +#if !defined(BROKEN_X86_ALIGNMENT) || defined(CONFIG_X86_X32) > + /* > + * These are handled fine if no alignment issues. To support x32 > + * which uses native 64-bit alignment we must emit these cases in > + * addition to the ia-32 compat set below. > + */ > case XFS_IOC_ALLOCSP: > case XFS_IOC_FREESP: > case XFS_IOC_RESVSP: > @@ -593,8 +597,16 @@ xfs_file_compat_ioctl( > case XFS_IOC_FSGROWFSDATA: > case XFS_IOC_FSGROWFSRT: > case XFS_IOC_ZERO_RANGE: > +#ifdef CONFIG_X86_X32 > + /* > + * x32 special: this gets a different cmd number from the ia-32 compat > + * case below; the associated data will match native 64-bit alignment. > + */ > + case XFS_IOC_SWAPEXT: > +#endif > return xfs_file_ioctl(filp, cmd, p); > -#else > +#endif > +#if defined(BROKEN_X86_ALIGNMENT) > case XFS_IOC_ALLOCSP_32: > case XFS_IOC_FREESP_32: > case XFS_IOC_ALLOCSP64_32: > -- > 2.16.1 >
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index 1cdc75dca779..bd9ffad0f65e 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -579,8 +579,12 @@ xfs_file_compat_ioctl( case FS_IOC_GETFSMAP: case XFS_IOC_SCRUB_METADATA: return xfs_file_ioctl(filp, cmd, p); -#ifndef BROKEN_X86_ALIGNMENT - /* These are handled fine if no alignment issues */ +#if !defined(BROKEN_X86_ALIGNMENT) || defined(CONFIG_X86_X32) + /* + * These are handled fine if no alignment issues. To support x32 + * which uses native 64-bit alignment we must emit these cases in + * addition to the ia-32 compat set below. + */ case XFS_IOC_ALLOCSP: case XFS_IOC_FREESP: case XFS_IOC_RESVSP: @@ -593,8 +597,16 @@ xfs_file_compat_ioctl( case XFS_IOC_FSGROWFSDATA: case XFS_IOC_FSGROWFSRT: case XFS_IOC_ZERO_RANGE: +#ifdef CONFIG_X86_X32 + /* + * x32 special: this gets a different cmd number from the ia-32 compat + * case below; the associated data will match native 64-bit alignment. + */ + case XFS_IOC_SWAPEXT: +#endif return xfs_file_ioctl(filp, cmd, p); -#else +#endif +#if defined(BROKEN_X86_ALIGNMENT) case XFS_IOC_ALLOCSP_32: case XFS_IOC_FREESP_32: case XFS_IOC_ALLOCSP64_32:
Several ioctl structs change size between native 32-bit (ia32) and x32 applications, because x32 follows the native 64-bit (amd64) integer alignment rules and uses 64-bit time_t. In these instances, the ioctl number changes so userspace simply gets -ENOTTY. This scenario can be handled by simply adding more cases. Looking at the different ioctls implemented here: - All the ones marked 'No size or alignment issue on any arch' should presumably all be fine. - All the ones under BROKEN_X86_ALIGNMENT are different under integer alignment rules. Since x32 matches amd64 here, we just need both sets of cases handled. - XFS_IOC_SWAPEXT has both integer alignment differences and time_t differences. Since x32 matches amd64 here, we need to add a case which calls the native implementation. - The remaining ioctls have neither 64-bit integers nor time_t, so x32 matches ia32 here and no change is required at this level. The bulkstat ioctl implementations have some pointer chasing which is handled separately. Signed-off-by: Nick Bowler <nbowler@draconx.ca> --- fs/xfs/xfs_ioctl32.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)