Commit 83da53c5 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Paul Moore

selinux: Add accessor functions for inode->i_security

Add functions dentry_security and inode_security for accessing
inode->i_security.  These functions initially don't do much, but they
will later be used to revalidate the security labels when necessary.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Acked-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
parent d6335d77
...@@ -242,6 +242,24 @@ static int inode_alloc_security(struct inode *inode) ...@@ -242,6 +242,24 @@ static int inode_alloc_security(struct inode *inode)
return 0; return 0;
} }
/*
* Get the security label of an inode.
*/
static struct inode_security_struct *inode_security(struct inode *inode)
{
return inode->i_security;
}
/*
* Get the security label of a dentry's backing inode.
*/
static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
{
struct inode *inode = d_backing_inode(dentry);
return inode->i_security;
}
static void inode_free_rcu(struct rcu_head *head) static void inode_free_rcu(struct rcu_head *head)
{ {
struct inode_security_struct *isec; struct inode_security_struct *isec;
...@@ -565,8 +583,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb, ...@@ -565,8 +583,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT;
} }
if (sbsec->flags & ROOTCONTEXT_MNT) { if (sbsec->flags & ROOTCONTEXT_MNT) {
struct inode *root = d_backing_inode(sbsec->sb->s_root); struct dentry *root = sbsec->sb->s_root;
struct inode_security_struct *isec = root->i_security; struct inode_security_struct *isec = backing_inode_security(root);
rc = security_sid_to_context(isec->sid, &context, &len); rc = security_sid_to_context(isec->sid, &context, &len);
if (rc) if (rc)
...@@ -621,8 +639,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -621,8 +639,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
int rc = 0, i; int rc = 0, i;
struct superblock_security_struct *sbsec = sb->s_security; struct superblock_security_struct *sbsec = sb->s_security;
const char *name = sb->s_type->name; const char *name = sb->s_type->name;
struct inode *inode = d_backing_inode(sbsec->sb->s_root); struct dentry *root = sbsec->sb->s_root;
struct inode_security_struct *root_isec = inode->i_security; struct inode_security_struct *root_isec = backing_inode_security(root);
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
u32 defcontext_sid = 0; u32 defcontext_sid = 0;
char **mount_options = opts->mnt_opts; char **mount_options = opts->mnt_opts;
...@@ -852,8 +870,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb, ...@@ -852,8 +870,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb,
if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
goto mismatch; goto mismatch;
if (oldflags & ROOTCONTEXT_MNT) { if (oldflags & ROOTCONTEXT_MNT) {
struct inode_security_struct *oldroot = d_backing_inode(oldsb->s_root)->i_security; struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
struct inode_security_struct *newroot = d_backing_inode(newsb->s_root)->i_security; struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
if (oldroot->sid != newroot->sid) if (oldroot->sid != newroot->sid)
goto mismatch; goto mismatch;
} }
...@@ -903,17 +921,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, ...@@ -903,17 +921,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
if (!set_fscontext) if (!set_fscontext)
newsbsec->sid = sid; newsbsec->sid = sid;
if (!set_rootcontext) { if (!set_rootcontext) {
struct inode *newinode = d_backing_inode(newsb->s_root); struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
struct inode_security_struct *newisec = newinode->i_security;
newisec->sid = sid; newisec->sid = sid;
} }
newsbsec->mntpoint_sid = sid; newsbsec->mntpoint_sid = sid;
} }
if (set_rootcontext) { if (set_rootcontext) {
const struct inode *oldinode = d_backing_inode(oldsb->s_root); const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
const struct inode_security_struct *oldisec = oldinode->i_security; struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
struct inode *newinode = d_backing_inode(newsb->s_root);
struct inode_security_struct *newisec = newinode->i_security;
newisec->sid = oldisec->sid; newisec->sid = oldisec->sid;
} }
...@@ -1712,13 +1727,13 @@ static int file_has_perm(const struct cred *cred, ...@@ -1712,13 +1727,13 @@ static int file_has_perm(const struct cred *cred,
/* /*
* Determine the label for an inode that might be unioned. * Determine the label for an inode that might be unioned.
*/ */
static int selinux_determine_inode_label(const struct inode *dir, static int selinux_determine_inode_label(struct inode *dir,
const struct qstr *name, const struct qstr *name,
u16 tclass, u16 tclass,
u32 *_new_isid) u32 *_new_isid)
{ {
const struct superblock_security_struct *sbsec = dir->i_sb->s_security; const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
const struct inode_security_struct *dsec = dir->i_security; const struct inode_security_struct *dsec = inode_security(dir);
const struct task_security_struct *tsec = current_security(); const struct task_security_struct *tsec = current_security();
if ((sbsec->flags & SE_SBINITIALIZED) && if ((sbsec->flags & SE_SBINITIALIZED) &&
...@@ -1747,7 +1762,7 @@ static int may_create(struct inode *dir, ...@@ -1747,7 +1762,7 @@ static int may_create(struct inode *dir,
struct common_audit_data ad; struct common_audit_data ad;
int rc; int rc;
dsec = dir->i_security; dsec = inode_security(dir);
sbsec = dir->i_sb->s_security; sbsec = dir->i_sb->s_security;
sid = tsec->sid; sid = tsec->sid;
...@@ -1800,8 +1815,8 @@ static int may_link(struct inode *dir, ...@@ -1800,8 +1815,8 @@ static int may_link(struct inode *dir,
u32 av; u32 av;
int rc; int rc;
dsec = dir->i_security; dsec = inode_security(dir);
isec = d_backing_inode(dentry)->i_security; isec = backing_inode_security(dentry);
ad.type = LSM_AUDIT_DATA_DENTRY; ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry; ad.u.dentry = dentry;
...@@ -1844,10 +1859,10 @@ static inline int may_rename(struct inode *old_dir, ...@@ -1844,10 +1859,10 @@ static inline int may_rename(struct inode *old_dir,
int old_is_dir, new_is_dir; int old_is_dir, new_is_dir;
int rc; int rc;
old_dsec = old_dir->i_security; old_dsec = inode_security(old_dir);
old_isec = d_backing_inode(old_dentry)->i_security; old_isec = backing_inode_security(old_dentry);
old_is_dir = d_is_dir(old_dentry); old_is_dir = d_is_dir(old_dentry);
new_dsec = new_dir->i_security; new_dsec = inode_security(new_dir);
ad.type = LSM_AUDIT_DATA_DENTRY; ad.type = LSM_AUDIT_DATA_DENTRY;
...@@ -1875,7 +1890,7 @@ static inline int may_rename(struct inode *old_dir, ...@@ -1875,7 +1890,7 @@ static inline int may_rename(struct inode *old_dir,
if (rc) if (rc)
return rc; return rc;
if (d_is_positive(new_dentry)) { if (d_is_positive(new_dentry)) {
new_isec = d_backing_inode(new_dentry)->i_security; new_isec = backing_inode_security(new_dentry);
new_is_dir = d_is_dir(new_dentry); new_is_dir = d_is_dir(new_dentry);
rc = avc_has_perm(sid, new_isec->sid, rc = avc_has_perm(sid, new_isec->sid,
new_isec->sclass, new_isec->sclass,
...@@ -2011,8 +2026,8 @@ static int selinux_binder_transfer_file(struct task_struct *from, ...@@ -2011,8 +2026,8 @@ static int selinux_binder_transfer_file(struct task_struct *from,
{ {
u32 sid = task_sid(to); u32 sid = task_sid(to);
struct file_security_struct *fsec = file->f_security; struct file_security_struct *fsec = file->f_security;
struct inode *inode = d_backing_inode(file->f_path.dentry); struct dentry *dentry = file->f_path.dentry;
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = backing_inode_security(dentry);
struct common_audit_data ad; struct common_audit_data ad;
int rc; int rc;
...@@ -2028,7 +2043,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, ...@@ -2028,7 +2043,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
return rc; return rc;
} }
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
return 0; return 0;
return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
...@@ -2217,7 +2232,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) ...@@ -2217,7 +2232,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
old_tsec = current_security(); old_tsec = current_security();
new_tsec = bprm->cred->security; new_tsec = bprm->cred->security;
isec = inode->i_security; isec = inode_security(inode);
/* Default to the current task SID. */ /* Default to the current task SID. */
new_tsec->sid = old_tsec->sid; new_tsec->sid = old_tsec->sid;
...@@ -2639,7 +2654,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data) ...@@ -2639,7 +2654,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
break; break;
case ROOTCONTEXT_MNT: { case ROOTCONTEXT_MNT: {
struct inode_security_struct *root_isec; struct inode_security_struct *root_isec;
root_isec = d_backing_inode(sb->s_root)->i_security; root_isec = backing_inode_security(sb->s_root);
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
goto out_bad_option; goto out_bad_option;
...@@ -2856,7 +2871,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, ...@@ -2856,7 +2871,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
ad.type = LSM_AUDIT_DATA_DENTRY; ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry; ad.u.dentry = dentry;
sid = cred_sid(cred); sid = cred_sid(cred);
isec = inode->i_security; isec = inode_security(inode);
return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad, return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad,
rcu ? MAY_NOT_BLOCK : 0); rcu ? MAY_NOT_BLOCK : 0);
...@@ -2908,7 +2923,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) ...@@ -2908,7 +2923,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
perms = file_mask_to_av(inode->i_mode, mask); perms = file_mask_to_av(inode->i_mode, mask);
sid = cred_sid(cred); sid = cred_sid(cred);
isec = inode->i_security; isec = inode_security(inode);
rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
audited = avc_audit_required(perms, &avd, rc, audited = avc_audit_required(perms, &avd, rc,
...@@ -2978,7 +2993,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, ...@@ -2978,7 +2993,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = backing_inode_security(dentry);
struct superblock_security_struct *sbsec; struct superblock_security_struct *sbsec;
struct common_audit_data ad; struct common_audit_data ad;
u32 newsid, sid = current_sid(); u32 newsid, sid = current_sid();
...@@ -3055,7 +3070,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, ...@@ -3055,7 +3070,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
int flags) int flags)
{ {
struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = backing_inode_security(dentry);
u32 newsid; u32 newsid;
int rc; int rc;
...@@ -3113,7 +3128,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void ...@@ -3113,7 +3128,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
u32 size; u32 size;
int error; int error;
char *context = NULL; char *context = NULL;
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
if (strcmp(name, XATTR_SELINUX_SUFFIX)) if (strcmp(name, XATTR_SELINUX_SUFFIX))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -3152,7 +3167,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void ...@@ -3152,7 +3167,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
static int selinux_inode_setsecurity(struct inode *inode, const char *name, static int selinux_inode_setsecurity(struct inode *inode, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
u32 newsid; u32 newsid;
int rc; int rc;
...@@ -3182,7 +3197,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t ...@@ -3182,7 +3197,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
static void selinux_inode_getsecid(struct inode *inode, u32 *secid) static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
{ {
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
*secid = isec->sid; *secid = isec->sid;
} }
...@@ -3205,7 +3220,7 @@ static int selinux_file_permission(struct file *file, int mask) ...@@ -3205,7 +3220,7 @@ static int selinux_file_permission(struct file *file, int mask)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct file_security_struct *fsec = file->f_security; struct file_security_struct *fsec = file->f_security;
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
u32 sid = current_sid(); u32 sid = current_sid();
if (!mask) if (!mask)
...@@ -3240,7 +3255,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, ...@@ -3240,7 +3255,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
struct common_audit_data ad; struct common_audit_data ad;
struct file_security_struct *fsec = file->f_security; struct file_security_struct *fsec = file->f_security;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
struct lsm_ioctlop_audit ioctl; struct lsm_ioctlop_audit ioctl;
u32 ssid = cred_sid(cred); u32 ssid = cred_sid(cred);
int rc; int rc;
...@@ -3504,7 +3519,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) ...@@ -3504,7 +3519,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
struct inode_security_struct *isec; struct inode_security_struct *isec;
fsec = file->f_security; fsec = file->f_security;
isec = file_inode(file)->i_security; isec = inode_security(file_inode(file));
/* /*
* Save inode label and policy sequence number * Save inode label and policy sequence number
* at open-time so that selinux_file_permission * at open-time so that selinux_file_permission
...@@ -3622,7 +3637,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) ...@@ -3622,7 +3637,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid)
*/ */
static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
{ {
struct inode_security_struct *isec = inode->i_security; struct inode_security_struct *isec = inode_security(inode);
struct task_security_struct *tsec = new->security; struct task_security_struct *tsec = new->security;
u32 sid = current_sid(); u32 sid = current_sid();
int ret; int ret;
...@@ -4063,7 +4078,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, ...@@ -4063,7 +4078,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
int type, int protocol, int kern) int type, int protocol, int kern)
{ {
const struct task_security_struct *tsec = current_security(); const struct task_security_struct *tsec = current_security();
struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; struct inode_security_struct *isec = inode_security(SOCK_INODE(sock));
struct sk_security_struct *sksec; struct sk_security_struct *sksec;
int err = 0; int err = 0;
...@@ -4263,9 +4278,9 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) ...@@ -4263,9 +4278,9 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
if (err) if (err)
return err; return err;
newisec = SOCK_INODE(newsock)->i_security; newisec = inode_security(SOCK_INODE(newsock));
isec = SOCK_INODE(sock)->i_security; isec = inode_security(SOCK_INODE(sock));
newisec->sclass = isec->sclass; newisec->sclass = isec->sclass;
newisec->sid = isec->sid; newisec->sid = isec->sid;
newisec->initialized = 1; newisec->initialized = 1;
...@@ -4603,7 +4618,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) ...@@ -4603,7 +4618,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
static void selinux_sock_graft(struct sock *sk, struct socket *parent) static void selinux_sock_graft(struct sock *sk, struct socket *parent)
{ {
struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; struct inode_security_struct *isec = inode_security(SOCK_INODE(parent));
struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *sksec = sk->sk_security;
if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
......
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