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) ...@@ -322,7 +322,8 @@ ext2_permission(struct inode *inode, int mask, struct nameidata *nd)
check_capabilities: check_capabilities:
/* Allowed to override Discretionary Access Control? */ /* 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)) if (capable(CAP_DAC_OVERRIDE))
return 0; return 0;
/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */ /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
......
...@@ -327,7 +327,8 @@ ext3_permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -327,7 +327,8 @@ ext3_permission(struct inode *inode, int mask, struct nameidata *nd)
check_capabilities: check_capabilities:
/* Allowed to override Discretionary Access Control? */ /* 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)) if (capable(CAP_DAC_OVERRIDE))
return 0; return 0;
/* Read and search granted if capable(CAP_DAC_READ_SEARCH) */ /* 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) ...@@ -191,7 +191,8 @@ int jfs_permission(struct inode * inode, int mask, struct nameidata *nd)
* Read/write DACs are always overridable. * Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set. * 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)) if (capable(CAP_DAC_OVERRIDE))
return 0; return 0;
......
...@@ -190,7 +190,8 @@ int vfs_permission(struct inode * inode, int mask) ...@@ -190,7 +190,8 @@ int vfs_permission(struct inode * inode, int mask)
* Read/write DACs are always overridable. * Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set. * 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)) if (capable(CAP_DAC_OVERRIDE))
return 0; return 0;
......
...@@ -3707,7 +3707,8 @@ xfs_iaccess( ...@@ -3707,7 +3707,8 @@ xfs_iaccess(
* Read/write DACs are always overridable. * Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set. * 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)) if (capable_cred(cr, CAP_DAC_OVERRIDE))
return 0; 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