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
Show 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);
...
@@ -1907,6 +1907,11 @@ extern int register_security (struct security_operations *ops);
extern
int
unregister_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_reg_security
(
const
char
*
name
,
struct
security_operations
*
ops
);
extern
int
mod_unreg_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 */
#else
/* CONFIG_SECURITY */
...
...
security/Kconfig
View file @
ddbf9ef3
...
@@ -35,6 +35,7 @@ config KEYS_DEBUG_PROC_KEYS
...
@@ -35,6 +35,7 @@ config KEYS_DEBUG_PROC_KEYS
config SECURITY
config SECURITY
bool "Enable different security models"
bool "Enable different security models"
depends on SYSFS
help
help
This allows you to choose different security modules to be
This allows you to choose different security modules to be
configured into your kernel.
configured into your kernel.
...
...
security/Makefile
View file @
ddbf9ef3
...
@@ -11,7 +11,7 @@ obj-y += commoncap.o
...
@@ -11,7 +11,7 @@ obj-y += commoncap.o
endif
endif
# Object file lists
# 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.
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX)
+=
selinux/built-in.o
obj-$(CONFIG_SECURITY_SELINUX)
+=
selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES)
+=
commoncap.o capability.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 "
...
@@ -118,69 +118,6 @@ MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
} \
} \
} while (0)
} 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.
* The actual security level. Ranges between -1 and 2 inclusive.
*/
*/
...
@@ -212,97 +149,44 @@ static int seclvl_sanity(int reqlvl)
...
@@ -212,97 +149,44 @@ static int seclvl_sanity(int reqlvl)
return
0
;
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:
* security level advancement rules:
* Valid levels are -1 through 2, inclusive.
* Valid levels are -1 through 2, inclusive.
* From -1, stuck. [ in case compiled into kernel ]
* From -1, stuck. [ in case compiled into kernel ]
* From 0 or above, can only increment.
* 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
)
{
int
ret
;
seclvl_printk
(
1
,
KERN_WARNING
,
"Cannot advance to seclvl "
int
newlvl
=
(
int
)
val
;
"[%d]
\n
"
,
newlvl
);
return
-
EINVAL
;
ret
=
seclvl_sanity
(
newlvl
);
}
if
(
ret
)
return
;
if
(
newlvl
>
2
)
{
if
(
newlvl
>
2
)
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Cannot advance to seclvl "
seclvl_printk
(
1
,
KERN_WARNING
,
"Cannot advance to seclvl "
"[%d]
\n
"
,
newlvl
);
"[%d]
\n
"
,
newlvl
);
return
-
EINVAL
;
return
;
}
}
if
(
seclvl
==
-
1
)
{
if
(
seclvl
==
-
1
)
{
seclvl_printk
(
1
,
KERN_WARNING
,
"Not allowed to advance to "
seclvl_printk
(
1
,
KERN_WARNING
,
"Not allowed to advance to "
"seclvl [%d]
\n
"
,
seclvl
);
"seclvl [%d]
\n
"
,
seclvl
);
return
-
EPERM
;
return
;
}
}
seclvl
=
newlvl
;
seclvl
=
newlvl
;
/* would it be more "correct" to set *data? */
return
0
;
return
;
}
}
/**
static
u64
seclvl_int_get
(
void
*
data
)
* 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
)
{
{
unsigned
long
val
;
return
*
(
int
*
)
data
;
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
;
}
}
/* Generate sysfs_attr_seclvl */
DEFINE_SIMPLE_ATTRIBUTE
(
seclvl_file_ops
,
seclvl_int_get
,
do_seclvl_advance
,
"%lld
\n
"
);
static
struct
seclvl_attribute
sysfs_attr_seclvl
=
__ATTR
(
seclvl
,
(
S_IFREG
|
S_IRUGO
|
S_IWUSR
),
seclvl_read_file
,
seclvl_write_file
);
static
unsigned
char
hashedPassword
[
SHA1_DIGEST_SIZE
];
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.
* 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)
...
@@ -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.
* object. It hashes the password and compares the hashed results.
*/
*/
static
ssize_t
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
;
int
i
;
unsigned
char
tmp
[
SHA1_DIGEST_SIZE
];
unsigned
char
tmp
[
SHA1_DIGEST_SIZE
];
char
*
page
;
int
rc
;
int
rc
;
int
len
;
int
len
;
if
(
!*
passwd
&&
!*
sha1_passwd
)
{
if
(
!*
passwd
&&
!*
sha1_passwd
)
{
seclvl_printk
(
0
,
KERN_ERR
,
"Attempt to password-unlock the "
seclvl_printk
(
0
,
KERN_ERR
,
"Attempt to password-unlock the "
"seclvl module, but neither a plain text "
"seclvl module, but neither a plain text "
...
@@ -363,13 +250,26 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
...
@@ -363,13 +250,26 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
"maintainer about this event.
\n
"
);
"maintainer about this event.
\n
"
);
return
-
EINVAL
;
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 */
/* ``echo "secret" > seclvl/passwd'' includes a newline */
if
(
buff
[
len
-
1
]
==
'\n'
)
{
if
(
page
[
len
-
1
]
==
'\n'
)
{
len
--
;
len
--
;
}
}
/* Hash the password, then compare the hashed values */
/* 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 = "
seclvl_printk
(
0
,
KERN_ERR
,
"Error hashing password: rc = "
"[%d]
\n
"
,
rc
);
"[%d]
\n
"
,
rc
);
return
rc
;
return
rc
;
...
@@ -382,13 +282,16 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
...
@@ -382,13 +282,16 @@ seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
seclvl_printk
(
0
,
KERN_INFO
,
seclvl_printk
(
0
,
KERN_INFO
,
"Password accepted; seclvl reduced to 0.
\n
"
);
"Password accepted; seclvl reduced to 0.
\n
"
);
seclvl
=
0
;
seclvl
=
0
;
return
count
;
len
=
count
;
out:
free_page
((
unsigned
long
)
page
);
return
len
;
}
}
/* Generate sysfs_attr_passwd */
static
struct
file_operations
passwd_file_ops
=
{
static
struct
seclvl_attribute
sysfs_attr_passwd
=
.
write
=
passwd_write_file
,
__ATTR
(
passwd
,
(
S_IFREG
|
S_IRUGO
|
S_IWUSR
),
seclvl_read_passwd
,
};
seclvl_write_passwd
);
/**
/**
* Explicitely disallow ptrace'ing the init process.
* Explicitely disallow ptrace'ing the init process.
...
@@ -647,22 +550,34 @@ static int processPassword(void)
...
@@ -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
;
dir_ino
=
securityfs_create_dir
(
"seclvl"
,
NULL
);
if
((
rc
=
subsystem_register
(
&
seclvl_subsys
)))
{
if
(
!
dir_ino
)
seclvl_printk
(
0
,
KERN_WARNING
,
return
-
EFAULT
;
"Error [%d] registering seclvl subsystem
\n
"
,
rc
);
return
rc
;
seclvl_ino
=
securityfs_create_file
(
"seclvl"
,
S_IRUGO
|
S_IWUSR
,
}
dir_ino
,
&
seclvl
,
&
seclvl_file_ops
);
sysfs_create_file
(
&
seclvl_subsys
.
kset
.
kobj
,
&
sysfs_attr_seclvl
.
attr
);
if
(
!
seclvl_ino
)
goto
out_deldir
;
if
(
*
passwd
||
*
sha1_passwd
)
{
if
(
*
passwd
||
*
sha1_passwd
)
{
sysfs_create_file
(
&
seclvl_subsys
.
kset
.
kobj
,
passwd_ino
=
securityfs_create_file
(
"passwd"
,
S_IRUGO
|
S_IWUSR
,
&
sysfs_attr_passwd
.
attr
);
dir_ino
,
NULL
,
&
passwd_file_ops
);
if
(
!
passwd_ino
)
goto
out_delf
;
}
}
return
0
;
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)
...
@@ -677,8 +592,6 @@ static int __init seclvl_init(void)
rc
=
-
EINVAL
;
rc
=
-
EINVAL
;
goto
exit
;
goto
exit
;
}
}
sysfs_attr_seclvl
.
attr
.
owner
=
THIS_MODULE
;
sysfs_attr_passwd
.
attr
.
owner
=
THIS_MODULE
;
if
(
initlvl
<
-
1
||
initlvl
>
2
)
{
if
(
initlvl
<
-
1
||
initlvl
>
2
)
{
seclvl_printk
(
0
,
KERN_ERR
,
"Error: bad initial securelevel "
seclvl_printk
(
0
,
KERN_ERR
,
"Error: bad initial securelevel "
"[%d].
\n
"
,
initlvl
);
"[%d].
\n
"
,
initlvl
);
...
@@ -706,7 +619,7 @@ static int __init seclvl_init(void)
...
@@ -706,7 +619,7 @@ static int __init seclvl_init(void)
}
/* if primary module registered */
}
/* if primary module registered */
secondary
=
1
;
secondary
=
1
;
}
/* if we registered ourselves with the security framework */
}
/* 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
"
);
seclvl_printk
(
0
,
KERN_ERR
,
"Error registering with sysfs
\n
"
);
goto
exit
;
goto
exit
;
}
}
...
@@ -724,12 +637,11 @@ static int __init seclvl_init(void)
...
@@ -724,12 +637,11 @@ static int __init seclvl_init(void)
*/
*/
static
void
__exit
seclvl_exit
(
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
)
{
if
(
*
passwd
||
*
sha1_passwd
)
{
sysfs_remove_file
(
&
seclvl_subsys
.
kset
.
kobj
,
securityfs_remove
(
passwd_ino
);
&
sysfs_attr_passwd
.
attr
);
}
}
s
ubsystem_unregister
(
&
seclvl_subsys
);
s
ecurityfs_remove
(
dir_ino
);
if
(
secondary
==
1
)
{
if
(
secondary
==
1
)
{
mod_unreg_security
(
MY_NAME
,
&
seclvl_ops
);
mod_unreg_security
(
MY_NAME
,
&
seclvl_ops
);
}
else
if
(
unregister_security
(
&
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