Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
ddbf9ef3
Commit
ddbf9ef3
authored
Sep 13, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/chrisw/lsm-2.6
parents
5d54e69c
2c40579b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
424 additions
and
159 deletions
+424
-159
include/linux/security.h
include/linux/security.h
+5
-0
security/Kconfig
security/Kconfig
+1
-0
security/Makefile
security/Makefile
+1
-1
security/inode.c
security/inode.c
+347
-0
security/seclvl.c
security/seclvl.c
+70
-158
No files found.
include/linux/security.h
View file @
ddbf9ef3
...
...
@@ -1907,6 +1907,11 @@ extern int register_security (struct security_operations *ops);
extern
int
unregister_security
(
struct
security_operations
*
ops
);
extern
int
mod_reg_security
(
const
char
*
name
,
struct
security_operations
*
ops
);
extern
int
mod_unreg_security
(
const
char
*
name
,
struct
security_operations
*
ops
);
extern
struct
dentry
*
securityfs_create_file
(
const
char
*
name
,
mode_t
mode
,
struct
dentry
*
parent
,
void
*
data
,
struct
file_operations
*
fops
);
extern
struct
dentry
*
securityfs_create_dir
(
const
char
*
name
,
struct
dentry
*
parent
);
extern
void
securityfs_remove
(
struct
dentry
*
dentry
);
#else
/* CONFIG_SECURITY */
...
...
security/Kconfig
View file @
ddbf9ef3
...
...
@@ -35,6 +35,7 @@ config KEYS_DEBUG_PROC_KEYS
config SECURITY
bool "Enable different security models"
depends on SYSFS
help
This allows you to choose different security modules to be
configured into your kernel.
...
...
security/Makefile
View file @
ddbf9ef3
...
...
@@ -11,7 +11,7 @@ obj-y += commoncap.o
endif
# Object file lists
obj-$(CONFIG_SECURITY)
+=
security.o dummy.o
obj-$(CONFIG_SECURITY)
+=
security.o dummy.o
inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX)
+=
selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES)
+=
commoncap.o capability.o
...
...
security/inode.c
0 → 100644
View file @
ddbf9ef3
/*
* inode.c - securityfs
*
* Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* Based on fs/debugfs/inode.c which had the following copyright notice:
* Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2004 IBM Inc.
*/
/* #define DEBUG */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/namei.h>
#include <linux/security.h>
#define SECURITYFS_MAGIC 0x73636673
static
struct
vfsmount
*
mount
;
static
int
mount_count
;
/*
* TODO:
* I think I can get rid of these default_file_ops, but not quite sure...
*/
static
ssize_t
default_read_file
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
return
0
;
}
static
ssize_t
default_write_file
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
return
count
;
}
static
int
default_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
if
(
inode
->
u
.
generic_ip
)
file
->
private_data
=
inode
->
u
.
generic_ip
;
return
0
;
}
static
struct
file_operations
default_file_ops
=
{
.
read
=
default_read_file
,
.
write
=
default_write_file
,
.
open
=
default_open
,
};
static
struct
inode
*
get_inode
(
struct
super_block
*
sb
,
int
mode
,
dev_t
dev
)
{
struct
inode
*
inode
=
new_inode
(
sb
);
if
(
inode
)
{
inode
->
i_mode
=
mode
;
inode
->
i_uid
=
0
;
inode
->
i_gid
=
0
;
inode
->
i_blksize
=
PAGE_CACHE_SIZE
;
inode
->
i_blocks
=
0
;
inode
->
i_atime
=
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
switch
(
mode
&
S_IFMT
)
{
default:
init_special_inode
(
inode
,
mode
,
dev
);
break
;
case
S_IFREG
:
inode
->
i_fop
=
&
default_file_ops
;
break
;
case
S_IFDIR
:
inode
->
i_op
=
&
simple_dir_inode_operations
;
inode
->
i_fop
=
&
simple_dir_operations
;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inode
->
i_nlink
++
;
break
;
}
}
return
inode
;
}
/* SMP-safe */
static
int
mknod
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
int
mode
,
dev_t
dev
)
{
struct
inode
*
inode
;
int
error
=
-
EPERM
;
if
(
dentry
->
d_inode
)
return
-
EEXIST
;
inode
=
get_inode
(
dir
->
i_sb
,
mode
,
dev
);
if
(
inode
)
{
d_instantiate
(
dentry
,
inode
);
dget
(
dentry
);
error
=
0
;
}
return
error
;
}
static
int
mkdir
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
int
mode
)
{
int
res
;
mode
=
(
mode
&
(
S_IRWXUGO
|
S_ISVTX
))
|
S_IFDIR
;
res
=
mknod
(
dir
,
dentry
,
mode
,
0
);
if
(
!
res
)
dir
->
i_nlink
++
;
return
res
;
}
static
int
create
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
int
mode
)
{
mode
=
(
mode
&
S_IALLUGO
)
|
S_IFREG
;
return
mknod
(
dir
,
dentry
,
mode
,
0
);
}
static
inline
int
positive
(
struct
dentry
*
dentry
)
{
return
dentry
->
d_inode
&&
!
d_unhashed
(
dentry
);
}
static
int
fill_super
(
struct
super_block
*
sb
,
void
*
data
,
int
silent
)
{
static
struct
tree_descr
files
[]
=
{{
""
}};
return
simple_fill_super
(
sb
,
SECURITYFS_MAGIC
,
files
);
}
static
struct
super_block
*
get_sb
(
struct
file_system_type
*
fs_type
,
int
flags
,
const
char
*
dev_name
,
void
*
data
)
{
return
get_sb_single
(
fs_type
,
flags
,
data
,
fill_super
);
}
static
struct
file_system_type
fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"securityfs"
,
.
get_sb
=
get_sb
,
.
kill_sb
=
kill_litter_super
,
};
static
int
create_by_name
(
const
char
*
name
,
mode_t
mode
,
struct
dentry
*
parent
,
struct
dentry
**
dentry
)
{
int
error
=
0
;
*
dentry
=
NULL
;
/* If the parent is not specified, we create it in the root.
* We need the root dentry to do this, which is in the super
* block. A pointer to that is in the struct vfsmount that we
* have around.
*/
if
(
!
parent
)
{
if
(
mount
&&
mount
->
mnt_sb
)
{
parent
=
mount
->
mnt_sb
->
s_root
;
}
}
if
(
!
parent
)
{
pr_debug
(
"securityfs: Ah! can not find a parent!
\n
"
);
return
-
EFAULT
;
}
down
(
&
parent
->
d_inode
->
i_sem
);
*
dentry
=
lookup_one_len
(
name
,
parent
,
strlen
(
name
));
if
(
!
IS_ERR
(
dentry
))
{
if
((
mode
&
S_IFMT
)
==
S_IFDIR
)
error
=
mkdir
(
parent
->
d_inode
,
*
dentry
,
mode
);
else
error
=
create
(
parent
->
d_inode
,
*
dentry
,
mode
);
}
else
error
=
PTR_ERR
(
dentry
);
up
(
&
parent
->
d_inode
->
i_sem
);
return
error
;
}
/**
* securityfs_create_file - create a file in the securityfs filesystem
*
* @name: a pointer to a string containing the name of the file to create.
* @mode: the permission that the file should have
* @parent: a pointer to the parent dentry for this file. This should be a
* directory dentry if set. If this paramater is NULL, then the
* file will be created in the root of the securityfs filesystem.
* @data: a pointer to something that the caller will want to get to later
* on. The inode.u.generic_ip pointer will point to this value on
* the open() call.
* @fops: a pointer to a struct file_operations that should be used for
* this file.
*
* This is the basic "create a file" function for securityfs. It allows for a
* wide range of flexibility in createing a file, or a directory (if you
* want to create a directory, the securityfs_create_dir() function is
* recommended to be used instead.)
*
* This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the securityfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, NULL will be returned.
*
* If securityfs is not enabled in the kernel, the value -ENODEV will be
* returned. It is not wise to check for this value, but rather, check for
* NULL or !NULL instead as to eliminate the need for #ifdef in the calling
* code.
*/
struct
dentry
*
securityfs_create_file
(
const
char
*
name
,
mode_t
mode
,
struct
dentry
*
parent
,
void
*
data
,
struct
file_operations
*
fops
)
{
struct
dentry
*
dentry
=
NULL
;
int
error
;
pr_debug
(
"securityfs: creating file '%s'
\n
"
,
name
);
error
=
simple_pin_fs
(
"securityfs"
,
&
mount
,
&
mount_count
);
if
(
error
)
{
dentry
=
ERR_PTR
(
error
);
goto
exit
;
}
error
=
create_by_name
(
name
,
mode
,
parent
,
&
dentry
);
if
(
error
)
{
dentry
=
ERR_PTR
(
error
);
simple_release_fs
(
&
mount
,
&
mount_count
);
goto
exit
;
}
if
(
dentry
->
d_inode
)
{
if
(
fops
)
dentry
->
d_inode
->
i_fop
=
fops
;
if
(
data
)
dentry
->
d_inode
->
u
.
generic_ip
=
data
;
}
exit:
return
dentry
;
}
EXPORT_SYMBOL_GPL
(
securityfs_create_file
);
/**
* securityfs_create_dir - create a directory in the securityfs filesystem
*
* @name: a pointer to a string containing the name of the directory to
* create.
* @parent: a pointer to the parent dentry for this file. This should be a
* directory dentry if set. If this paramater is NULL, then the
* directory will be created in the root of the securityfs filesystem.
*
* This function creates a directory in securityfs with the given name.
*
* This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the securityfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, NULL will be returned.
*
* If securityfs is not enabled in the kernel, the value -ENODEV will be
* returned. It is not wise to check for this value, but rather, check for
* NULL or !NULL instead as to eliminate the need for #ifdef in the calling
* code.
*/
struct
dentry
*
securityfs_create_dir
(
const
char
*
name
,
struct
dentry
*
parent
)
{
return
securityfs_create_file
(
name
,
S_IFDIR
|
S_IRWXU
|
S_IRUGO
|
S_IXUGO
,
parent
,
NULL
,
NULL
);
}
EXPORT_SYMBOL_GPL
(
securityfs_create_dir
);
/**
* securityfs_remove - removes a file or directory from the securityfs filesystem
*
* @dentry: a pointer to a the dentry of the file or directory to be
* removed.
*
* This function removes a file or directory in securityfs that was previously
* created with a call to another securityfs function (like
* securityfs_create_file() or variants thereof.)
*
* This function is required to be called in order for the file to be
* removed, no automatic cleanup of files will happen when a module is
* removed, you are responsible here.
*/
void
securityfs_remove
(
struct
dentry
*
dentry
)
{
struct
dentry
*
parent
;
if
(
!
dentry
)
return
;
parent
=
dentry
->
d_parent
;
if
(
!
parent
||
!
parent
->
d_inode
)
return
;
down
(
&
parent
->
d_inode
->
i_sem
);
if
(
positive
(
dentry
))
{
if
(
dentry
->
d_inode
)
{
if
(
S_ISDIR
(
dentry
->
d_inode
->
i_mode
))
simple_rmdir
(
parent
->
d_inode
,
dentry
);
else
simple_unlink
(
parent
->
d_inode
,
dentry
);
dput
(
dentry
);
}
}
up
(
&
parent
->
d_inode
->
i_sem
);
simple_release_fs
(
&
mount
,
&
mount_count
);
}
EXPORT_SYMBOL_GPL
(
securityfs_remove
);
static
decl_subsys
(
security
,
NULL
,
NULL
);
static
int
__init
securityfs_init
(
void
)
{
int
retval
;
kset_set_kset_s
(
&
security_subsys
,
kernel_subsys
);
retval
=
subsystem_register
(
&
security_subsys
);
if
(
retval
)
return
retval
;
retval
=
register_filesystem
(
&
fs_type
);
if
(
retval
)
subsystem_unregister
(
&
security_subsys
);
return
retval
;
}
static
void
__exit
securityfs_exit
(
void
)
{
simple_release_fs
(
&
mount
,
&
mount_count
);
unregister_filesystem
(
&
fs_type
);
subsystem_unregister
(
&
security_subsys
);
}
core_initcall
(
securityfs_init
);
module_exit
(
securityfs_exit
);
MODULE_LICENSE
(
"GPL"
);
security/seclvl.c
View file @
ddbf9ef3
...
...
@@ -118,69 +118,6 @@ MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
} \
} while (0)
/**
* kobject stuff
*/
struct
subsystem
seclvl_subsys
;
struct
seclvl_obj
{
char
*
name
;
struct
list_head
slot_list
;
struct
kobject
kobj
;
};
/**
* There is a seclvl_attribute struct for each file in sysfs.
*
* In our case, we have one of these structs for "passwd" and another
* for "seclvl".
*/
struct
seclvl_attribute
{
struct
attribute
attr
;
ssize_t
(
*
show
)
(
struct
seclvl_obj
*
,
char
*
);
ssize_t
(
*
store
)
(
struct
seclvl_obj
*
,
const
char
*
,
size_t
);
};
/**
* When this function is called, one of the files in sysfs is being
* written to. attribute->store is a function pointer to whatever the
* struct seclvl_attribute store function pointer points to. It is
* unique for "passwd" and "seclvl".
*/
static
ssize_t
seclvl_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
len
)
{
struct
seclvl_obj
*
obj
=
container_of
(
kobj
,
struct
seclvl_obj
,
kobj
);
struct
seclvl_attribute
*
attribute
=
container_of
(
attr
,
struct
seclvl_attribute
,
attr
);
return
attribute
->
store
?
attribute
->
store
(
obj
,
buf
,
len
)
:
-
EIO
;
}
static
ssize_t
seclvl_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
seclvl_obj
*
obj
=
container_of
(
kobj
,
struct
seclvl_obj
,
kobj
);
struct
seclvl_attribute
*
attribute
=
container_of
(
attr
,
struct
seclvl_attribute
,
attr
);
return
attribute
->
show
?
attribute
->
show
(
obj
,
buf
)
:
-
EIO
;
}
/**
* Callback function pointers for show and store
*/
static
struct
sysfs_ops
seclvlfs_sysfs_ops
=
{
.
show
=
seclvl_attr_show
,
.
store
=
seclvl_attr_store
,
};
static
struct
kobj_type
seclvl_ktype
=
{
.
sysfs_ops
=
&
seclvlfs_sysfs_ops
};
decl_subsys
(
seclvl
,
&
seclvl_ktype
,
NULL
);
/**
* The actual security level. Ranges between -1 and 2 inclusive.
*/
...
...
@@ -212,97 +149,44 @@ static int seclvl_sanity(int reqlvl)
return
0
;
}
/**
* Called whenever the user reads the sysfs handle to this kernel
* object
*/
static
ssize_t
seclvl_read_file
(
struct
seclvl_obj
*
obj
,
char
*
buff
)
{
return
snprintf
(
buff
,
PAGE_SIZE
,
"%d
\n
"
,
seclvl
);
}
/**
* security level advancement rules:
* Valid levels are -1 through 2, inclusive.
* From -1, stuck. [ in case compiled into kernel ]
* From 0 or above, can only increment.
*/
static
int
do_seclvl_advance
(
int
newlv
l
)
static
void
do_seclvl_advance
(
void
*
data
,
u64
va
l
)
{
if
(
newlvl
<=
seclvl
)
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Cannot advance to seclvl "
"[%d]
\n
"
,
newlvl
);
return
-
EINVAL
;
}
int
ret
;
int
newlvl
=
(
int
)
val
;
ret
=
seclvl_sanity
(
newlvl
);
if
(
ret
)
return
;
if
(
newlvl
>
2
)
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Cannot advance to seclvl "
"[%d]
\n
"
,
newlvl
);
return
-
EINVAL
;
return
;
}
if
(
seclvl
==
-
1
)
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Not allowed to advance to "
"seclvl [%d]
\n
"
,
seclvl
);
return
-
EPERM
;
return
;
}
seclvl
=
newlvl
;
return
0
;
seclvl
=
newlvl
;
/* would it be more "correct" to set *data? */
return
;
}
/**
* Called whenever the user writes to the sysfs handle to this kernel
* object (seclvl/seclvl). It expects a single-digit number.
*/
static
ssize_t
seclvl_write_file
(
struct
seclvl_obj
*
obj
,
const
char
*
buff
,
size_t
count
)
static
u64
seclvl_int_get
(
void
*
data
)
{
unsigned
long
val
;
if
(
count
>
2
||
(
count
==
2
&&
buff
[
1
]
!=
'\n'
))
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Invalid value passed to "
"seclvl: [%s]
\n
"
,
buff
);
return
-
EINVAL
;
}
val
=
buff
[
0
]
-
48
;
if
(
seclvl_sanity
(
val
))
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Illegal secure level "
"requested: [%d]
\n
"
,
(
int
)
val
);
return
-
EPERM
;
}
if
(
do_seclvl_advance
(
val
))
{
seclvl_printk
(
0
,
KERN_ERR
,
"Failure advancing security level "
"to %lu
\n
"
,
val
);
}
return
count
;
return
*
(
int
*
)
data
;
}
/* Generate sysfs_attr_seclvl */
static
struct
seclvl_attribute
sysfs_attr_seclvl
=
__ATTR
(
seclvl
,
(
S_IFREG
|
S_IRUGO
|
S_IWUSR
),
seclvl_read_file
,
seclvl_write_file
);
DEFINE_SIMPLE_ATTRIBUTE
(
seclvl_file_ops
,
seclvl_int_get
,
do_seclvl_advance
,
"%lld
\n
"
);
static
unsigned
char
hashedPassword
[
SHA1_DIGEST_SIZE
];
/**
* Called whenever the user reads the sysfs passwd handle.
*/
static
ssize_t
seclvl_read_passwd
(
struct
seclvl_obj
*
obj
,
char
*
buff
)
{
/* So just how good *is* your password? :-) */
char
tmp
[
3
];
int
i
=
0
;
buff
[
0
]
=
'\0'
;
if
(
hideHash
)
{
/* Security through obscurity */
return
0
;
}
while
(
i
<
SHA1_DIGEST_SIZE
)
{
snprintf
(
tmp
,
3
,
"%02x"
,
hashedPassword
[
i
]);
strncat
(
buff
,
tmp
,
2
);
i
++
;
}
strcat
(
buff
,
"
\n
"
);
return
((
SHA1_DIGEST_SIZE
*
2
)
+
1
);
}
/**
* Converts a block of plaintext of into its SHA1 hashed value.
*
...
...
@@ -347,12 +231,15 @@ plaintext_to_sha1(unsigned char *hash, const char *plaintext, int len)
* object. It hashes the password and compares the hashed results.
*/
static
ssize_t
seclvl_write_passwd
(
struct
seclvl_obj
*
obj
,
const
char
*
buff
,
size_t
count
)
passwd_write_file
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
int
i
;
unsigned
char
tmp
[
SHA1_DIGEST_SIZE
];
char
*
page
;
int
rc
;
int
len
;
if
(
!*
passwd
&&
!*
sha1_passwd
)
{
seclvl_printk
(
0
,
KERN_ERR
,
"Attempt to password-unlock the "
"seclvl module, but neither a plain text "
...
...
@@ -363,13 +250,26 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
"maintainer about this event.
\n
"
);
return
-
EINVAL
;
}
len
=
strlen
(
buff
);
if
(
count
<
0
||
count
>=
PAGE_SIZE
)
return
-
ENOMEM
;
if
(
*
ppos
!=
0
)
{
return
-
EINVAL
;
}
page
=
(
char
*
)
get_zeroed_page
(
GFP_KERNEL
);
if
(
!
page
)
return
-
ENOMEM
;
len
=
-
EFAULT
;
if
(
copy_from_user
(
page
,
buf
,
count
))
goto
out
;
len
=
strlen
(
page
);
/* ``echo "secret" > seclvl/passwd'' includes a newline */
if
(
buff
[
len
-
1
]
==
'\n'
)
{
if
(
page
[
len
-
1
]
==
'\n'
)
{
len
--
;
}
/* Hash the password, then compare the hashed values */
if
((
rc
=
plaintext_to_sha1
(
tmp
,
buff
,
len
)))
{
if
((
rc
=
plaintext_to_sha1
(
tmp
,
page
,
len
)))
{
seclvl_printk
(
0
,
KERN_ERR
,
"Error hashing password: rc = "
"[%d]
\n
"
,
rc
);
return
rc
;
...
...
@@ -382,13 +282,16 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
seclvl_printk
(
0
,
KERN_INFO
,
"Password accepted; seclvl reduced to 0.
\n
"
);
seclvl
=
0
;
return
count
;
len
=
count
;
out:
free_page
((
unsigned
long
)
page
);
return
len
;
}
/* Generate sysfs_attr_passwd */
static
struct
seclvl_attribute
sysfs_attr_passwd
=
__ATTR
(
passwd
,
(
S_IFREG
|
S_IRUGO
|
S_IWUSR
),
seclvl_read_passwd
,
seclvl_write_passwd
);
static
struct
file_operations
passwd_file_ops
=
{
.
write
=
passwd_write_file
,
};
/**
* Explicitely disallow ptrace'ing the init process.
...
...
@@ -647,22 +550,34 @@ static int processPassword(void)
}
/**
*
Sys
fs registrations
*
security
fs registrations
*/
static
int
doSysfsRegistrations
(
void
)
struct
dentry
*
dir_ino
,
*
seclvl_ino
,
*
passwd_ino
;
static
int
seclvlfs_register
(
void
)
{
int
rc
=
0
;
if
((
rc
=
subsystem_register
(
&
seclvl_subsys
)))
{
seclvl_printk
(
0
,
KERN_WARNING
,
"Error [%d] registering seclvl subsystem
\n
"
,
rc
);
return
rc
;
}
sysfs_create_file
(
&
seclvl_subsys
.
kset
.
kobj
,
&
sysfs_attr_seclvl
.
attr
);
dir_ino
=
securityfs_create_dir
(
"seclvl"
,
NULL
);
if
(
!
dir_ino
)
return
-
EFAULT
;
seclvl_ino
=
securityfs_create_file
(
"seclvl"
,
S_IRUGO
|
S_IWUSR
,
dir_ino
,
&
seclvl
,
&
seclvl_file_ops
);
if
(
!
seclvl_ino
)
goto
out_deldir
;
if
(
*
passwd
||
*
sha1_passwd
)
{
sysfs_create_file
(
&
seclvl_subsys
.
kset
.
kobj
,
&
sysfs_attr_passwd
.
attr
);
passwd_ino
=
securityfs_create_file
(
"passwd"
,
S_IRUGO
|
S_IWUSR
,
dir_ino
,
NULL
,
&
passwd_file_ops
);
if
(
!
passwd_ino
)
goto
out_delf
;
}
return
0
;
out_deldir:
securityfs_remove
(
dir_ino
);
out_delf:
securityfs_remove
(
seclvl_ino
);
return
-
EFAULT
;
}
/**
...
...
@@ -677,8 +592,6 @@ static int __init seclvl_init(void)
rc
=
-
EINVAL
;
goto
exit
;
}
sysfs_attr_seclvl
.
attr
.
owner
=
THIS_MODULE
;
sysfs_attr_passwd
.
attr
.
owner
=
THIS_MODULE
;
if
(
initlvl
<
-
1
||
initlvl
>
2
)
{
seclvl_printk
(
0
,
KERN_ERR
,
"Error: bad initial securelevel "
"[%d].
\n
"
,
initlvl
);
...
...
@@ -706,7 +619,7 @@ static int __init seclvl_init(void)
}
/* if primary module registered */
secondary
=
1
;
}
/* if we registered ourselves with the security framework */
if
((
rc
=
doSysfsRegistrations
()))
{
if
((
rc
=
seclvlfs_register
()))
{
seclvl_printk
(
0
,
KERN_ERR
,
"Error registering with sysfs
\n
"
);
goto
exit
;
}
...
...
@@ -724,12 +637,11 @@ static int __init seclvl_init(void)
*/
static
void
__exit
seclvl_exit
(
void
)
{
s
ysfs_remove_file
(
&
seclvl_subsys
.
kset
.
kobj
,
&
sysfs_attr_seclvl
.
attr
);
s
ecurityfs_remove
(
seclvl_ino
);
if
(
*
passwd
||
*
sha1_passwd
)
{
sysfs_remove_file
(
&
seclvl_subsys
.
kset
.
kobj
,
&
sysfs_attr_passwd
.
attr
);
securityfs_remove
(
passwd_ino
);
}
s
ubsystem_unregister
(
&
seclvl_subsys
);
s
ecurityfs_remove
(
dir_ino
);
if
(
secondary
==
1
)
{
mod_unreg_security
(
MY_NAME
,
&
seclvl_ops
);
}
else
if
(
unregister_security
(
&
seclvl_ops
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment