Reintroduce revalidation. Index: b/security/apparmor/lsm.c =================================================================== --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -421,6 +421,55 @@ static int apparmor_inode_removexattr(st MAY_WRITE); } +static int apparmor_file_permission(struct file *file, int mask) +{ + struct aa_profile *profile; + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + int error = 0; + + if (!file_profile) + goto out; + + /* + * If this file was opened under a different profile, we + * revalidate the access against the current profile. + */ + profile = aa_get_profile(current); + if (profile && file_profile != profile) { + struct dentry *dentry = file->f_dentry; + struct vfsmount *mnt = file->f_vfsmnt; + + /* + * FIXME: We should remember which profiles we revalidated + * against. + */ + mask &= (MAY_READ | MAY_WRITE | MAY_EXEC); + error = aa_permission(dentry->d_inode, dentry, mnt, mask, 1); + } + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_file_alloc_security(struct file *file) +{ + struct aa_profile *profile; + + profile = aa_get_profile(current); + if (profile) + file->f_security = profile; + + return 0; +} + +static void apparmor_file_free_security(struct file *file) +{ + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + + aa_put_profile(file_profile); +} + static inline int aa_mmap(struct file *file, unsigned long prot, unsigned long flags) { @@ -644,6 +693,9 @@ struct security_operations apparmor_ops .inode_getxattr = apparmor_inode_getxattr, .inode_listxattr = apparmor_inode_listxattr, .inode_removexattr = apparmor_inode_removexattr, + .file_permission = apparmor_file_permission, + .file_alloc_security = apparmor_file_alloc_security, + .file_free_security = apparmor_file_free_security, .file_mmap = apparmor_file_mmap, .file_mprotect = apparmor_file_mprotect,