From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: [PATCH] move read-only and immutable checks into permission() Date: Thu, 13 Jan 2005 17:47:09 +0100 Message-ID: <20050113164709.GA24196@lst.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: linux-fsdevel@vger.kernel.org Return-path: Received: from verein.lst.de ([213.95.11.210]:13185 "EHLO mail.lst.de") by vger.kernel.org with ESMTP id S261231AbVAMQrP (ORCPT ); Thu, 13 Jan 2005 11:47:15 -0500 To: akpm@osdl.org, viro@parcelfarce.linux.theplanet.co.uk Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org Currently it's up to the filesystem ->permission method to check whether the filesystem is readonly or the file marked immutable. But this is really a VFS decision, and the distintion becomes more important when moving to per-mountpoint read only flags. For most filesystems that have been using generic_permission this is not change in behaviour. For those that we're missing the check (cifs without CIFS_MOUNT_NO_PERM and coda [1]) this is a bugfix. Both reiserfs and xfs have this check still in their ->permission routine because they call it from other places aswell. I'll try switching them over to generic_permission and will take care of this one. [1] coda_ioctl_permission always returns 0, aka always grants access, which looks more than fishy to me. --- 1.116/fs/namei.c 2005-01-05 03:48:11 +01:00 +++ edited/fs/namei.c 2005-01-12 19:41:49 +01:00 @@ -169,21 +169,6 @@ { umode_t mode = inode->i_mode; - if (mask & MAY_WRITE) { - /* - * Nobody gets write access to a read-only fs. - */ - if (IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - - /* - * Nobody gets write access to an immutable file. - */ - if (IS_IMMUTABLE(inode)) - return -EACCES; - } - if (current->fsuid == inode->i_uid) mode >>= 6; else { @@ -225,14 +210,30 @@ return -EACCES; } -int permission(struct inode * inode,int mask, struct nameidata *nd) +int permission(struct inode *inode, int mask, struct nameidata *nd) { - int retval; - int submask; + int retval, submask; + + if (mask & MAY_WRITE) { + umode_t mode = inode->i_mode; + + /* + * Nobody gets write access to a read-only fs. + */ + if (IS_RDONLY(inode) && + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) + return -EROFS; + + /* + * Nobody gets write access to an immutable file. + */ + if (IS_IMMUTABLE(inode)) + return -EACCES; + } + /* Ordinary permission routines do not understand MAY_APPEND. */ submask = mask & ~MAY_APPEND; - if (inode->i_op && inode->i_op->permission) retval = inode->i_op->permission(inode, submask, nd); else --- 1.86/fs/nfs/dir.c 2005-01-04 01:00:00 +01:00 +++ edited/fs/nfs/dir.c 2005-01-12 19:55:30 +01:00 @@ -1498,29 +1498,11 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) { struct rpc_cred *cred; - int mode = inode->i_mode; int res; if (mask == 0) return 0; - if (mask & MAY_WRITE) { - /* - * - * Nobody gets write access to a read-only fs. - * - */ - if (IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - /* - * - * Nobody gets write access to an immutable file. - * - */ - if (IS_IMMUTABLE(inode)) - return -EACCES; - } /* Are we checking permissions on anything other than lookup/execute? */ if ((mask & MAY_EXEC) == 0) { /* We only need to check permissions on file open() and access() */