int generic_permission(struct inode *inode, int mask, int (*check_acl)(struct inode *inode, int mask))

umode_t mode = inode->i_mode;

if (current->fsuid == inode->i_uid) mode >>= 6;

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) return error;

Checking for the fsuid is simple. If the fsuid agrees with the UID of the file, then the mode value needs to be shifted by six positions such that the bits for ''owner'' are now the least significant ones.

Checking the fsgid is slightly more involved because all groups to which the process belongs need to be considered, so this is delegated to the (not discussed) helper function in_group_p. Should this be successful, the mode value needs to be shifted by three places such that the mode bits for ''group'' are now the least significant ones. Note that the kernel may also need to perform an ACL check, which is described below.

If both UID and GID checks fail, then no shifting of the mode bits is performed, and the bits for ''other'' remain the least significant ones.

The discretionary access control (DAC) check is then performed on the chosen permission bits as follows: fs/namei.c if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) return 0;

If the required permissions mask is allowed by the mode permission bits, then a zero is returned. This signals that the operation is allowed.

Failure of the DAC check does not yet mean that the desired operation is forbidden since capabilities might still allow it. The kernel tests this as follows:

Continue reading here: Fsnameic

Was this article helpful?

0 0