lkml.org 
[lkml]   [2003]   [Dec]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: chmod -x problem
    From
    Date
    Hello,

    after checking POSIX 1003.1e draft 17 more thoroughly, it turned out
    that we have the following situation:

    Draft 17 mentions the CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,
    CAP_DAC_WRITE, and CAP_DAC_EXECUTE capabilities (among others). In
    Appendix B (pp.319) it says that ``the group also considered a single
    CAP_DAC_OVERRIDE capability, but this granularity was considered
    insufficient'' for reasons explained there. The group decided to split
    CAP_DAC_OVERRIDE into CAP_DAC_READ_SEARCH, CAP_DAC_WRITE, and
    CAP_DAC_EXECUTE. The deprecated CAP_DAC_OVERRIDE capability is still
    mentioned in several places in the draft 17 text, but not in the table
    that defines the base set of required capabilities. So it appears that
    Andrew Morgan based the Linux Capabilities implementation on an earlier
    draft.

    Replacing CAP_DAC_OVERRIDE with the split capabilities does not seem a
    reasonable thing to do to me at this point. So I believe that the
    attached patch is a sufficient fix for the POSIX non-compliance bug
    (thread
    http://marc.theaimsgroup.com/?l=linux-kernel&m=106631710402696&w=2).

    The previous version of the fix for this problem that was posted to LKML
    was not granting execute access to directories that had no execute bits
    set. This was causing the problems observed. Checking for execute bits
    makes sense for regular files, because it prevents privileged users from
    trying to execute random files. The operation of traversing a directory
    is different from executing an arbitrary file, because it always has
    ``reasonable'' semantics.

    We had the equivalent of the attached patch included for about a month
    now, so IMO the patch is safe to apply.


    Cheers,
    --
    Andreas Gruenbacher <agruen@suse.de>
    SUSE Labs, SUSE LINUX AG
    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).

    Index: linux-2.6.0+fix/fs/jfs/acl.c
    ===================================================================
    --- linux-2.6.0+fix.orig/fs/jfs/acl.c 2003-12-18 03:58:07.000000000 +0100
    +++ linux-2.6.0+fix/fs/jfs/acl.c 2003-12-27 02:01:56.000000000 +0100
    @@ -191,7 +191,8 @@ check_capabilities:
    * 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;

    Index: linux-2.6.0+fix/fs/xfs/xfs_inode.c
    ===================================================================
    --- linux-2.6.0+fix.orig/fs/xfs/xfs_inode.c 2003-12-18 03:59:45.000000000 +0100
    +++ linux-2.6.0+fix/fs/xfs/xfs_inode.c 2003-12-27 02:05:00.000000000 +0100
    @@ -3722,7 +3722,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;

    Index: linux-2.6.0+fix/fs/ext2/acl.c
    ===================================================================
    --- linux-2.6.0+fix.orig/fs/ext2/acl.c 2003-12-18 03:59:18.000000000 +0100
    +++ linux-2.6.0+fix/fs/ext2/acl.c 2003-12-27 02:05:46.000000000 +0100
    @@ -322,7 +322,8 @@ check_groups:

    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) */
    Index: linux-2.6.0+fix/fs/ext3/acl.c
    ===================================================================
    --- linux-2.6.0+fix.orig/fs/ext3/acl.c 2003-12-18 03:58:39.000000000 +0100
    +++ linux-2.6.0+fix/fs/ext3/acl.c 2003-12-27 02:07:02.000000000 +0100
    @@ -327,7 +327,8 @@ check_groups:

    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) */
    Index: linux-2.6.0+fix/fs/namei.c
    ===================================================================
    --- linux-2.6.0+fix.orig/fs/namei.c 2003-12-18 03:58:40.000000000 +0100
    +++ linux-2.6.0+fix/fs/namei.c 2003-12-27 01:58:23.000000000 +0100
    @@ -190,7 +190,8 @@ int vfs_permission(struct inode * inode,
    * 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;
    \
     
     \ /
      Last update: 2005-03-22 13:59    [W:0.026 / U:0.060 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site