Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp3348524ybc; Thu, 14 Nov 2019 07:48:20 -0800 (PST) X-Google-Smtp-Source: APXvYqwzHME4T5alo2StedGqO3Yyi6kmkd57fA2CAQ5KOSAA1PFJUJy8u1o+inyGPJjznWjht67B X-Received: by 2002:a50:eb91:: with SMTP id y17mr2017492edr.216.1573746500649; Thu, 14 Nov 2019 07:48:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573746500; cv=none; d=google.com; s=arc-20160816; b=e0cvt41Wbm4fW8QiAjAwBHSpmipCyoI3wvI37iHlVQy31ktltDYT02Aaa1vMIoYYUu nvX6C6hMtWAjK3hwQbJQwAjfZqPlIdQyGPw2ZV7zg4GjncD2RvOueNe9oJ2SoT8ZmdJn rOipfrpIkVBaV1lqLVswy8JQN0weL5x73c5fgF/HS4qBxhwFm529KprsqDPotPUEiAul 7ogH1DnKLe9AVTtrH7FMFEAEXVKtZ5Kb/R+BHGJjc3MnTLDHLvmOtjUxR5TMBlEFOYk0 DLxuHx10TWDJlkHwl23/pIkhb+7kED8IOKjTrfiVdfP7c60JxzoDOtSDpUugO3Vo1Et7 Cgbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:content-disposition :mime-version:message-id:subject:cc:to:from:date; bh=0omqymYwc8Sar67oWZiqwbSqW2E9qYvTRDQrI8LEwNQ=; b=JqTrUOblaA5DzSZsrF2OUDwaKaUwpZC9kUoxmjo17wLPI6iSRl/UXQvdD6c4nsuZI8 6MwjQ1G+1cf+KoChlApcatcpO3B5ysgKVvHwP0tAujLMmGPet0FKJ0zQUwJ/k2g4G5di lJPQ+DmxWKfgRGEAnTsD1vxL+sYFd3Z9DnqExCxvJas16pcgMPlFetBKUWtF/TAWfoKi TaXhviVI1ZqrriH8nn4CAnqlWMQ3Ey1CKc2GsiKtuquwMjXQOXb+Vi9pnWqCpQXbsLGl NYy3rX/VFeORV8BPnSPNLcwHDMaUuFozC44LSQ9QHucBLzWAsTK3NhfQjIJhC6+vTzK8 RpOQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o21si3624265ejx.139.2019.11.14.07.47.43; Thu, 14 Nov 2019 07:48:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726901AbfKNPrZ (ORCPT + 99 others); Thu, 14 Nov 2019 10:47:25 -0500 Received: from zeniv.linux.org.uk ([195.92.253.2]:41912 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726894AbfKNPrZ (ORCPT ); Thu, 14 Nov 2019 10:47:25 -0500 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92.3 #3 (Red Hat Linux)) id 1iVHL9-0006xg-Ji; Thu, 14 Nov 2019 15:47:23 +0000 Date: Thu, 14 Nov 2019 15:47:23 +0000 From: Al Viro To: Amir Goldstein Cc: linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, "J. Bruce Fields" Subject: [RFC] is ovl_fh->fid really intended to be misaligned? Message-ID: <20191114154723.GJ26530@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org AFAICS, this bytes = (fh->len - offsetof(struct ovl_fh, fid)); real = exportfs_decode_fh(mnt, (struct fid *)fh->fid, bytes >> 2, (int)fh->type, connected ? ovl_acceptable : NULL, mnt); in ovl_decode_real_fh() combined with origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt, connected); in ovl_check_origin_fh(), /* First lookup overlay inode in inode cache by origin fh */ err = ovl_check_origin_fh(ofs, fh, false, NULL, &stack); in ovl_lower_fh_to_d() and struct ovl_fh *fh = (struct ovl_fh *) fid; ... ovl_lower_fh_to_d(sb, fh); in ovl_fh_to_dentry() leads to the pointer to struct fid passed to exportfs_decode_fh() being 21 bytes ahead of that passed to ovl_fh_to_dentry(). However, alignment of struct fid pointers is 32 bits and quite a few places dealing with those (including ->fh_to_dentry() instances) do access them directly. Argument of ->fh_to_dentry() is supposed to be 32bit-aligned, and callers generally guarantee that. Your code, OTOH, violates the alignment systematically there - what it passes to layers' ->fh_to_dentry() (by way of exportfs_decode_fh()) always has two lower bits different from what it got itself. What do we do with that? One solution would be to insert sane padding in ovl_fh, but the damn thing appears to be stored as-is in xattrs on disk, so that would require rather unpleasant operations reinserting the padding on the fly ;-/ Another is to declare struct fid unaligned with explicit use of __aligned in declaration and let all code normally dealing with those pay the price. Frankly, I don't like that - it's overlayfs mess, so penalizing the much older users doesn't sound like a good idea. Worse, any code that does (like overlayfs) cast the incoming struct fid * to a pointer to its own struct will still be in trouble - explicit cast is explicit cast, and it discards all alignment information (as yours has done). BTW, your ->encode_fh() appears to report the length greater than the object it has returned... Granted, the 3 overreported bytes will be right after the end of 4n+1-byte kmalloc'ed area, so they won't fall over the page boundary, but the values in those are left uninitialized. And they are sent in over-the-wire representations; you ignore those on decode, but they are there.