Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157288
b: refs/heads/master
c: 5909cca
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Sep 8, 2009
1 parent 17e7a72 commit c4df03b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cb9179ead0aa0e3b7b4087cdba59baf16bbeef6d
refs/heads/master: 5909ccaa300a4a834ffa275327af4df0b9cb5295
62 changes: 35 additions & 27 deletions trunk/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,10 @@ void putname(const char *name)
EXPORT_SYMBOL(putname);
#endif


/**
* generic_permission - check for access rights on a Posix-like filesystem
* @inode: inode to check access rights for
* @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
* @check_acl: optional callback to check for Posix ACLs
*
* Used to check for read/write/execute permissions on a file.
* We use "fsuid" for this, letting us set arbitrary permissions
* for filesystem access without changing the "normal" uids which
* are used for other things..
/*
* This does basic POSIX ACL permission checking
*/
int generic_permission(struct inode *inode, int mask,
static int acl_permission_check(struct inode *inode, int mask,
int (*check_acl)(struct inode *inode, int mask))
{
umode_t mode = inode->i_mode;
Expand All @@ -193,9 +184,7 @@ int generic_permission(struct inode *inode, int mask,
else {
if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
int error = check_acl(inode, mask);
if (error == -EACCES)
goto check_capabilities;
else if (error != -EAGAIN)
if (error != -EAGAIN)
return error;
}

Expand All @@ -208,8 +197,32 @@ int generic_permission(struct inode *inode, int mask,
*/
if ((mask & ~mode) == 0)
return 0;
return -EACCES;
}

/**
* generic_permission - check for access rights on a Posix-like filesystem
* @inode: inode to check access rights for
* @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
* @check_acl: optional callback to check for Posix ACLs
*
* Used to check for read/write/execute permissions on a file.
* We use "fsuid" for this, letting us set arbitrary permissions
* for filesystem access without changing the "normal" uids which
* are used for other things..
*/
int generic_permission(struct inode *inode, int mask,
int (*check_acl)(struct inode *inode, int mask))
{
int ret;

/*
* Do the basic POSIX ACL permission checks.
*/
ret = acl_permission_check(inode, mask, check_acl);
if (ret != -EACCES)
return ret;

check_capabilities:
/*
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
Expand Down Expand Up @@ -262,7 +275,7 @@ int inode_permission(struct inode *inode, int mask)
if (inode->i_op->permission)
retval = inode->i_op->permission(inode, mask);
else
retval = generic_permission(inode, mask, NULL);
retval = generic_permission(inode, mask, inode->i_op->check_acl);

if (retval)
return retval;
Expand Down Expand Up @@ -432,27 +445,22 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name,
*/
static int exec_permission_lite(struct inode *inode)
{
umode_t mode = inode->i_mode;
int ret;

if (inode->i_op->permission) {
int ret = inode->i_op->permission(inode, MAY_EXEC);
ret = inode->i_op->permission(inode, MAY_EXEC);
if (!ret)
goto ok;
return ret;
}

if (current_fsuid() == inode->i_uid)
mode >>= 6;
else if (in_group_p(inode->i_gid))
mode >>= 3;

if (mode & MAY_EXEC)
ret = acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl);
if (!ret)
goto ok;

if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH))
goto ok;

return -EACCES;
return ret;
ok:
return security_inode_permission(inode, MAY_EXEC);
}
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,7 @@ struct inode_operations {
void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int);
int (*check_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
Expand Down

0 comments on commit c4df03b

Please sign in to comment.