fs/autofs4/waitq.c | 21 +++++++++++++++++++-- 1 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index da8876d38a7b..f6fcca58e0e3 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "autofs_i.h" /* We make this a static variable rather than a part of the superblock; it @@ -91,6 +92,23 @@ static int autofs4_write(struct autofs_sb_info *sbi, return (bytes > 0); } + +/* + * The autofs_v5 packet was misdesigned. + * + * The packets are identical on x86-32 and x86-64, but have different + * alignment. Which means that 'sizeof()' will give different results. + * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. + */ +static noinline size_t autofs_v5_packet_size(void) +{ + size_t pktsz = sizeof(struct autofs_v5_packet); +#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) + if (is_compat_task()) + pktsz -= 4; +#endif + return pktsz; +} static void autofs4_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq, @@ -155,8 +173,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, { struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; - pktsz = sizeof(*packet); - + pktsz = autofs_v5_packet_size(); packet->wait_queue_token = wq->wait_queue_token; packet->len = wq->name.len; memcpy(packet->name, wq->name.name, wq->name.len);