From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:50 +0000
Subject: [PATCH] rtl88x2CE_WiFi_linux driver
---
kernel/security/selinux/selinuxfs.c | 338 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 225 insertions(+), 113 deletions(-)
diff --git a/kernel/security/selinux/selinuxfs.c b/kernel/security/selinux/selinuxfs.c
index f6bc78a..d893c22 100644
--- a/kernel/security/selinux/selinuxfs.c
+++ b/kernel/security/selinux/selinuxfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/* Updated: Karl MacMillan <kmacmillan@tresys.com>
*
* Added conditional policy language extensions
@@ -9,9 +10,6 @@
* Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
* Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
*/
#include <linux/kernel.h>
@@ -19,8 +17,10 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
+#include <linux/fs_context.h>
#include <linux/mount.h>
#include <linux/mutex.h>
+#include <linux/namei.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/security.h>
@@ -75,7 +75,6 @@
unsigned long last_class_ino;
bool policy_opened;
struct dentry *policycap_dir;
- struct mutex mutex;
unsigned long last_ino;
struct selinux_state *state;
struct super_block *sb;
@@ -89,7 +88,6 @@
if (!fsi)
return -ENOMEM;
- mutex_init(&fsi->mutex);
fsi->last_ino = SEL_INO_NEXT - 1;
fsi->state = &selinux_state;
fsi->sb = sb;
@@ -117,6 +115,10 @@
#define SEL_CLASS_INO_OFFSET 0x04000000
#define SEL_POLICYCAP_INO_OFFSET 0x08000000
#define SEL_INO_MASK 0x00ffffff
+
+#define BOOL_DIR_NAME "booleans"
+#define CLASS_DIR_NAME "class"
+#define POLICYCAP_DIR_NAME "policy_capabilities"
#define TMPBUFLEN 12
static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -169,18 +171,17 @@
goto out;
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u ses=%u"
- " enabled=%d old-enabled=%d lsm=selinux res=1",
+ " enabled=1 old-enabled=1 lsm=selinux res=1",
new_value, old_value,
from_kuid(&init_user_ns, audit_get_loginuid(current)),
- audit_get_sessionid(current),
- selinux_enabled, selinux_enabled);
+ audit_get_sessionid(current));
enforcing_set(state, new_value);
if (new_value)
avc_ss_reset(state->avc, 0);
selnl_notify_setenforce(new_value);
selinux_status_update_setenforce(state, new_value);
if (!new_value)
- call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
+ call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
}
length = count;
out:
@@ -283,6 +284,13 @@
int new_value;
int enforcing;
+ /* NOTE: we are now officially considering runtime disable as
+ * deprecated, and using it will become increasingly painful
+ * (e.g. sleeping/blocking) as we progress through future
+ * kernel releases until eventually it is removed
+ */
+ pr_err("SELinux: Runtime disable is deprecated, use selinux=0 on the kernel cmdline.\n");
+
if (count >= PAGE_SIZE)
return -ENOMEM;
@@ -305,10 +313,10 @@
goto out;
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u ses=%u"
- " enabled=%d old-enabled=%d lsm=selinux res=1",
+ " enabled=0 old-enabled=1 lsm=selinux res=1",
enforcing, enforcing,
from_kuid(&init_user_ns, audit_get_loginuid(current)),
- audit_get_sessionid(current), 0, 1);
+ audit_get_sessionid(current));
}
length = count;
@@ -341,13 +349,23 @@
};
/* declaration for sel_write_load */
-static int sel_make_bools(struct selinux_fs_info *fsi);
-static int sel_make_classes(struct selinux_fs_info *fsi);
-static int sel_make_policycap(struct selinux_fs_info *fsi);
+static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
+ unsigned int *bool_num, char ***bool_pending_names,
+ unsigned int **bool_pending_values);
+static int sel_make_classes(struct selinux_policy *newpolicy,
+ struct dentry *class_dir,
+ unsigned long *last_class_ino);
/* declaration for sel_make_class_dirs */
static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
unsigned long *ino);
+
+/* declaration for sel_make_policy_nodes */
+static struct dentry *sel_make_disconnected_dir(struct super_block *sb,
+ unsigned long *ino);
+
+/* declaration for sel_make_policy_nodes */
+static void sel_remove_entries(struct dentry *de);
static ssize_t sel_read_mls(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
@@ -380,7 +398,7 @@
BUG_ON(filp->private_data);
- mutex_lock(&fsi->mutex);
+ mutex_lock(&fsi->state->policy_mutex);
rc = avc_has_perm(&selinux_state,
current_sid(), SECINITSID_SECURITY,
@@ -397,25 +415,25 @@
if (!plm)
goto err;
- if (i_size_read(inode) != security_policydb_len(state)) {
- inode_lock(inode);
- i_size_write(inode, security_policydb_len(state));
- inode_unlock(inode);
- }
-
rc = security_read_policy(state, &plm->data, &plm->len);
if (rc)
goto err;
+
+ if ((size_t)i_size_read(inode) != plm->len) {
+ inode_lock(inode);
+ i_size_write(inode, plm->len);
+ inode_unlock(inode);
+ }
fsi->policy_opened = 1;
filp->private_data = plm;
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
return 0;
err:
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
if (plm)
vfree(plm->data);
@@ -503,29 +521,94 @@
.llseek = generic_file_llseek,
};
-static int sel_make_policy_nodes(struct selinux_fs_info *fsi)
+static void sel_remove_old_bool_data(unsigned int bool_num, char **bool_names,
+ unsigned int *bool_values)
{
- int ret;
+ u32 i;
- ret = sel_make_bools(fsi);
+ /* bool_dir cleanup */
+ for (i = 0; i < bool_num; i++)
+ kfree(bool_names[i]);
+ kfree(bool_names);
+ kfree(bool_values);
+}
+
+static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
+ struct selinux_policy *newpolicy)
+{
+ int ret = 0;
+ struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir, *old_dentry;
+ unsigned int tmp_bool_num, old_bool_num;
+ char **tmp_bool_names, **old_bool_names;
+ unsigned int *tmp_bool_values, *old_bool_values;
+ unsigned long tmp_ino = fsi->last_ino; /* Don't increment last_ino in this function */
+
+ tmp_parent = sel_make_disconnected_dir(fsi->sb, &tmp_ino);
+ if (IS_ERR(tmp_parent))
+ return PTR_ERR(tmp_parent);
+
+ tmp_ino = fsi->bool_dir->d_inode->i_ino - 1; /* sel_make_dir will increment and set */
+ tmp_bool_dir = sel_make_dir(tmp_parent, BOOL_DIR_NAME, &tmp_ino);
+ if (IS_ERR(tmp_bool_dir)) {
+ ret = PTR_ERR(tmp_bool_dir);
+ goto out;
+ }
+
+ tmp_ino = fsi->class_dir->d_inode->i_ino - 1; /* sel_make_dir will increment and set */
+ tmp_class_dir = sel_make_dir(tmp_parent, CLASS_DIR_NAME, &tmp_ino);
+ if (IS_ERR(tmp_class_dir)) {
+ ret = PTR_ERR(tmp_class_dir);
+ goto out;
+ }
+
+ ret = sel_make_bools(newpolicy, tmp_bool_dir, &tmp_bool_num,
+ &tmp_bool_names, &tmp_bool_values);
if (ret) {
pr_err("SELinux: failed to load policy booleans\n");
- return ret;
+ goto out;
}
- ret = sel_make_classes(fsi);
+ ret = sel_make_classes(newpolicy, tmp_class_dir,
+ &fsi->last_class_ino);
if (ret) {
pr_err("SELinux: failed to load policy classes\n");
- return ret;
+ goto out;
}
- ret = sel_make_policycap(fsi);
- if (ret) {
- pr_err("SELinux: failed to load policy capabilities\n");
- return ret;
- }
+ /* booleans */
+ old_dentry = fsi->bool_dir;
+ lock_rename(tmp_bool_dir, old_dentry);
+ d_exchange(tmp_bool_dir, fsi->bool_dir);
- return 0;
+ old_bool_num = fsi->bool_num;
+ old_bool_names = fsi->bool_pending_names;
+ old_bool_values = fsi->bool_pending_values;
+
+ fsi->bool_num = tmp_bool_num;
+ fsi->bool_pending_names = tmp_bool_names;
+ fsi->bool_pending_values = tmp_bool_values;
+
+ sel_remove_old_bool_data(old_bool_num, old_bool_names, old_bool_values);
+
+ fsi->bool_dir = tmp_bool_dir;
+ unlock_rename(tmp_bool_dir, old_dentry);
+
+ /* classes */
+ old_dentry = fsi->class_dir;
+ lock_rename(tmp_class_dir, old_dentry);
+ d_exchange(tmp_class_dir, fsi->class_dir);
+ fsi->class_dir = tmp_class_dir;
+ unlock_rename(tmp_class_dir, old_dentry);
+
+out:
+ /* Since the other temporary dirs are children of tmp_parent
+ * this will handle all the cleanup in the case of a failure before
+ * the swapover
+ */
+ sel_remove_entries(tmp_parent);
+ dput(tmp_parent); /* d_genocide() only handles the children */
+
+ return ret;
}
static ssize_t sel_write_load(struct file *file, const char __user *buf,
@@ -533,10 +616,11 @@
{
struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
+ struct selinux_load_state load_state;
ssize_t length;
void *data = NULL;
- mutex_lock(&fsi->mutex);
+ mutex_lock(&fsi->state->policy_mutex);
length = avc_has_perm(&selinux_state,
current_sid(), SECINITSID_SECURITY,
@@ -549,10 +633,6 @@
if (*ppos != 0)
goto out;
- length = -EFBIG;
- if (count > 64 * 1024 * 1024)
- goto out;
-
length = -ENOMEM;
data = vmalloc(count);
if (!data)
@@ -562,25 +642,28 @@
if (copy_from_user(data, buf, count) != 0)
goto out;
- length = security_load_policy(fsi->state, data, count);
+ length = security_load_policy(fsi->state, data, count, &load_state);
if (length) {
pr_warn_ratelimited("SELinux: failed to load policy\n");
goto out;
}
- length = sel_make_policy_nodes(fsi);
- if (length)
- goto out1;
+ length = sel_make_policy_nodes(fsi, load_state.policy);
+ if (length) {
+ selinux_policy_cancel(fsi->state, &load_state);
+ goto out;
+ }
+
+ selinux_policy_commit(fsi->state, &load_state);
length = count;
-out1:
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
"auid=%u ses=%u lsm=selinux res=1",
from_kuid(&init_user_ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
out:
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
vfree(data);
return length;
}
@@ -633,7 +716,8 @@
char tmpbuf[TMPBUFLEN];
ssize_t length;
- length = scnprintf(tmpbuf, TMPBUFLEN, "%u", fsi->state->checkreqprot);
+ length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
+ checkreqprot_get(fsi->state));
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
}
@@ -667,7 +751,15 @@
if (sscanf(page, "%u", &new_value) != 1)
goto out;
- fsi->state->checkreqprot = new_value ? 1 : 0;
+ if (new_value) {
+ char comm[sizeof(current->comm)];
+
+ memcpy(comm, current->comm, sizeof(comm));
+ pr_warn_once("SELinux: %s (%d) set checkreqprot to 1. This is deprecated and will be rejected in a future kernel release.\n",
+ comm, current->pid);
+ }
+
+ checkreqprot_set(fsi->state, (new_value ? 1 : 0));
length = count;
out:
kfree(page);
@@ -1177,7 +1269,7 @@
unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK;
const char *name = filep->f_path.dentry->d_name.name;
- mutex_lock(&fsi->mutex);
+ mutex_lock(&fsi->state->policy_mutex);
ret = -EINVAL;
if (index >= fsi->bool_num || strcmp(name,
@@ -1196,14 +1288,14 @@
}
length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
fsi->bool_pending_values[index]);
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
ret = simple_read_from_buffer(buf, count, ppos, page, length);
out_free:
free_page((unsigned long)page);
return ret;
out_unlock:
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
goto out_free;
}
@@ -1228,7 +1320,7 @@
if (IS_ERR(page))
return PTR_ERR(page);
- mutex_lock(&fsi->mutex);
+ mutex_lock(&fsi->state->policy_mutex);
length = avc_has_perm(&selinux_state,
current_sid(), SECINITSID_SECURITY,
@@ -1253,7 +1345,7 @@
length = count;
out:
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
kfree(page);
return length;
}
@@ -1284,7 +1376,7 @@
if (IS_ERR(page))
return PTR_ERR(page);
- mutex_lock(&fsi->mutex);
+ mutex_lock(&fsi->state->policy_mutex);
length = avc_has_perm(&selinux_state,
current_sid(), SECINITSID_SECURITY,
@@ -1306,7 +1398,7 @@
length = count;
out:
- mutex_unlock(&fsi->mutex);
+ mutex_unlock(&fsi->state->policy_mutex);
kfree(page);
return length;
}
@@ -1322,49 +1414,37 @@
shrink_dcache_parent(de);
}
-#define BOOL_DIR_NAME "booleans"
-
-static int sel_make_bools(struct selinux_fs_info *fsi)
+static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
+ unsigned int *bool_num, char ***bool_pending_names,
+ unsigned int **bool_pending_values)
{
- int i, ret;
+ int ret;
ssize_t len;
struct dentry *dentry = NULL;
- struct dentry *dir = fsi->bool_dir;
struct inode *inode = NULL;
struct inode_security_struct *isec;
char **names = NULL, *page;
- int num;
+ u32 i, num;
int *values = NULL;
u32 sid;
-
- /* remove any existing files */
- for (i = 0; i < fsi->bool_num; i++)
- kfree(fsi->bool_pending_names[i]);
- kfree(fsi->bool_pending_names);
- kfree(fsi->bool_pending_values);
- fsi->bool_num = 0;
- fsi->bool_pending_names = NULL;
- fsi->bool_pending_values = NULL;
-
- sel_remove_entries(dir);
ret = -ENOMEM;
page = (char *)get_zeroed_page(GFP_KERNEL);
if (!page)
goto out;
- ret = security_get_bools(fsi->state, &num, &names, &values);
+ ret = security_get_bools(newpolicy, &num, &names, &values);
if (ret)
goto out;
for (i = 0; i < num; i++) {
ret = -ENOMEM;
- dentry = d_alloc_name(dir, names[i]);
+ dentry = d_alloc_name(bool_dir, names[i]);
if (!dentry)
goto out;
ret = -ENOMEM;
- inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
+ inode = sel_make_inode(bool_dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
if (!inode) {
dput(dentry);
goto out;
@@ -1378,8 +1458,8 @@
goto out;
}
- isec = (struct inode_security_struct *)inode->i_security;
- ret = security_genfs_sid(fsi->state, "selinuxfs", page,
+ isec = selinux_inode(inode);
+ ret = selinux_policy_genfs_sid(newpolicy, "selinuxfs", page,
SECCLASS_FILE, &sid);
if (ret) {
pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
@@ -1393,9 +1473,9 @@
inode->i_ino = i|SEL_BOOL_INO_OFFSET;
d_add(dentry, inode);
}
- fsi->bool_num = num;
- fsi->bool_pending_names = names;
- fsi->bool_pending_values = values;
+ *bool_num = num;
+ *bool_pending_names = names;
+ *bool_pending_values = values;
free_page((unsigned long)page);
return 0;
@@ -1408,7 +1488,7 @@
kfree(names);
}
kfree(values);
- sel_remove_entries(dir);
+ sel_remove_entries(bool_dir);
return ret;
}
@@ -1692,7 +1772,11 @@
for (i = 1; i <= SECINITSID_NUM; i++) {
struct inode *inode;
struct dentry *dentry;
- dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
+ const char *s = security_get_initial_sid_context(i);
+
+ if (!s)
+ continue;
+ dentry = d_alloc_name(dir, s);
if (!dentry)
return -ENOMEM;
@@ -1735,7 +1819,7 @@
{
unsigned long ino = file_inode(file)->i_ino;
char res[TMPBUFLEN];
- ssize_t len = snprintf(res, sizeof(res), "%d", sel_ino_to_class(ino));
+ ssize_t len = scnprintf(res, sizeof(res), "%d", sel_ino_to_class(ino));
return simple_read_from_buffer(buf, count, ppos, res, len);
}
@@ -1749,7 +1833,7 @@
{
unsigned long ino = file_inode(file)->i_ino;
char res[TMPBUFLEN];
- ssize_t len = snprintf(res, sizeof(res), "%d", sel_ino_to_perm(ino));
+ ssize_t len = scnprintf(res, sizeof(res), "%d", sel_ino_to_perm(ino));
return simple_read_from_buffer(buf, count, ppos, res, len);
}
@@ -1778,14 +1862,14 @@
.llseek = generic_file_llseek,
};
-static int sel_make_perm_files(char *objclass, int classvalue,
- struct dentry *dir)
+static int sel_make_perm_files(struct selinux_policy *newpolicy,
+ char *objclass, int classvalue,
+ struct dentry *dir)
{
- struct selinux_fs_info *fsi = dir->d_sb->s_fs_info;
int i, rc, nperms;
char **perms;
- rc = security_get_permissions(fsi->state, objclass, &perms, &nperms);
+ rc = security_get_permissions(newpolicy, objclass, &perms, &nperms);
if (rc)
return rc;
@@ -1818,8 +1902,9 @@
return rc;
}
-static int sel_make_class_dir_entries(char *classname, int index,
- struct dentry *dir)
+static int sel_make_class_dir_entries(struct selinux_policy *newpolicy,
+ char *classname, int index,
+ struct dentry *dir)
{
struct super_block *sb = dir->d_sb;
struct selinux_fs_info *fsi = sb->s_fs_info;
@@ -1845,39 +1930,38 @@
if (IS_ERR(dentry))
return PTR_ERR(dentry);
- rc = sel_make_perm_files(classname, index, dentry);
+ rc = sel_make_perm_files(newpolicy, classname, index, dentry);
return rc;
}
-static int sel_make_classes(struct selinux_fs_info *fsi)
+static int sel_make_classes(struct selinux_policy *newpolicy,
+ struct dentry *class_dir,
+ unsigned long *last_class_ino)
{
int rc, nclasses, i;
char **classes;
- /* delete any existing entries */
- sel_remove_entries(fsi->class_dir);
-
- rc = security_get_classes(fsi->state, &classes, &nclasses);
+ rc = security_get_classes(newpolicy, &classes, &nclasses);
if (rc)
return rc;
/* +2 since classes are 1-indexed */
- fsi->last_class_ino = sel_class_to_ino(nclasses + 2);
+ *last_class_ino = sel_class_to_ino(nclasses + 2);
for (i = 0; i < nclasses; i++) {
struct dentry *class_name_dir;
- class_name_dir = sel_make_dir(fsi->class_dir, classes[i],
- &fsi->last_class_ino);
+ class_name_dir = sel_make_dir(class_dir, classes[i],
+ last_class_ino);
if (IS_ERR(class_name_dir)) {
rc = PTR_ERR(class_name_dir);
goto out;
}
/* i+1 since class values are 1-indexed */
- rc = sel_make_class_dir_entries(classes[i], i + 1,
+ rc = sel_make_class_dir_entries(newpolicy, classes[i], i + 1,
class_name_dir);
if (rc)
goto out;
@@ -1895,8 +1979,6 @@
unsigned int iter;
struct dentry *dentry = NULL;
struct inode *inode = NULL;
-
- sel_remove_entries(fsi->policycap_dir);
for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
if (iter < ARRAY_SIZE(selinux_policycap_names))
@@ -1949,9 +2031,25 @@
return dentry;
}
+static struct dentry *sel_make_disconnected_dir(struct super_block *sb,
+ unsigned long *ino)
+{
+ struct inode *inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
+
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+ inode->i_ino = ++(*ino);
+ /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ inc_nlink(inode);
+ return d_obtain_alias(inode);
+}
+
#define NULL_FILE_NAME "null"
-static int sel_fill_super(struct super_block *sb, void *data, int silent)
+static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
{
struct selinux_fs_info *fsi;
int ret;
@@ -2011,7 +2109,7 @@
}
inode->i_ino = ++fsi->last_ino;
- isec = (struct inode_security_struct *)inode->i_security;
+ isec = selinux_inode(inode);
isec->sid = SECINITSID_DEVNULL;
isec->sclass = SECCLASS_CHR_FILE;
isec->initialized = LABEL_INITIALIZED;
@@ -2026,6 +2124,8 @@
}
ret = sel_make_avc_files(dentry);
+ if (ret)
+ goto err;
dentry = sel_make_dir(sb->s_root, "ss", &fsi->last_ino);
if (IS_ERR(dentry)) {
@@ -2047,14 +2147,14 @@
if (ret)
goto err;
- fsi->class_dir = sel_make_dir(sb->s_root, "class", &fsi->last_ino);
+ fsi->class_dir = sel_make_dir(sb->s_root, CLASS_DIR_NAME, &fsi->last_ino);
if (IS_ERR(fsi->class_dir)) {
ret = PTR_ERR(fsi->class_dir);
fsi->class_dir = NULL;
goto err;
}
- fsi->policycap_dir = sel_make_dir(sb->s_root, "policy_capabilities",
+ fsi->policycap_dir = sel_make_dir(sb->s_root, POLICYCAP_DIR_NAME,
&fsi->last_ino);
if (IS_ERR(fsi->policycap_dir)) {
ret = PTR_ERR(fsi->policycap_dir);
@@ -2062,9 +2162,12 @@
goto err;
}
- ret = sel_make_policy_nodes(fsi);
- if (ret)
+ ret = sel_make_policycap(fsi);
+ if (ret) {
+ pr_err("SELinux: failed to load policy capabilities\n");
goto err;
+ }
+
return 0;
err:
pr_err("SELinux: %s: failed while creating inodes\n",
@@ -2075,10 +2178,19 @@
return ret;
}
-static struct dentry *sel_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+static int sel_get_tree(struct fs_context *fc)
{
- return mount_single(fs_type, flags, data, sel_fill_super);
+ return get_tree_single(fc, sel_fill_super);
+}
+
+static const struct fs_context_operations sel_context_ops = {
+ .get_tree = sel_get_tree,
+};
+
+static int sel_init_fs_context(struct fs_context *fc)
+{
+ fc->ops = &sel_context_ops;
+ return 0;
}
static void sel_kill_sb(struct super_block *sb)
@@ -2089,7 +2201,7 @@
static struct file_system_type sel_fs_type = {
.name = "selinuxfs",
- .mount = sel_mount,
+ .init_fs_context = sel_init_fs_context,
.kill_sb = sel_kill_sb,
};
@@ -2102,7 +2214,7 @@
sizeof(NULL_FILE_NAME)-1);
int err;
- if (!selinux_enabled)
+ if (!selinux_enabled_boot)
return 0;
err = sysfs_create_mount_point(fs_kobj, "selinux");
--
Gitblit v1.6.2