Commit 05789ebc authored by Andrew Morton's avatar Andrew Morton Committed by David S. Miller

[PATCH] fix access() POSIX compliance

From: Andreas Gruenbacher <agruen@suse.de>

The fix for permission() that makes it compliant with POSIX.1-2001
apparently was lost.  Here is the patch I sent before.  (The relevant lines
from the standard text are cited in
http://www.ussg.iu.edu/hypermail/linux/kernel/0310.2/0286.html.  The fix
proposed in that posting did not handle directories without execute
permissions correctly.)


Make permission check conform to POSIX.1-2001

The access(2) function does not conform to POSIX.1-2001: For root
and a file with no permissions, access(file, MAY_READ|MAY_EXEC)
returns 0 (it should return -1).
parent 808fde0a
......@@ -322,7 +322,8 @@ ext2_permission(struct inode *inode, int mask, struct nameidata *nd)
check_capabilities:
/* Allowed to override Discretionary Access Control? */
if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
if (!(mask & MAY_EXEC) ||
(inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable(CAP_DAC_OVERRIDE))
return 0;
/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
......
......@@ -327,7 +327,8 @@ ext3_permission(struct inode *inode, int mask, struct nameidata *nd)
check_capabilities:
/* Allowed to override Discretionary Access Control? */
if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
if (!(mask & MAY_EXEC) ||
(inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable(CAP_DAC_OVERRIDE))
return 0;
/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
......
......@@ -191,7 +191,8 @@ int jfs_permission(struct inode * inode, int mask, struct nameidata *nd)
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
*/
if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
if (!(mask & MAY_EXEC) ||
(inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable(CAP_DAC_OVERRIDE))
return 0;
......
......@@ -190,7 +190,8 @@ int vfs_permission(struct inode * inode, int mask)
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
*/
if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
if (!(mask & MAY_EXEC) ||
(inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable(CAP_DAC_OVERRIDE))
return 0;
......
......@@ -3707,7 +3707,8 @@ xfs_iaccess(
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
*/
if ((orgmode & (S_IRUSR|S_IWUSR)) || (inode->i_mode & S_IXUGO))
if (!(orgmode & S_IXUSR) || (inode->i_mode & S_IXUGO) ||
(ip->i_d.di_mode & S_IFMT) == S_IFDIR)
if (capable_cred(cr, CAP_DAC_OVERRIDE))
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment