Commit a584f710 authored by Eric Sandeen's avatar Eric Sandeen Committed by Nathan Scott

[XFS] Fix root exec access checks on files with acls

SGI Modid: 2.5.x-xfs:slinx:130837a
parent ad1ea17f
...@@ -381,6 +381,38 @@ xfs_acl_allow_set( ...@@ -381,6 +381,38 @@ xfs_acl_allow_set(
return error; return error;
} }
/*
* Look for any effective exec access, to allow CAP_DAC_OVERRIDE for exec.
* Ignore checking for exec in USER_OBJ when there is no mask, because
* in this "minimal acl" case we don't have any actual acls, and we
* won't even be here.
*/
STATIC int
xfs_acl_find_any_exec(
xfs_acl_t *fap)
{
int i;
int masked_aces = 0;
int mask = 0;
for (i = 0; i < fap->acl_cnt; i++) {
if (fap->acl_entry[i].ae_perm & ACL_EXECUTE) {
if (fap->acl_entry[i].ae_tag & (ACL_USER_OBJ|ACL_OTHER))
return 1;
if (fap->acl_entry[i].ae_tag == ACL_MASK)
mask = fap->acl_entry[i].ae_perm;
else
masked_aces |= fap->acl_entry[i].ae_perm;
if ((mask & masked_aces) & ACL_EXECUTE)
return 1;
}
}
return 0;
}
/* /*
* The access control process to determine the access permission: * The access control process to determine the access permission:
* if uid == file owner id, use the file owner bits. * if uid == file owner id, use the file owner bits.
...@@ -390,19 +422,25 @@ xfs_acl_allow_set( ...@@ -390,19 +422,25 @@ xfs_acl_allow_set(
* until all acl entries are exhausted. The final permission produced * until all acl entries are exhausted. The final permission produced
* by matching acl entry or entries needs to be & with group permission. * by matching acl entry or entries needs to be & with group permission.
* if not owner, owning group, or matching entry in ACL, use file * if not owner, owning group, or matching entry in ACL, use file
* other bits. * other bits. Don't allow CAP_DAC_OVERRIDE on exec access unless
* there is some effective exec access somewhere.
*/ */
STATIC int STATIC int
xfs_acl_capability_check( xfs_acl_capability_check(
mode_t mode, mode_t mode,
cred_t *cr) cred_t *cr,
xfs_acl_t *fap)
{ {
if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH)) if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH))
return EACCES; return EACCES;
if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE))
return EACCES; return EACCES;
if ((mode & ACL_EXECUTE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) if ((mode & ACL_EXECUTE) &&
(!capable_cred(cr, CAP_DAC_OVERRIDE) ||
!xfs_acl_find_any_exec(fap))) {
return EACCES; return EACCES;
}
return 0; return 0;
} }
...@@ -507,7 +545,8 @@ xfs_acl_access( ...@@ -507,7 +545,8 @@ xfs_acl_access(
case 0: case 0:
break; break;
} }
return xfs_acl_capability_check(md, cr);
return xfs_acl_capability_check(md, cr, fap);
} }
/* /*
......
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