Commit 37babe4e authored by James Morris's avatar James Morris

Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/selinux into next

parents 3cb92fe4 76319946
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/gfs2_ondisk.h> #include <linux/gfs2_ondisk.h>
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
#include <linux/security.h>
#include "gfs2.h" #include "gfs2.h"
#include "incore.h" #include "incore.h"
...@@ -262,6 +263,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) ...@@ -262,6 +263,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
if (ip) { if (ip) {
set_bit(GIF_INVALID, &ip->i_flags); set_bit(GIF_INVALID, &ip->i_flags);
forget_all_cached_acls(&ip->i_inode); forget_all_cached_acls(&ip->i_inode);
security_inode_invalidate_secctx(&ip->i_inode);
gfs2_dir_hash_inval(ip); gfs2_dir_hash_inval(ip);
} }
} }
......
...@@ -137,7 +137,7 @@ extern void __audit_getname(struct filename *name); ...@@ -137,7 +137,7 @@ extern void __audit_getname(struct filename *name);
extern void __audit_inode(struct filename *name, const struct dentry *dentry, extern void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags); unsigned int flags);
extern void __audit_file(const struct file *); extern void __audit_file(const struct file *);
extern void __audit_inode_child(const struct inode *parent, extern void __audit_inode_child(struct inode *parent,
const struct dentry *dentry, const struct dentry *dentry,
const unsigned char type); const unsigned char type);
extern void __audit_seccomp(unsigned long syscall, long signr, int code); extern void __audit_seccomp(unsigned long syscall, long signr, int code);
...@@ -202,7 +202,7 @@ static inline void audit_inode_parent_hidden(struct filename *name, ...@@ -202,7 +202,7 @@ static inline void audit_inode_parent_hidden(struct filename *name,
__audit_inode(name, dentry, __audit_inode(name, dentry,
AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN); AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN);
} }
static inline void audit_inode_child(const struct inode *parent, static inline void audit_inode_child(struct inode *parent,
const struct dentry *dentry, const struct dentry *dentry,
const unsigned char type) { const unsigned char type) {
if (unlikely(!audit_dummy_context())) if (unlikely(!audit_dummy_context()))
...@@ -359,7 +359,7 @@ static inline void __audit_inode(struct filename *name, ...@@ -359,7 +359,7 @@ static inline void __audit_inode(struct filename *name,
const struct dentry *dentry, const struct dentry *dentry,
unsigned int flags) unsigned int flags)
{ } { }
static inline void __audit_inode_child(const struct inode *parent, static inline void __audit_inode_child(struct inode *parent,
const struct dentry *dentry, const struct dentry *dentry,
const unsigned char type) const unsigned char type)
{ } { }
...@@ -373,7 +373,7 @@ static inline void audit_file(struct file *file) ...@@ -373,7 +373,7 @@ static inline void audit_file(struct file *file)
static inline void audit_inode_parent_hidden(struct filename *name, static inline void audit_inode_parent_hidden(struct filename *name,
const struct dentry *dentry) const struct dentry *dentry)
{ } { }
static inline void audit_inode_child(const struct inode *parent, static inline void audit_inode_child(struct inode *parent,
const struct dentry *dentry, const struct dentry *dentry,
const unsigned char type) const unsigned char type)
{ } { }
......
...@@ -1261,6 +1261,10 @@ ...@@ -1261,6 +1261,10 @@
* audit_rule_init. * audit_rule_init.
* @rule contains the allocated rule * @rule contains the allocated rule
* *
* @inode_invalidate_secctx:
* Notify the security module that it must revalidate the security context
* of an inode.
*
* @inode_notifysecctx: * @inode_notifysecctx:
* Notify the security module of what the security context of an inode * Notify the security module of what the security context of an inode
* should be. Initializes the incore security context managed by the * should be. Initializes the incore security context managed by the
...@@ -1413,14 +1417,14 @@ union security_list_options { ...@@ -1413,14 +1417,14 @@ union security_list_options {
int (*inode_removexattr)(struct dentry *dentry, const char *name); int (*inode_removexattr)(struct dentry *dentry, const char *name);
int (*inode_need_killpriv)(struct dentry *dentry); int (*inode_need_killpriv)(struct dentry *dentry);
int (*inode_killpriv)(struct dentry *dentry); int (*inode_killpriv)(struct dentry *dentry);
int (*inode_getsecurity)(const struct inode *inode, const char *name, int (*inode_getsecurity)(struct inode *inode, const char *name,
void **buffer, bool alloc); void **buffer, bool alloc);
int (*inode_setsecurity)(struct inode *inode, const char *name, int (*inode_setsecurity)(struct inode *inode, const char *name,
const void *value, size_t size, const void *value, size_t size,
int flags); int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, int (*inode_listsecurity)(struct inode *inode, char *buffer,
size_t buffer_size); size_t buffer_size);
void (*inode_getsecid)(const struct inode *inode, u32 *secid); void (*inode_getsecid)(struct inode *inode, u32 *secid);
int (*file_permission)(struct file *file, int mask); int (*file_permission)(struct file *file, int mask);
int (*file_alloc_security)(struct file *file); int (*file_alloc_security)(struct file *file);
...@@ -1516,6 +1520,7 @@ union security_list_options { ...@@ -1516,6 +1520,7 @@ union security_list_options {
int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid); int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid);
void (*release_secctx)(char *secdata, u32 seclen); void (*release_secctx)(char *secdata, u32 seclen);
void (*inode_invalidate_secctx)(struct inode *inode);
int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen); int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen); int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
...@@ -1757,6 +1762,7 @@ struct security_hook_heads { ...@@ -1757,6 +1762,7 @@ struct security_hook_heads {
struct list_head secid_to_secctx; struct list_head secid_to_secctx;
struct list_head secctx_to_secid; struct list_head secctx_to_secid;
struct list_head release_secctx; struct list_head release_secctx;
struct list_head inode_invalidate_secctx;
struct list_head inode_notifysecctx; struct list_head inode_notifysecctx;
struct list_head inode_setsecctx; struct list_head inode_setsecctx;
struct list_head inode_getsecctx; struct list_head inode_getsecctx;
......
...@@ -270,10 +270,10 @@ int security_inode_listxattr(struct dentry *dentry); ...@@ -270,10 +270,10 @@ int security_inode_listxattr(struct dentry *dentry);
int security_inode_removexattr(struct dentry *dentry, const char *name); int security_inode_removexattr(struct dentry *dentry, const char *name);
int security_inode_need_killpriv(struct dentry *dentry); int security_inode_need_killpriv(struct dentry *dentry);
int security_inode_killpriv(struct dentry *dentry); int security_inode_killpriv(struct dentry *dentry);
int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc);
int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
void security_inode_getsecid(const struct inode *inode, u32 *secid); void security_inode_getsecid(struct inode *inode, u32 *secid);
int security_file_permission(struct file *file, int mask); int security_file_permission(struct file *file, int mask);
int security_file_alloc(struct file *file); int security_file_alloc(struct file *file);
void security_file_free(struct file *file); void security_file_free(struct file *file);
...@@ -353,6 +353,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); ...@@ -353,6 +353,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
void security_release_secctx(char *secdata, u32 seclen); void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
...@@ -719,7 +720,7 @@ static inline int security_inode_killpriv(struct dentry *dentry) ...@@ -719,7 +720,7 @@ static inline int security_inode_killpriv(struct dentry *dentry)
return cap_inode_killpriv(dentry); return cap_inode_killpriv(dentry);
} }
static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) static inline int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -734,7 +735,7 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer, ...@@ -734,7 +735,7 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer,
return 0; return 0;
} }
static inline void security_inode_getsecid(const struct inode *inode, u32 *secid) static inline void security_inode_getsecid(struct inode *inode, u32 *secid)
{ {
*secid = 0; *secid = 0;
} }
...@@ -1093,6 +1094,10 @@ static inline void security_release_secctx(char *secdata, u32 seclen) ...@@ -1093,6 +1094,10 @@ static inline void security_release_secctx(char *secdata, u32 seclen)
{ {
} }
static inline void security_inode_invalidate_secctx(struct inode *inode)
{
}
static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -1722,7 +1722,7 @@ static inline int audit_copy_fcaps(struct audit_names *name, ...@@ -1722,7 +1722,7 @@ static inline int audit_copy_fcaps(struct audit_names *name,
/* Copy inode data into an audit_names. */ /* Copy inode data into an audit_names. */
void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
const struct inode *inode) struct inode *inode)
{ {
name->ino = inode->i_ino; name->ino = inode->i_ino;
name->dev = inode->i_sb->s_dev; name->dev = inode->i_sb->s_dev;
......
...@@ -207,7 +207,7 @@ extern u32 audit_ever_enabled; ...@@ -207,7 +207,7 @@ extern u32 audit_ever_enabled;
extern void audit_copy_inode(struct audit_names *name, extern void audit_copy_inode(struct audit_names *name,
const struct dentry *dentry, const struct dentry *dentry,
const struct inode *inode); struct inode *inode);
extern void audit_log_cap(struct audit_buffer *ab, char *prefix, extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
kernel_cap_t *cap); kernel_cap_t *cap);
extern void audit_log_name(struct audit_context *context, extern void audit_log_name(struct audit_context *context,
......
...@@ -1754,7 +1754,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, ...@@ -1754,7 +1754,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags) unsigned int flags)
{ {
struct audit_context *context = current->audit_context; struct audit_context *context = current->audit_context;
const struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
struct audit_names *n; struct audit_names *n;
bool parent = flags & AUDIT_INODE_PARENT; bool parent = flags & AUDIT_INODE_PARENT;
...@@ -1848,12 +1848,12 @@ void __audit_file(const struct file *file) ...@@ -1848,12 +1848,12 @@ void __audit_file(const struct file *file)
* must be hooked prior, in order to capture the target inode during * must be hooked prior, in order to capture the target inode during
* unsuccessful attempts. * unsuccessful attempts.
*/ */
void __audit_inode_child(const struct inode *parent, void __audit_inode_child(struct inode *parent,
const struct dentry *dentry, const struct dentry *dentry,
const unsigned char type) const unsigned char type)
{ {
struct audit_context *context = current->audit_context; struct audit_context *context = current->audit_context;
const struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
const char *dname = dentry->d_name.name; const char *dname = dentry->d_name.name;
struct audit_names *n, *found_parent = NULL, *found_child = NULL; struct audit_names *n, *found_parent = NULL, *found_child = NULL;
......
...@@ -697,7 +697,7 @@ int security_inode_killpriv(struct dentry *dentry) ...@@ -697,7 +697,7 @@ int security_inode_killpriv(struct dentry *dentry)
return call_int_hook(inode_killpriv, 0, dentry); return call_int_hook(inode_killpriv, 0, dentry);
} }
int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
{ {
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -721,7 +721,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer ...@@ -721,7 +721,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
} }
EXPORT_SYMBOL(security_inode_listsecurity); EXPORT_SYMBOL(security_inode_listsecurity);
void security_inode_getsecid(const struct inode *inode, u32 *secid) void security_inode_getsecid(struct inode *inode, u32 *secid)
{ {
call_void_hook(inode_getsecid, inode, secid); call_void_hook(inode_getsecid, inode, secid);
} }
...@@ -1161,6 +1161,12 @@ void security_release_secctx(char *secdata, u32 seclen) ...@@ -1161,6 +1161,12 @@ void security_release_secctx(char *secdata, u32 seclen)
} }
EXPORT_SYMBOL(security_release_secctx); EXPORT_SYMBOL(security_release_secctx);
void security_inode_invalidate_secctx(struct inode *inode)
{
call_void_hook(inode_invalidate_secctx, inode);
}
EXPORT_SYMBOL(security_inode_invalidate_secctx);
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
{ {
return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen);
...@@ -1763,6 +1769,8 @@ struct security_hook_heads security_hook_heads = { ...@@ -1763,6 +1769,8 @@ struct security_hook_heads security_hook_heads = {
LIST_HEAD_INIT(security_hook_heads.secctx_to_secid), LIST_HEAD_INIT(security_hook_heads.secctx_to_secid),
.release_secctx = .release_secctx =
LIST_HEAD_INIT(security_hook_heads.release_secctx), LIST_HEAD_INIT(security_hook_heads.release_secctx),
.inode_invalidate_secctx =
LIST_HEAD_INIT(security_hook_heads.inode_invalidate_secctx),
.inode_notifysecctx = .inode_notifysecctx =
LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx), LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx),
.inode_setsecctx = .inode_setsecctx =
......
This diff is collapsed.
...@@ -21,7 +21,7 @@ struct security_class_mapping secclass_map[] = { ...@@ -21,7 +21,7 @@ struct security_class_mapping secclass_map[] = {
{ "compute_av", "compute_create", "compute_member", { "compute_av", "compute_create", "compute_member",
"check_context", "load_policy", "compute_relabel", "check_context", "load_policy", "compute_relabel",
"compute_user", "setenforce", "setbool", "setsecparam", "compute_user", "setenforce", "setbool", "setsecparam",
"setcheckreqprot", "read_policy", NULL } }, "setcheckreqprot", "read_policy", "validate_trans", NULL } },
{ "process", { "process",
{ "fork", "transition", "sigchld", "sigkill", { "fork", "transition", "sigchld", "sigkill",
"sigstop", "signull", "signal", "ptrace", "getsched", "setsched", "sigstop", "signull", "signal", "ptrace", "getsched", "setsched",
......
...@@ -37,6 +37,12 @@ struct task_security_struct { ...@@ -37,6 +37,12 @@ struct task_security_struct {
u32 sockcreate_sid; /* fscreate SID */ u32 sockcreate_sid; /* fscreate SID */
}; };
enum label_initialized {
LABEL_MISSING, /* not initialized */
LABEL_INITIALIZED, /* inizialized */
LABEL_INVALID /* invalid */
};
struct inode_security_struct { struct inode_security_struct {
struct inode *inode; /* back pointer to inode object */ struct inode *inode; /* back pointer to inode object */
union { union {
......
...@@ -187,6 +187,9 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen, ...@@ -187,6 +187,9 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass); u16 tclass);
int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
int security_bounded_transition(u32 oldsid, u32 newsid); int security_bounded_transition(u32 oldsid, u32 newsid);
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
......
...@@ -116,6 +116,7 @@ enum sel_inos { ...@@ -116,6 +116,7 @@ enum sel_inos {
SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */ SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
SEL_STATUS, /* export current status using mmap() */ SEL_STATUS, /* export current status using mmap() */
SEL_POLICY, /* allow userspace to read the in kernel policy */ SEL_POLICY, /* allow userspace to read the in kernel policy */
SEL_VALIDATE_TRANS, /* compute validatetrans decision */
SEL_INO_NEXT, /* The next inode number to use */ SEL_INO_NEXT, /* The next inode number to use */
}; };
...@@ -653,6 +654,83 @@ static const struct file_operations sel_checkreqprot_ops = { ...@@ -653,6 +654,83 @@ static const struct file_operations sel_checkreqprot_ops = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
static ssize_t sel_write_validatetrans(struct file *file,
const char __user *buf,
size_t count, loff_t *ppos)
{
char *oldcon = NULL, *newcon = NULL, *taskcon = NULL;
char *req = NULL;
u32 osid, nsid, tsid;
u16 tclass;
int rc;
rc = task_has_security(current, SECURITY__VALIDATE_TRANS);
if (rc)
goto out;
rc = -ENOMEM;
if (count >= PAGE_SIZE)
goto out;
/* No partial writes. */
rc = -EINVAL;
if (*ppos != 0)
goto out;
rc = -ENOMEM;
req = kzalloc(count + 1, GFP_KERNEL);
if (!req)
goto out;
rc = -EFAULT;
if (copy_from_user(req, buf, count))
goto out;
rc = -ENOMEM;
oldcon = kzalloc(count + 1, GFP_KERNEL);
if (!oldcon)
goto out;
newcon = kzalloc(count + 1, GFP_KERNEL);
if (!newcon)
goto out;
taskcon = kzalloc(count + 1, GFP_KERNEL);
if (!taskcon)
goto out;
rc = -EINVAL;
if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
goto out;
rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL);
if (rc)
goto out;
rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL);
if (rc)
goto out;
rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL);
if (rc)
goto out;
rc = security_validate_transition_user(osid, nsid, tsid, tclass);
if (!rc)
rc = count;
out:
kfree(req);
kfree(oldcon);
kfree(newcon);
kfree(taskcon);
return rc;
}
static const struct file_operations sel_transition_ops = {
.write = sel_write_validatetrans,
.llseek = generic_file_llseek,
};
/* /*
* Remaining nodes use transaction based IO methods like nfsd/nfsctl.c * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
*/ */
...@@ -1759,6 +1837,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1759,6 +1837,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
[SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO}, [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
S_IWUGO},
/* last one */ {""} /* last one */ {""}
}; };
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
......
...@@ -778,8 +778,8 @@ static int security_validtrans_handle_fail(struct context *ocontext, ...@@ -778,8 +778,8 @@ static int security_validtrans_handle_fail(struct context *ocontext,
return -EPERM; return -EPERM;
} }
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid,
u16 orig_tclass) u16 orig_tclass, bool user)
{ {
struct context *ocontext; struct context *ocontext;
struct context *ncontext; struct context *ncontext;
...@@ -794,11 +794,12 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, ...@@ -794,11 +794,12 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
read_lock(&policy_rwlock); read_lock(&policy_rwlock);
tclass = unmap_class(orig_tclass); if (!user)
tclass = unmap_class(orig_tclass);
else
tclass = orig_tclass;
if (!tclass || tclass > policydb.p_classes.nprim) { if (!tclass || tclass > policydb.p_classes.nprim) {
printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
__func__, tclass);
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
...@@ -832,8 +833,13 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, ...@@ -832,8 +833,13 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
while (constraint) { while (constraint) {
if (!constraint_expr_eval(ocontext, ncontext, tcontext, if (!constraint_expr_eval(ocontext, ncontext, tcontext,
constraint->expr)) { constraint->expr)) {
rc = security_validtrans_handle_fail(ocontext, ncontext, if (user)
tcontext, tclass); rc = -EPERM;
else
rc = security_validtrans_handle_fail(ocontext,
ncontext,
tcontext,
tclass);
goto out; goto out;
} }
constraint = constraint->next; constraint = constraint->next;
...@@ -844,6 +850,20 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, ...@@ -844,6 +850,20 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
return rc; return rc;
} }
int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass)
{
return security_compute_validatetrans(oldsid, newsid, tasksid,
tclass, true);
}
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 orig_tclass)
{
return security_compute_validatetrans(oldsid, newsid, tasksid,
orig_tclass, false);
}
/* /*
* security_bounded_transition - check whether the given * security_bounded_transition - check whether the given
* transition is directed to bounded, or not. * transition is directed to bounded, or not.
......
...@@ -1465,7 +1465,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) ...@@ -1465,7 +1465,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
* *
* Returns the size of the attribute or an error code * Returns the size of the attribute or an error code
*/ */
static int smack_inode_getsecurity(const struct inode *inode, static int smack_inode_getsecurity(struct inode *inode,
const char *name, void **buffer, const char *name, void **buffer,
bool alloc) bool alloc)
{ {
...@@ -1538,7 +1538,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer, ...@@ -1538,7 +1538,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
* @inode: inode to extract the info from * @inode: inode to extract the info from
* @secid: where result will be saved * @secid: where result will be saved
*/ */
static void smack_inode_getsecid(const struct inode *inode, u32 *secid) static void smack_inode_getsecid(struct inode *inode, u32 *secid)
{ {
struct inode_smack *isp = inode->i_security; struct inode_smack *isp = inode->i_security;
......
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