From ecc052ba4efd2ee81fac2a35047bbd34a0344aca Mon Sep 17 00:00:00 2001 From: Andrey Markovytch Date: Mon, 8 Jun 2015 11:29:36 +0300 Subject: platform: msm: add Per-File-Tagger (PFT) driver Integrated from msm-3.14. Additional fixes were made to compile with the new kernel and various new warnings and checkpatch issues were fixed Change-Id: I073db1041e41eac9066e37ee099f1da9e4eed6c0 Signed-off-by: Andrey Markovytch [gbroner@codeaurora.org: fixed merge conflict and adapted the LSM security hooks] Signed-off-by: Gilad Broner --- security/security.c | 21 ++++++++++++++ security/selinux/hooks.c | 59 ++++++++++++++++++++++++++++++++++++++- security/selinux/include/objsec.h | 1 + 3 files changed, 80 insertions(+), 1 deletion(-) (limited to 'security') diff --git a/security/security.c b/security/security.c index 46f405ce6b0f..81a555c14a35 100644 --- a/security/security.c +++ b/security/security.c @@ -513,6 +513,14 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode } EXPORT_SYMBOL_GPL(security_inode_create); +int security_inode_post_create(struct inode *dir, struct dentry *dentry, + umode_t mode) +{ + if (unlikely(IS_PRIVATE(dir))) + return 0; + return call_int_hook(inode_post_create, 0, dir, dentry, mode); +} + int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { @@ -844,6 +852,16 @@ int security_file_open(struct file *file, const struct cred *cred) return fsnotify_perm(file, MAY_OPEN); } +int security_file_close(struct file *file) +{ + return call_int_hook(file_close, 0, file); +} + +bool security_allow_merge_bio(struct bio *bio1, struct bio *bio2) +{ + return call_int_hook(allow_merge_bio, 1, bio1, bio2); +} + int security_task_create(unsigned long clone_flags) { return call_int_hook(task_create, 0, clone_flags); @@ -1614,6 +1632,7 @@ struct security_hook_heads security_hook_heads = { .inode_init_security = LIST_HEAD_INIT(security_hook_heads.inode_init_security), .inode_create = LIST_HEAD_INIT(security_hook_heads.inode_create), + .inode_post_create = LIST_HEAD_INIT(security_hook_heads.inode_post_create), .inode_link = LIST_HEAD_INIT(security_hook_heads.inode_link), .inode_unlink = LIST_HEAD_INIT(security_hook_heads.inode_unlink), .inode_symlink = @@ -1673,6 +1692,8 @@ struct security_hook_heads security_hook_heads = { LIST_HEAD_INIT(security_hook_heads.file_send_sigiotask), .file_receive = LIST_HEAD_INIT(security_hook_heads.file_receive), .file_open = LIST_HEAD_INIT(security_hook_heads.file_open), + .file_close = LIST_HEAD_INIT(security_hook_heads.file_close), + .allow_merge_bio = LIST_HEAD_INIT(security_hook_heads.allow_merge_bio), .task_create = LIST_HEAD_INIT(security_hook_heads.task_create), .task_free = LIST_HEAD_INIT(security_hook_heads.task_free), .cred_alloc_blank = diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7c22a15c7e4b..a00bb5f9fcde 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -83,6 +83,7 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" @@ -1777,9 +1778,15 @@ static int may_create(struct inode *dir, if (rc) return rc; - return avc_has_perm(newsid, sbsec->sid, + rc = avc_has_perm(newsid, sbsec->sid, SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, &ad); + if (rc) + return rc; + + rc = pft_inode_mknod(dir, dentry, 0, 0); + + return rc; } /* Check whether a task can create a key. */ @@ -1836,6 +1843,12 @@ static int may_link(struct inode *dir, } rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad); + if (rc) + return rc; + + if (kind == MAY_UNLINK) + rc = pft_inode_unlink(dir, dentry); + return rc; } @@ -2806,9 +2819,21 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode) { + int ret; + + ret = pft_inode_create(dir, dentry, mode); + if (ret < 0) + return ret; + return may_create(dir, dentry, SECCLASS_FILE); } +static int selinux_inode_post_create(struct inode *dir, struct dentry *dentry, + umode_t mode) +{ + return pft_inode_post_create(dir, dentry, mode); +} + static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { return may_link(dir, old_dentry, MAY_LINK); @@ -2842,6 +2867,12 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, struct inode *new_inode, struct dentry *new_dentry) { + int rc; + + rc = pft_inode_rename(old_inode, old_dentry, new_inode, new_dentry); + if (rc) + return rc; + return may_rename(old_inode, old_dentry, new_inode, new_dentry); } @@ -2966,6 +2997,9 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) { const struct cred *cred = current_cred(); + if (pft_inode_set_xattr(dentry, name, NULL, 0, 0) < 0) + return -EACCES; + if (!strncmp(name, XATTR_SECURITY_PREFIX, sizeof XATTR_SECURITY_PREFIX - 1)) { if (!strcmp(name, XATTR_NAME_CAPS)) { @@ -3216,11 +3250,16 @@ static int selinux_file_permission(struct file *file, int mask) struct file_security_struct *fsec = file->f_security; struct inode_security_struct *isec = inode->i_security; u32 sid = current_sid(); + int ret; if (!mask) /* No permission to check. Existence test. */ return 0; + ret = pft_file_permission(file, mask); + if (ret < 0) + return ret; + if (sid == fsec->sid && fsec->isid == isec->sid && fsec->pseqno == avc_policy_seqno()) /* No change since file_open check. */ @@ -3511,6 +3550,11 @@ static int selinux_file_open(struct file *file, const struct cred *cred) { struct file_security_struct *fsec; struct inode_security_struct *isec; + int ret; + + ret = pft_file_open(file, cred); + if (ret < 0) + return ret; fsec = file->f_security; isec = file_inode(file)->i_security; @@ -3534,6 +3578,16 @@ static int selinux_file_open(struct file *file, const struct cred *cred) return file_path_has_perm(cred, file, open_file_to_av(file)); } +static int selinux_file_close(struct file *file) +{ + return pft_file_close(file); +} + +static bool selinux_allow_merge_bio(struct bio *bio1, struct bio *bio2) +{ + return pft_allow_merge_bio(bio1, bio2); +} + /* task security operations */ static int selinux_task_create(unsigned long clone_flags) @@ -5905,6 +5959,7 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security), LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security), LSM_HOOK_INIT(inode_create, selinux_inode_create), + LSM_HOOK_INIT(inode_post_create, selinux_inode_post_create), LSM_HOOK_INIT(inode_link, selinux_inode_link), LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink), LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink), @@ -5941,6 +5996,8 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(file_receive, selinux_file_receive), LSM_HOOK_INIT(file_open, selinux_file_open), + LSM_HOOK_INIT(file_close, selinux_file_close), + LSM_HOOK_INIT(allow_merge_bio, selinux_allow_merge_bio), LSM_HOOK_INIT(task_create, selinux_task_create), LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 81fa718d5cb3..a6204e701224 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -47,6 +47,7 @@ struct inode_security_struct { u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ unsigned char initialized; /* initialization flag */ + u32 tag; /* Per-File-Encryption tag */ struct mutex lock; }; -- cgit v1.2.3