Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp132061yba; Tue, 23 Apr 2019 21:14:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqwWnqVXPcW9ecuHtYPBcz3HC7J83NKkNBvSC+mm0mB0P68qiVApCbwVAzont8lXCjdAlTKC X-Received: by 2002:a65:5183:: with SMTP id h3mr28215320pgq.53.1556079247551; Tue, 23 Apr 2019 21:14:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556079247; cv=none; d=google.com; s=arc-20160816; b=HzpJEyt4O7E8HVfS34/z6aoPvb8ICR8IY4/dTl0HA9OOWbutded0X4BDUWiO+Ncj4p UtCdWk2D2R91MrlYV8zVRcKnB4idDYZljqI8EIvI/HZhWbV6oXajYuKgrDS8yhFCaNi3 eTEXqCE5JaBMTzt3dvdJnHdXONZM0nZBjZx69LJqa1VYuPrqvRvMcsgDCKo6cBWCjSz/ gLk6WIi4wJGuhN9PtY05ESYFDO5CvdYcdye+Rbx7fB5gtd9YerLlXz8zK71o6+l2OsNk Mr5bQKkaCg5GK1+Sm6zHUK6PPPlCinqxGOjiO14EKxqGBnop+hgX1cwHVy+JGHUE/QrO PRbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=Y+wgi82U3QomYPozXeDwrUA0uhlQaRCTFeZbFZZb/2U=; b=ZehWp8INXM4OA/fp7Z484UT1+12a27hKHCUdQWW5aAEpYrFp0nKKsRQAOUaFkytzxn Y1bvxqW9NVrF94V3pjsrFNNqtO4Lb+AsDonz5h3OYaXp/hAdDYf+/28u0l9GB7/enuI4 NwQFpjkqFZSBbCn14DU0jPwDNTeu82Ptc5OPTWqXedeH3SxsqSMptiae0qPSswHCCVVC Rn/waeV/+JhE+nM3NMNOwleu2RRFXEMJ14u4ZH5fLsveFUKnGHSXS5rsBfJjnOtnQNfb rKPPSHCMnT1Ms0cpIVChHopL9ly1ekPv2aekadqsyipStvooSFog3kyHhBpDfQz/Fi14 KW0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 d2si16094109pgv.22.2019.04.23.21.13.51; Tue, 23 Apr 2019 21:14:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726151AbfDXENA (ORCPT + 99 others); Wed, 24 Apr 2019 00:13:00 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:45870 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725440AbfDXENA (ORCPT ); Wed, 24 Apr 2019 00:13:00 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92 #3 (Red Hat Linux)) id 1hJ9HC-0001md-Vb; Wed, 24 Apr 2019 04:12:55 +0000 Date: Wed, 24 Apr 2019 05:12:54 +0100 From: Al Viro To: Bharath Vedartham Cc: dushistov@mail.ru, linux-kernel@vger.kernel.org Subject: Re: [PATCH] fs/ufs: Force type conversion from __fs16 to u16 Message-ID: <20190424041254.GO2217@ZenIV.linux.org.uk> References: <20190423090118.GA465@bharath12345-Inspiron-5559> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190423090118.GA465@bharath12345-Inspiron-5559> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 23, 2019 at 02:31:18PM +0530, Bharath Vedartham wrote: > This patch fixes the sparse warning: > warning: restricted __fs16 degrades to integer > > inode->ui_u1.oldids.ui_suid is of type __fs16, a restricted integer. > 0XFFFF is a 16 bit unsigned integer. Use __force to fix the sparse > warning. NAK. As always, ask whether the code is correct and if so, why is it correct. Here, of course, the answer is that 16bit value with all bits set is the same regardless of endianness. If it was le16, we could simply write cpu_to_le16(0xffff) and let the compiler fold the constant expression; for fs16 it's beyond what gcc can (reliably) do - you get essentially UFS_SB(sbp)->s_bytesex == BYTESEX_LE ? (unsigned short)0xffff : (unsigned short)0xffff which would be nice to optimize to 0xffff, but it's not guaranteed to happen. So let's do this: static inline bool ufs_reserved_uid(__fs16 uid) { return (__fs16)~uid == 0; /* all 16 bits set */ } and use it in... wait. Wait, it *is* broken. Look: static inline u32 ufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode) { switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { case UFS_UID_44BSD: return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid); case UFS_UID_EFT: if (inode->ui_u1.oldids.ui_suid == 0xFFFF) return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid); /* Fall through */ default: return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid); } } OK, so * old flavours: 16bit uids, stored in ->ui_u1.oldids.ui_suid (offset 4) * new flavours (44bsd, ufs2, openstep): 32bit uids, stored in ->ui_u3.ui_44.ui_uid (offset 0x70) * Solaris flavours (sun, sunx86): 32bit uids; if smaller than 0xffff, stored where old flavours used to, if greater or equal - stored in ->ui_u3.ui_sun.ui_uid (offset 0x74), with 0xffff stored in the old place. Makes sense, and ufs_set_inode_uid() matches that (with extra piece of information - for new flavours the lower 16 bits of uid are duplicated into the old place, for solaris - min(uid, 0xffff) goes there). However, the other place with similar logics is static inline u32 ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode) { switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { case UFS_UID_44BSD: return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid); case UFS_UID_EFT: if (inode->ui_u1.oldids.ui_suid == 0xFFFF) return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); /* Fall through */ default: return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid); } } See the problem? For Solaris flavours we check the old *UID* location to decide whether we want the new GID one or the old GID one. That makes no sense - after all, setting UID=1000, GID=80000 should be possible, and that couldn't work; we would get 1000 stored in old UID location, 80000 - in new GID one, so this ufs_get_inode_gid() would end up returning the old GID field, which is 16bit and could not store 80000, no matter what. So we have a braino in ufs_get_inode_gid(), AFAICS since 252e211e90ce5 ("Add in SunOS 4.1.x compatible mode for UFS"). It should go if (inode->ui_u1.oldids.ui_sgid == 0xFFFF) return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); instead of checking ui_suid... The breakage there isn't what sparse complained about, but it still needs fixing. IMO it should go in two steps: first diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 1fd3011ea623..7fd4802222b8 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h @@ -229,7 +229,7 @@ ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode) case UFS_UID_44BSD: return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid); case UFS_UID_EFT: - if (inode->ui_u1.oldids.ui_suid == 0xFFFF) + if (inode->ui_u1.oldids.ui_sgid == 0xFFFF) return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); /* Fall through */ default: then introduction of static inline bool solaris_xid_overflow(__fs16 xid) { /* * Solaris indicates the use of 32bit [UG]ID by storing * all-ones bit pattern in the corresponding old (16bit) field */ return (__fs16)~xid == 0; /* all 16 bits set */ } with these two lines turned into if (solaris_xid_overflow(inode->ui_u1.oldids.ui_suid)) and if (solaris_xid_overflow(inode->ui_u1.oldids.ui_sgid)) resp.