Commit ff2bb047 authored by James Morris's avatar James Morris

Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into next

Per pull request, for 3.5.
parents cffee16e c737f828
...@@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, ...@@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f->f_op = fops_get(inode->i_fop); f->f_op = fops_get(inode->i_fop);
error = security_dentry_open(f, cred); error = security_file_open(f, cred);
if (error) if (error)
goto cleanup_all; goto cleanup_all;
......
...@@ -53,7 +53,6 @@ struct common_audit_data { ...@@ -53,7 +53,6 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_KMOD 8 #define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9 #define LSM_AUDIT_DATA_INODE 9
#define LSM_AUDIT_DATA_DENTRY 10 #define LSM_AUDIT_DATA_DENTRY 10
struct task_struct *tsk;
union { union {
struct path path; struct path path;
struct dentry *dentry; struct dentry *dentry;
...@@ -93,11 +92,6 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -93,11 +92,6 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
int ipv6_skb_to_auditdata(struct sk_buff *skb, int ipv6_skb_to_auditdata(struct sk_buff *skb,
struct common_audit_data *ad, u8 *proto); struct common_audit_data *ad, u8 *proto);
/* Initialize an LSM audit data structure. */
#define COMMON_AUDIT_DATA_INIT(_d, _t) \
{ memset((_d), 0, sizeof(struct common_audit_data)); \
(_d)->type = LSM_AUDIT_DATA_##_t; }
void common_lsm_audit(struct common_audit_data *a, void common_lsm_audit(struct common_audit_data *a,
void (*pre_audit)(struct audit_buffer *, void *), void (*pre_audit)(struct audit_buffer *, void *),
void (*post_audit)(struct audit_buffer *, void *)); void (*post_audit)(struct audit_buffer *, void *));
......
...@@ -640,10 +640,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -640,10 +640,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* to receive an open file descriptor via socket IPC. * to receive an open file descriptor via socket IPC.
* @file contains the file structure being received. * @file contains the file structure being received.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* * @file_open
* Security hook for dentry
*
* @dentry_open
* Save open-time permission checking state for later use upon * Save open-time permission checking state for later use upon
* file_permission, and recheck access if anything has changed * file_permission, and recheck access if anything has changed
* since inode_permission. * since inode_permission.
...@@ -1498,7 +1495,7 @@ struct security_operations { ...@@ -1498,7 +1495,7 @@ struct security_operations {
int (*file_send_sigiotask) (struct task_struct *tsk, int (*file_send_sigiotask) (struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int (*file_receive) (struct file *file); int (*file_receive) (struct file *file);
int (*dentry_open) (struct file *file, const struct cred *cred); int (*file_open) (struct file *file, const struct cred *cred);
int (*task_create) (unsigned long clone_flags); int (*task_create) (unsigned long clone_flags);
void (*task_free) (struct task_struct *task); void (*task_free) (struct task_struct *task);
...@@ -1757,7 +1754,7 @@ int security_file_set_fowner(struct file *file); ...@@ -1757,7 +1754,7 @@ int security_file_set_fowner(struct file *file);
int security_file_send_sigiotask(struct task_struct *tsk, int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int security_file_receive(struct file *file); int security_file_receive(struct file *file);
int security_dentry_open(struct file *file, const struct cred *cred); int security_file_open(struct file *file, const struct cred *cred);
int security_task_create(unsigned long clone_flags); int security_task_create(unsigned long clone_flags);
void security_task_free(struct task_struct *task); void security_task_free(struct task_struct *task);
int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
...@@ -2228,7 +2225,7 @@ static inline int security_file_receive(struct file *file) ...@@ -2228,7 +2225,7 @@ static inline int security_file_receive(struct file *file)
return 0; return 0;
} }
static inline int security_dentry_open(struct file *file, static inline int security_file_open(struct file *file,
const struct cred *cred) const struct cred *cred)
{ {
return 0; return 0;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <net/dst.h> #include <net/dst.h>
#include <net/flow.h>
#include <net/xfrm.h> #include <net/xfrm.h>
#include <net/ip.h> #include <net/ip.h>
#ifdef CONFIG_XFRM_STATISTICS #ifdef CONFIG_XFRM_STATISTICS
......
...@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = { ...@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = {
static void audit_pre(struct audit_buffer *ab, void *ca) static void audit_pre(struct audit_buffer *ab, void *ca)
{ {
struct common_audit_data *sa = ca; struct common_audit_data *sa = ca;
struct task_struct *tsk = sa->tsk ? sa->tsk : current; struct task_struct *tsk = sa->aad->tsk ? sa->aad->tsk : current;
if (aa_g_audit_header) { if (aa_g_audit_header) {
audit_log_format(ab, "apparmor="); audit_log_format(ab, "apparmor=");
...@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, sa->aad->name); audit_log_untrustedstring(ab, sa->aad->name);
} }
if (sa->aad->tsk) {
audit_log_format(ab, " pid=%d comm=", tsk->pid);
audit_log_untrustedstring(ab, tsk->comm);
}
} }
/** /**
...@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, ...@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
aa_audit_msg(type, sa, cb); aa_audit_msg(type, sa, cb);
if (sa->aad->type == AUDIT_APPARMOR_KILL) if (sa->aad->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); (void)send_sig_info(SIGKILL, NULL,
sa->aad->tsk ? sa->aad->tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error); return complain_error(sa->aad->error);
......
...@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, ...@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, CAP); sa.type = LSM_AUDIT_DATA_CAP;
sa.aad = &aad; sa.aad = &aad;
sa.tsk = task;
sa.u.cap = cap; sa.u.cap = cap;
sa.aad->tsk = task;
sa.aad->op = OP_CAPABLE; sa.aad->op = OP_CAPABLE;
sa.aad->error = error; sa.aad->error = error;
......
...@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, ...@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.op = op, aad.op = op,
aad.fs.request = request; aad.fs.request = request;
......
...@@ -110,6 +110,7 @@ struct apparmor_audit_data { ...@@ -110,6 +110,7 @@ struct apparmor_audit_data {
void *profile; void *profile;
const char *name; const char *name;
const char *info; const char *info;
struct task_struct *tsk;
union { union {
void *target; void *target;
struct { struct {
......
...@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile, ...@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile,
{ {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.op = OP_PTRACE; aad.op = OP_PTRACE;
aad.target = target; aad.target = target;
......
...@@ -66,7 +66,7 @@ void aa_info_message(const char *str) ...@@ -66,7 +66,7 @@ void aa_info_message(const char *str)
if (audit_enabled) { if (audit_enabled) {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.info = str; aad.info = str;
aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
......
...@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) ...@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
AA_MAY_META_READ); AA_MAY_META_READ);
} }
static int apparmor_dentry_open(struct file *file, const struct cred *cred) static int apparmor_file_open(struct file *file, const struct cred *cred)
{ {
struct aa_file_cxt *fcxt = file->f_security; struct aa_file_cxt *fcxt = file->f_security;
struct aa_profile *profile; struct aa_profile *profile;
...@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, ...@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
} else { } else {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.op = OP_SETPROCATTR; aad.op = OP_SETPROCATTR;
aad.info = name; aad.info = name;
...@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = { ...@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = {
.path_chmod = apparmor_path_chmod, .path_chmod = apparmor_path_chmod,
.path_chown = apparmor_path_chown, .path_chown = apparmor_path_chown,
.path_truncate = apparmor_path_truncate, .path_truncate = apparmor_path_truncate,
.dentry_open = apparmor_dentry_open,
.inode_getattr = apparmor_inode_getattr, .inode_getattr = apparmor_inode_getattr,
.file_open = apparmor_file_open,
.file_permission = apparmor_file_permission, .file_permission = apparmor_file_permission,
.file_alloc_security = apparmor_file_alloc_security, .file_alloc_security = apparmor_file_alloc_security,
.file_free_security = apparmor_file_free_security, .file_free_security = apparmor_file_free_security,
......
...@@ -969,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info, ...@@ -969,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
{ {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.op = op; aad.op = op;
aad.name = name; aad.name = name;
......
...@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name, ...@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name,
struct aa_profile *profile = __aa_current_profile(); struct aa_profile *profile = __aa_current_profile();
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
if (e) if (e)
aad.iface.pos = e->pos - e->start; aad.iface.pos = e->pos - e->start;
......
...@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource, ...@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource,
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,}; struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad; sa.aad = &aad;
aad.op = OP_SETRLIMIT, aad.op = OP_SETRLIMIT,
aad.rlim.rlim = resource; aad.rlim.rlim = resource;
......
...@@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file) ...@@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file)
return 0; return 0;
} }
static int cap_dentry_open(struct file *file, const struct cred *cred) static int cap_file_open(struct file *file, const struct cred *cred)
{ {
return 0; return 0;
} }
...@@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops) ...@@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, file_set_fowner); set_to_cap_if_null(ops, file_set_fowner);
set_to_cap_if_null(ops, file_send_sigiotask); set_to_cap_if_null(ops, file_send_sigiotask);
set_to_cap_if_null(ops, file_receive); set_to_cap_if_null(ops, file_receive);
set_to_cap_if_null(ops, dentry_open); set_to_cap_if_null(ops, file_open);
set_to_cap_if_null(ops, task_create); set_to_cap_if_null(ops, task_create);
set_to_cap_if_null(ops, task_free); set_to_cap_if_null(ops, task_free);
set_to_cap_if_null(ops, cred_alloc_blank); set_to_cap_if_null(ops, cred_alloc_blank);
......
...@@ -213,12 +213,15 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -213,12 +213,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
if (a->tsk) /*
tsk = a->tsk; * To keep stack sizes in check force programers to notice if they
if (tsk && tsk->pid) { * start making this union too large! See struct lsm_network_audit
* as an example of how to deal with large data.
*/
BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
audit_log_format(ab, " pid=%d comm=", tsk->pid); audit_log_format(ab, " pid=%d comm=", tsk->pid);
audit_log_untrustedstring(ab, tsk->comm); audit_log_untrustedstring(ab, tsk->comm);
}
switch (a->type) { switch (a->type) {
case LSM_AUDIT_DATA_NONE: case LSM_AUDIT_DATA_NONE:
......
...@@ -701,11 +701,11 @@ int security_file_receive(struct file *file) ...@@ -701,11 +701,11 @@ int security_file_receive(struct file *file)
return security_ops->file_receive(file); return security_ops->file_receive(file);
} }
int security_dentry_open(struct file *file, const struct cred *cred) int security_file_open(struct file *file, const struct cred *cred)
{ {
int ret; int ret;
ret = security_ops->dentry_open(file, cred); ret = security_ops->file_open(file, cred);
if (ret) if (ret)
return ret; return ret;
......
...@@ -65,14 +65,8 @@ struct avc_cache { ...@@ -65,14 +65,8 @@ struct avc_cache {
}; };
struct avc_callback_node { struct avc_callback_node {
int (*callback) (u32 event, u32 ssid, u32 tsid, int (*callback) (u32 event);
u16 tclass, u32 perms,
u32 *out_retained);
u32 events; u32 events;
u32 ssid;
u32 tsid;
u16 tclass;
u32 perms;
struct avc_callback_node *next; struct avc_callback_node *next;
}; };
...@@ -436,9 +430,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) ...@@ -436,9 +430,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
{ {
struct common_audit_data *ad = a; struct common_audit_data *ad = a;
audit_log_format(ab, "avc: %s ", audit_log_format(ab, "avc: %s ",
ad->selinux_audit_data->slad->denied ? "denied" : "granted"); ad->selinux_audit_data->denied ? "denied" : "granted");
avc_dump_av(ab, ad->selinux_audit_data->slad->tclass, avc_dump_av(ab, ad->selinux_audit_data->tclass,
ad->selinux_audit_data->slad->audited); ad->selinux_audit_data->audited);
audit_log_format(ab, " for "); audit_log_format(ab, " for ");
} }
...@@ -452,25 +446,23 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) ...@@ -452,25 +446,23 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
{ {
struct common_audit_data *ad = a; struct common_audit_data *ad = a;
audit_log_format(ab, " "); audit_log_format(ab, " ");
avc_dump_query(ab, ad->selinux_audit_data->slad->ssid, avc_dump_query(ab, ad->selinux_audit_data->ssid,
ad->selinux_audit_data->slad->tsid, ad->selinux_audit_data->tsid,
ad->selinux_audit_data->slad->tclass); ad->selinux_audit_data->tclass);
} }
/* This is the slow part of avc audit with big stack footprint */ /* This is the slow part of avc audit with big stack footprint */
static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
u32 requested, u32 audited, u32 denied, u32 requested, u32 audited, u32 denied,
struct common_audit_data *a, struct common_audit_data *a,
unsigned flags) unsigned flags)
{ {
struct common_audit_data stack_data; struct common_audit_data stack_data;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad;
struct selinux_late_audit_data slad;
if (!a) { if (!a) {
a = &stack_data; a = &stack_data;
COMMON_AUDIT_DATA_INIT(a, NONE); a->type = LSM_AUDIT_DATA_NONE;
a->selinux_audit_data = &sad;
} }
/* /*
...@@ -484,104 +476,34 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, ...@@ -484,104 +476,34 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
(flags & MAY_NOT_BLOCK)) (flags & MAY_NOT_BLOCK))
return -ECHILD; return -ECHILD;
slad.tclass = tclass; sad.tclass = tclass;
slad.requested = requested; sad.requested = requested;
slad.ssid = ssid; sad.ssid = ssid;
slad.tsid = tsid; sad.tsid = tsid;
slad.audited = audited; sad.audited = audited;
slad.denied = denied; sad.denied = denied;
a->selinux_audit_data->slad = &slad; a->selinux_audit_data = &sad;
common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
return 0;
}
/** common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
* avc_audit - Audit the granting or denial of permissions.
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
* @requested: requested permissions
* @avd: access vector decisions
* @result: result from avc_has_perm_noaudit
* @a: auxiliary audit data
* @flags: VFS walk flags
*
* Audit the granting or denial of permissions in accordance
* with the policy. This function is typically called by
* avc_has_perm() after a permission check, but can also be
* called directly by callers who use avc_has_perm_noaudit()
* in order to separate the permission check from the auditing.
* For example, this separation is useful when the permission check must
* be performed under a lock, to allow the lock to be released
* before calling the auditing code.
*/
inline int avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd, int result, struct common_audit_data *a,
unsigned flags)
{
u32 denied, audited;
denied = requested & ~avd->allowed;
if (unlikely(denied)) {
audited = denied & avd->auditdeny;
/*
* a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in
* this field means that ANY denials should NOT be audited if
* the policy contains an explicit dontaudit rule for that
* permission. Take notice that this is unrelated to the
* actual permissions that were denied. As an example lets
* assume:
*
* denied == READ
* avd.auditdeny & ACCESS == 0 (not set means explicit rule)
* selinux_audit_data->auditdeny & ACCESS == 1
*
* We will NOT audit the denial even though the denied
* permission was READ and the auditdeny checks were for
* ACCESS
*/
if (a &&
a->selinux_audit_data->auditdeny &&
!(a->selinux_audit_data->auditdeny & avd->auditdeny))
audited = 0;
} else if (result)
audited = denied = requested;
else
audited = requested & avd->auditallow;
if (likely(!audited))
return 0; return 0;
return slow_avc_audit(ssid, tsid, tclass,
requested, audited, denied,
a, flags);
} }
/** /**
* avc_add_callback - Register a callback for security events. * avc_add_callback - Register a callback for security events.
* @callback: callback function * @callback: callback function
* @events: security events * @events: security events
* @ssid: source security identifier or %SECSID_WILD
* @tsid: target security identifier or %SECSID_WILD
* @tclass: target security class
* @perms: permissions
* *
* Register a callback function for events in the set @events * Register a callback function for events in the set @events.
* related to the SID pair (@ssid, @tsid) * Returns %0 on success or -%ENOMEM if insufficient memory
* and the permissions @perms, interpreting * exists to add the callback.
* @perms based on @tclass. Returns %0 on success or
* -%ENOMEM if insufficient memory exists to add the callback.
*/ */
int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, int __init avc_add_callback(int (*callback)(u32 event), u32 events)
u16 tclass, u32 perms,
u32 *out_retained),
u32 events, u32 ssid, u32 tsid,
u16 tclass, u32 perms)
{ {
struct avc_callback_node *c; struct avc_callback_node *c;
int rc = 0; int rc = 0;
c = kmalloc(sizeof(*c), GFP_ATOMIC); c = kmalloc(sizeof(*c), GFP_KERNEL);
if (!c) { if (!c) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
...@@ -589,9 +511,6 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, ...@@ -589,9 +511,6 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
c->callback = callback; c->callback = callback;
c->events = events; c->events = events;
c->ssid = ssid;
c->tsid = tsid;
c->perms = perms;
c->next = avc_callbacks; c->next = avc_callbacks;
avc_callbacks = c; avc_callbacks = c;
out: out:
...@@ -731,8 +650,7 @@ int avc_ss_reset(u32 seqno) ...@@ -731,8 +650,7 @@ int avc_ss_reset(u32 seqno)
for (c = avc_callbacks; c; c = c->next) { for (c = avc_callbacks; c; c = c->next) {
if (c->events & AVC_CALLBACK_RESET) { if (c->events & AVC_CALLBACK_RESET) {
tmprc = c->callback(AVC_CALLBACK_RESET, tmprc = c->callback(AVC_CALLBACK_RESET);
0, 0, 0, 0, NULL);
/* save the first error encountered for the return /* save the first error encountered for the return
value and continue processing the callbacks */ value and continue processing the callbacks */
if (!rc) if (!rc)
......
This diff is collapsed.
...@@ -49,7 +49,7 @@ struct avc_cache_stats { ...@@ -49,7 +49,7 @@ struct avc_cache_stats {
/* /*
* We only need this data after we have decided to send an audit message. * We only need this data after we have decided to send an audit message.
*/ */
struct selinux_late_audit_data { struct selinux_audit_data {
u32 ssid; u32 ssid;
u32 tsid; u32 tsid;
u16 tclass; u16 tclass;
...@@ -59,29 +59,87 @@ struct selinux_late_audit_data { ...@@ -59,29 +59,87 @@ struct selinux_late_audit_data {
int result; int result;
}; };
/*
* We collect this at the beginning or during an selinux security operation
*/
struct selinux_audit_data {
/*
* auditdeny is a bit tricky and unintuitive. See the
* comments in avc.c for it's meaning and usage.
*/
u32 auditdeny;
struct selinux_late_audit_data *slad;
};
/* /*
* AVC operations * AVC operations
*/ */
void __init avc_init(void); void __init avc_init(void);
int avc_audit(u32 ssid, u32 tsid, static inline u32 avc_audit_required(u32 requested,
struct av_decision *avd,
int result,
u32 auditdeny,
u32 *deniedp)
{
u32 denied, audited;
denied = requested & ~avd->allowed;
if (unlikely(denied)) {
audited = denied & avd->auditdeny;
/*
* auditdeny is TRICKY! Setting a bit in
* this field means that ANY denials should NOT be audited if
* the policy contains an explicit dontaudit rule for that
* permission. Take notice that this is unrelated to the
* actual permissions that were denied. As an example lets
* assume:
*
* denied == READ
* avd.auditdeny & ACCESS == 0 (not set means explicit rule)
* auditdeny & ACCESS == 1
*
* We will NOT audit the denial even though the denied
* permission was READ and the auditdeny checks were for
* ACCESS
*/
if (auditdeny && !(auditdeny & avd->auditdeny))
audited = 0;
} else if (result)
audited = denied = requested;
else
audited = requested & avd->auditallow;
*deniedp = denied;
return audited;
}
int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
u32 requested, u32 audited, u32 denied,
struct common_audit_data *a,
unsigned flags);
/**
* avc_audit - Audit the granting or denial of permissions.
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
* @requested: requested permissions
* @avd: access vector decisions
* @result: result from avc_has_perm_noaudit
* @a: auxiliary audit data
* @flags: VFS walk flags
*
* Audit the granting or denial of permissions in accordance
* with the policy. This function is typically called by
* avc_has_perm() after a permission check, but can also be
* called directly by callers who use avc_has_perm_noaudit()
* in order to separate the permission check from the auditing.
* For example, this separation is useful when the permission check must
* be performed under a lock, to allow the lock to be released
* before calling the auditing code.
*/
static inline int avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested, u16 tclass, u32 requested,
struct av_decision *avd, struct av_decision *avd,
int result, int result,
struct common_audit_data *a, unsigned flags); struct common_audit_data *a, unsigned flags)
{
u32 audited, denied;
audited = avc_audit_required(requested, avd, result, 0, &denied);
if (likely(!audited))
return 0;
return slow_avc_audit(ssid, tsid, tclass,
requested, audited, denied,
a, flags);
}
#define AVC_STRICT 1 /* Ignore permissive mode. */ #define AVC_STRICT 1 /* Ignore permissive mode. */
int avc_has_perm_noaudit(u32 ssid, u32 tsid, int avc_has_perm_noaudit(u32 ssid, u32 tsid,
...@@ -112,11 +170,7 @@ u32 avc_policy_seqno(void); ...@@ -112,11 +170,7 @@ u32 avc_policy_seqno(void);
#define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_ENABLE 64
#define AVC_CALLBACK_AUDITDENY_DISABLE 128 #define AVC_CALLBACK_AUDITDENY_DISABLE 128
int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, int avc_add_callback(int (*callback)(u32 event), u32 events);
u16 tclass, u32 perms,
u32 *out_retained),
u32 events, u32 ssid, u32 tsid,
u16 tclass, u32 perms);
/* Exported to selinuxfs */ /* Exported to selinuxfs */
int avc_get_hash_stats(char *page); int avc_get_hash_stats(char *page);
......
...@@ -31,13 +31,15 @@ ...@@ -31,13 +31,15 @@
#define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_BOUNDARY 24
#define POLICYDB_VERSION_FILENAME_TRANS 25 #define POLICYDB_VERSION_FILENAME_TRANS 25
#define POLICYDB_VERSION_ROLETRANS 26 #define POLICYDB_VERSION_ROLETRANS 26
#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
#define POLICYDB_VERSION_DEFAULT_TYPE 28
/* Range of policy versions we understand*/ /* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#else #else
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS #define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE
#endif #endif
/* Mask for just the mount related flags */ /* Mask for just the mount related flags */
......
...@@ -252,8 +252,7 @@ static void sel_netif_flush(void) ...@@ -252,8 +252,7 @@ static void sel_netif_flush(void)
spin_unlock_bh(&sel_netif_lock); spin_unlock_bh(&sel_netif_lock);
} }
static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid, static int sel_netif_avc_callback(u32 event)
u16 class, u32 perms, u32 *retained)
{ {
if (event == AVC_CALLBACK_RESET) { if (event == AVC_CALLBACK_RESET) {
sel_netif_flush(); sel_netif_flush();
...@@ -292,8 +291,7 @@ static __init int sel_netif_init(void) ...@@ -292,8 +291,7 @@ static __init int sel_netif_init(void)
register_netdevice_notifier(&sel_netif_netdev_notifier); register_netdevice_notifier(&sel_netif_netdev_notifier);
err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET, err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
if (err) if (err)
panic("avc_add_callback() failed, error %d\n", err); panic("avc_add_callback() failed, error %d\n", err);
......
...@@ -297,8 +297,7 @@ static void sel_netnode_flush(void) ...@@ -297,8 +297,7 @@ static void sel_netnode_flush(void)
spin_unlock_bh(&sel_netnode_lock); spin_unlock_bh(&sel_netnode_lock);
} }
static int sel_netnode_avc_callback(u32 event, u32 ssid, u32 tsid, static int sel_netnode_avc_callback(u32 event)
u16 class, u32 perms, u32 *retained)
{ {
if (event == AVC_CALLBACK_RESET) { if (event == AVC_CALLBACK_RESET) {
sel_netnode_flush(); sel_netnode_flush();
...@@ -320,8 +319,7 @@ static __init int sel_netnode_init(void) ...@@ -320,8 +319,7 @@ static __init int sel_netnode_init(void)
sel_netnode_hash[iter].size = 0; sel_netnode_hash[iter].size = 0;
} }
ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
if (ret != 0) if (ret != 0)
panic("avc_add_callback() failed, error %d\n", ret); panic("avc_add_callback() failed, error %d\n", ret);
......
...@@ -234,8 +234,7 @@ static void sel_netport_flush(void) ...@@ -234,8 +234,7 @@ static void sel_netport_flush(void)
spin_unlock_bh(&sel_netport_lock); spin_unlock_bh(&sel_netport_lock);
} }
static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid, static int sel_netport_avc_callback(u32 event)
u16 class, u32 perms, u32 *retained)
{ {
if (event == AVC_CALLBACK_RESET) { if (event == AVC_CALLBACK_RESET) {
sel_netport_flush(); sel_netport_flush();
...@@ -257,8 +256,7 @@ static __init int sel_netport_init(void) ...@@ -257,8 +256,7 @@ static __init int sel_netport_init(void)
sel_netport_hash[iter].size = 0; sel_netport_hash[iter].size = 0;
} }
ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET, ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
if (ret != 0) if (ret != 0)
panic("avc_add_callback() failed, error %d\n", ret); panic("avc_add_callback() failed, error %d\n", ret);
......
...@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = { ...@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = {
.read = sel_read_policy, .read = sel_read_policy,
.mmap = sel_mmap_policy, .mmap = sel_mmap_policy,
.release = sel_release_policy, .release = sel_release_policy,
.llseek = generic_file_llseek,
}; };
static ssize_t sel_write_load(struct file *file, const char __user *buf, static ssize_t sel_write_load(struct file *file, const char __user *buf,
...@@ -1232,6 +1233,7 @@ static int sel_make_bools(void) ...@@ -1232,6 +1233,7 @@ static int sel_make_bools(void)
kfree(bool_pending_names[i]); kfree(bool_pending_names[i]);
kfree(bool_pending_names); kfree(bool_pending_names);
kfree(bool_pending_values); kfree(bool_pending_values);
bool_num = 0;
bool_pending_names = NULL; bool_pending_names = NULL;
bool_pending_values = NULL; bool_pending_values = NULL;
...@@ -1532,11 +1534,6 @@ static int sel_make_initcon_files(struct dentry *dir) ...@@ -1532,11 +1534,6 @@ static int sel_make_initcon_files(struct dentry *dir)
return 0; return 0;
} }
static inline unsigned int sel_div(unsigned long a, unsigned long b)
{
return a / b - (a % b < 0);
}
static inline unsigned long sel_class_to_ino(u16 class) static inline unsigned long sel_class_to_ino(u16 class)
{ {
return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET; return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
...@@ -1544,7 +1541,7 @@ static inline unsigned long sel_class_to_ino(u16 class) ...@@ -1544,7 +1541,7 @@ static inline unsigned long sel_class_to_ino(u16 class)
static inline u16 sel_ino_to_class(unsigned long ino) static inline u16 sel_ino_to_class(unsigned long ino)
{ {
return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1); return (ino & SEL_INO_MASK) / (SEL_VEC_MAX + 1);
} }
static inline unsigned long sel_perm_to_ino(u16 class, u32 perm) static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
...@@ -1831,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1831,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO}, [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
[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_IRUSR}, [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
/* last one */ {""} /* last one */ {""}
}; };
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
......
...@@ -74,6 +74,26 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src) ...@@ -74,6 +74,26 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
return rc; return rc;
} }
/*
* Sets both levels in the MLS range of 'dst' to the high level of 'src'.
*/
static inline int mls_context_cpy_high(struct context *dst, struct context *src)
{
int rc;
dst->range.level[0].sens = src->range.level[1].sens;
rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
if (rc)
goto out;
dst->range.level[1].sens = src->range.level[1].sens;
rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
if (rc)
ebitmap_destroy(&dst->range.level[0].cat);
out:
return rc;
}
static inline int mls_context_cmp(struct context *c1, struct context *c2) static inline int mls_context_cmp(struct context *c1, struct context *c2)
{ {
return ((c1->range.level[0].sens == c2->range.level[0].sens) && return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
......
...@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext, ...@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext,
{ {
struct range_trans rtr; struct range_trans rtr;
struct mls_range *r; struct mls_range *r;
struct class_datum *cladatum;
int default_range = 0;
if (!policydb.mls_enabled) if (!policydb.mls_enabled)
return 0; return 0;
...@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext, ...@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext,
r = hashtab_search(policydb.range_tr, &rtr); r = hashtab_search(policydb.range_tr, &rtr);
if (r) if (r)
return mls_range_set(newcontext, r); return mls_range_set(newcontext, r);
if (tclass && tclass <= policydb.p_classes.nprim) {
cladatum = policydb.class_val_to_struct[tclass - 1];
if (cladatum)
default_range = cladatum->default_range;
}
switch (default_range) {
case DEFAULT_SOURCE_LOW:
return mls_context_cpy_low(newcontext, scontext);
case DEFAULT_SOURCE_HIGH:
return mls_context_cpy_high(newcontext, scontext);
case DEFAULT_SOURCE_LOW_HIGH:
return mls_context_cpy(newcontext, scontext);
case DEFAULT_TARGET_LOW:
return mls_context_cpy_low(newcontext, tcontext);
case DEFAULT_TARGET_HIGH:
return mls_context_cpy_high(newcontext, tcontext);
case DEFAULT_TARGET_LOW_HIGH:
return mls_context_cpy(newcontext, tcontext);
}
/* Fallthrough */ /* Fallthrough */
case AVTAB_CHANGE: case AVTAB_CHANGE:
if ((tclass == policydb.process_class) || (sock == true)) if ((tclass == policydb.process_class) || (sock == true))
......
...@@ -133,6 +133,16 @@ static struct policydb_compat_info policydb_compat[] = { ...@@ -133,6 +133,16 @@ static struct policydb_compat_info policydb_compat[] = {
.sym_num = SYM_NUM, .sym_num = SYM_NUM,
.ocon_num = OCON_NUM, .ocon_num = OCON_NUM,
}, },
{
.version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
{
.version = POLICYDB_VERSION_DEFAULT_TYPE,
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
}; };
static struct policydb_compat_info *policydb_lookup_compat(int version) static struct policydb_compat_info *policydb_lookup_compat(int version)
...@@ -1306,6 +1316,23 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1306,6 +1316,23 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
goto bad; goto bad;
} }
if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
rc = next_entry(buf, fp, sizeof(u32) * 3);
if (rc)
goto bad;
cladatum->default_user = le32_to_cpu(buf[0]);
cladatum->default_role = le32_to_cpu(buf[1]);
cladatum->default_range = le32_to_cpu(buf[2]);
}
if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
rc = next_entry(buf, fp, sizeof(u32) * 1);
if (rc)
goto bad;
cladatum->default_type = le32_to_cpu(buf[0]);
}
rc = hashtab_insert(h, key, cladatum); rc = hashtab_insert(h, key, cladatum);
if (rc) if (rc)
goto bad; goto bad;
...@@ -2832,6 +2859,23 @@ static int class_write(void *vkey, void *datum, void *ptr) ...@@ -2832,6 +2859,23 @@ static int class_write(void *vkey, void *datum, void *ptr)
if (rc) if (rc)
return rc; return rc;
if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
buf[0] = cpu_to_le32(cladatum->default_user);
buf[1] = cpu_to_le32(cladatum->default_role);
buf[2] = cpu_to_le32(cladatum->default_range);
rc = put_entry(buf, sizeof(uint32_t), 3, fp);
if (rc)
return rc;
}
if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
buf[0] = cpu_to_le32(cladatum->default_type);
rc = put_entry(buf, sizeof(uint32_t), 1, fp);
if (rc)
return rc;
}
return 0; return 0;
} }
......
...@@ -60,6 +60,20 @@ struct class_datum { ...@@ -60,6 +60,20 @@ struct class_datum {
struct symtab permissions; /* class-specific permission symbol table */ struct symtab permissions; /* class-specific permission symbol table */
struct constraint_node *constraints; /* constraints on class permissions */ struct constraint_node *constraints; /* constraints on class permissions */
struct constraint_node *validatetrans; /* special transition rules */ struct constraint_node *validatetrans; /* special transition rules */
/* Options how a new object user, role, and type should be decided */
#define DEFAULT_SOURCE 1
#define DEFAULT_TARGET 2
char default_user;
char default_role;
char default_type;
/* Options how a new object range should be decided */
#define DEFAULT_SOURCE_LOW 1
#define DEFAULT_SOURCE_HIGH 2
#define DEFAULT_SOURCE_LOW_HIGH 3
#define DEFAULT_TARGET_LOW 4
#define DEFAULT_TARGET_HIGH 5
#define DEFAULT_TARGET_LOW_HIGH 6
char default_range;
}; };
/* Role attributes */ /* Role attributes */
......
...@@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 ...@@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
if (context->len) { if (context->len) {
*scontext_len = context->len; *scontext_len = context->len;
if (scontext) {
*scontext = kstrdup(context->str, GFP_ATOMIC); *scontext = kstrdup(context->str, GFP_ATOMIC);
if (!(*scontext)) if (!(*scontext))
return -ENOMEM; return -ENOMEM;
}
return 0; return 0;
} }
...@@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid, ...@@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid,
u32 *out_sid, u32 *out_sid,
bool kern) bool kern)
{ {
struct class_datum *cladatum = NULL;
struct context *scontext = NULL, *tcontext = NULL, newcontext; struct context *scontext = NULL, *tcontext = NULL, newcontext;
struct role_trans *roletr = NULL; struct role_trans *roletr = NULL;
struct avtab_key avkey; struct avtab_key avkey;
...@@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid, ...@@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid,
goto out_unlock; goto out_unlock;
} }
if (tclass && tclass <= policydb.p_classes.nprim)
cladatum = policydb.class_val_to_struct[tclass - 1];
/* Set the user identity. */ /* Set the user identity. */
switch (specified) { switch (specified) {
case AVTAB_TRANSITION: case AVTAB_TRANSITION:
case AVTAB_CHANGE: case AVTAB_CHANGE:
if (cladatum && cladatum->default_user == DEFAULT_TARGET) {
newcontext.user = tcontext->user;
} else {
/* notice this gets both DEFAULT_SOURCE and unset */
/* Use the process user identity. */ /* Use the process user identity. */
newcontext.user = scontext->user; newcontext.user = scontext->user;
}
break; break;
case AVTAB_MEMBER: case AVTAB_MEMBER:
/* Use the related object owner. */ /* Use the related object owner. */
...@@ -1450,17 +1461,32 @@ static int security_compute_sid(u32 ssid, ...@@ -1450,17 +1461,32 @@ static int security_compute_sid(u32 ssid,
break; break;
} }
/* Set the role and type to default values. */ /* Set the role to default values. */
if ((tclass == policydb.process_class) || (sock == true)) { if (cladatum && cladatum->default_role == DEFAULT_SOURCE) {
/* Use the current role and type of process. */
newcontext.role = scontext->role; newcontext.role = scontext->role;
newcontext.type = scontext->type; } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) {
newcontext.role = tcontext->role;
} else { } else {
/* Use the well-defined object role. */ if ((tclass == policydb.process_class) || (sock == true))
newcontext.role = scontext->role;
else
newcontext.role = OBJECT_R_VAL; newcontext.role = OBJECT_R_VAL;
}
/* Set the type to default values. */
if (cladatum && cladatum->default_type == DEFAULT_SOURCE) {
newcontext.type = scontext->type;
} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
newcontext.type = tcontext->type;
} else {
if ((tclass == policydb.process_class) || (sock == true)) {
/* Use the type of process. */
newcontext.type = scontext->type;
} else {
/* Use the type of the related object. */ /* Use the type of the related object. */
newcontext.type = tcontext->type; newcontext.type = tcontext->type;
} }
}
/* Look for a type transition/member/change rule. */ /* Look for a type transition/member/change rule. */
avkey.source_type = scontext->type; avkey.source_type = scontext->type;
...@@ -3018,8 +3044,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, ...@@ -3018,8 +3044,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
static int (*aurule_callback)(void) = audit_update_lsm_rules; static int (*aurule_callback)(void) = audit_update_lsm_rules;
static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, static int aurule_avc_callback(u32 event)
u16 class, u32 perms, u32 *retained)
{ {
int err = 0; int err = 0;
...@@ -3032,8 +3057,7 @@ static int __init aurule_init(void) ...@@ -3032,8 +3057,7 @@ static int __init aurule_init(void)
{ {
int err; int err;
err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET);
SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
if (err) if (err)
panic("avc_add_callback() failed, error %d\n", err); panic("avc_add_callback() failed, error %d\n", err);
......
...@@ -304,7 +304,7 @@ void smack_log(char *subject_label, char *object_label, ...@@ -304,7 +304,7 @@ void smack_log(char *subject_label, char *object_label,
static inline void smk_ad_init(struct smk_audit_info *a, const char *func, static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
char type) char type)
{ {
memset(a, 0, sizeof(*a)); memset(&a->sad, 0, sizeof(a->sad));
a->a.type = type; a->a.type = type;
a->a.smack_audit_data = &a->sad; a->a.smack_audit_data = &a->sad;
a->a.smack_audit_data->function = func; a->a.smack_audit_data->function = func;
......
...@@ -1359,7 +1359,7 @@ static int smack_file_receive(struct file *file) ...@@ -1359,7 +1359,7 @@ static int smack_file_receive(struct file *file)
} }
/** /**
* smack_dentry_open - Smack dentry open processing * smack_file_open - Smack dentry open processing
* @file: the object * @file: the object
* @cred: unused * @cred: unused
* *
...@@ -1367,7 +1367,7 @@ static int smack_file_receive(struct file *file) ...@@ -1367,7 +1367,7 @@ static int smack_file_receive(struct file *file)
* *
* Returns 0 * Returns 0
*/ */
static int smack_dentry_open(struct file *file, const struct cred *cred) static int smack_file_open(struct file *file, const struct cred *cred)
{ {
struct inode_smack *isp = file->f_path.dentry->d_inode->i_security; struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
...@@ -3487,7 +3487,7 @@ struct security_operations smack_ops = { ...@@ -3487,7 +3487,7 @@ struct security_operations smack_ops = {
.file_send_sigiotask = smack_file_send_sigiotask, .file_send_sigiotask = smack_file_send_sigiotask,
.file_receive = smack_file_receive, .file_receive = smack_file_receive,
.dentry_open = smack_dentry_open, .file_open = smack_file_open,
.cred_alloc_blank = smack_cred_alloc_blank, .cred_alloc_blank = smack_cred_alloc_blank,
.cred_free = smack_cred_free, .cred_free = smack_cred_free,
......
...@@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, ...@@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
} }
/** /**
* tomoyo_dentry_open - Target for security_dentry_open(). * tomoyo_file_open - Target for security_file_open().
* *
* @f: Pointer to "struct file". * @f: Pointer to "struct file".
* @cred: Pointer to "struct cred". * @cred: Pointer to "struct cred".
* *
* Returns 0 on success, negative value otherwise. * Returns 0 on success, negative value otherwise.
*/ */
static int tomoyo_dentry_open(struct file *f, const struct cred *cred) static int tomoyo_file_open(struct file *f, const struct cred *cred)
{ {
int flags = f->f_flags; int flags = f->f_flags;
/* Don't check read permission here if called from do_execve(). */ /* Don't check read permission here if called from do_execve(). */
...@@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = { ...@@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = {
.bprm_set_creds = tomoyo_bprm_set_creds, .bprm_set_creds = tomoyo_bprm_set_creds,
.bprm_check_security = tomoyo_bprm_check_security, .bprm_check_security = tomoyo_bprm_check_security,
.file_fcntl = tomoyo_file_fcntl, .file_fcntl = tomoyo_file_fcntl,
.dentry_open = tomoyo_dentry_open, .file_open = tomoyo_file_open,
.path_truncate = tomoyo_path_truncate, .path_truncate = tomoyo_path_truncate,
.path_unlink = tomoyo_path_unlink, .path_unlink = tomoyo_path_unlink,
.path_mkdir = tomoyo_path_mkdir, .path_mkdir = tomoyo_path_mkdir,
......
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