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
Kirill Smelkov
linux
Commits
539c99fd
Commit
539c99fd
authored
May 18, 2010
by
James Morris
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
parents
ba2e1c5f
4d09ec0f
Changes
57
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
1246 additions
and
1061 deletions
+1246
-1061
Documentation/credentials.txt
Documentation/credentials.txt
+5
-9
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+10
-0
drivers/char/tpm/Kconfig
drivers/char/tpm/Kconfig
+4
-2
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.c
+40
-7
drivers/char/tpm/tpm_tis.c
drivers/char/tpm/tpm_tis.c
+21
-19
fs/inode.c
fs/inode.c
+0
-2
fs/namespace.c
fs/namespace.c
+0
-13
include/linux/lsm_audit.h
include/linux/lsm_audit.h
+1
-1
include/linux/security.h
include/linux/security.h
+0
-180
kernel/acct.c
kernel/acct.c
+5
-15
kernel/cred.c
kernel/cred.c
+0
-2
kernel/groups.c
kernel/groups.c
+0
-6
kernel/sys.c
kernel/sys.c
+0
-31
scripts/selinux/genheaders/genheaders.c
scripts/selinux/genheaders/genheaders.c
+1
-1
security/capability.c
security/capability.c
+1
-75
security/commoncap.c
security/commoncap.c
+3
-3
security/device_cgroup.c
security/device_cgroup.c
+1
-1
security/integrity/ima/Kconfig
security/integrity/ima/Kconfig
+2
-3
security/integrity/ima/ima.h
security/integrity/ima/ima.h
+1
-1
security/integrity/ima/ima_audit.c
security/integrity/ima/ima_audit.c
+1
-1
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_crypto.c
+2
-2
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_fs.c
+20
-18
security/integrity/ima/ima_iint.c
security/integrity/ima/ima_iint.c
+3
-3
security/integrity/ima/ima_init.c
security/integrity/ima/ima_init.c
+1
-1
security/integrity/ima/ima_main.c
security/integrity/ima/ima_main.c
+1
-1
security/integrity/ima/ima_policy.c
security/integrity/ima/ima_policy.c
+79
-28
security/integrity/ima/ima_queue.c
security/integrity/ima/ima_queue.c
+2
-2
security/keys/internal.h
security/keys/internal.h
+10
-1
security/keys/key.c
security/keys/key.c
+30
-17
security/keys/keyctl.c
security/keys/keyctl.c
+29
-36
security/keys/keyring.c
security/keys/keyring.c
+160
-113
security/keys/permission.c
security/keys/permission.c
+1
-1
security/keys/proc.c
security/keys/proc.c
+1
-1
security/keys/process_keys.c
security/keys/process_keys.c
+3
-3
security/keys/request_key.c
security/keys/request_key.c
+45
-10
security/lsm_audit.c
security/lsm_audit.c
+1
-1
security/security.c
security/security.c
+3
-72
security/selinux/avc.c
security/selinux/avc.c
+1
-2
security/selinux/hooks.c
security/selinux/hooks.c
+34
-32
security/selinux/include/initial_sid_to_string.h
security/selinux/include/initial_sid_to_string.h
+1
-1
security/selinux/include/netlabel.h
security/selinux/include/netlabel.h
+4
-4
security/selinux/netlabel.c
security/selinux/netlabel.c
+7
-7
security/selinux/netlink.c
security/selinux/netlink.c
+0
-1
security/selinux/nlmsgtab.c
security/selinux/nlmsgtab.c
+0
-1
security/selinux/selinuxfs.c
security/selinux/selinuxfs.c
+22
-22
security/selinux/ss/mls.c
security/selinux/ss/mls.c
+1
-1
security/selinux/ss/policydb.c
security/selinux/ss/policydb.c
+3
-4
security/selinux/ss/services.c
security/selinux/ss/services.c
+28
-21
security/smack/smack_lsm.c
security/smack/smack_lsm.c
+0
-11
security/tomoyo/Makefile
security/tomoyo/Makefile
+1
-1
security/tomoyo/common.c
security/tomoyo/common.c
+113
-44
security/tomoyo/common.h
security/tomoyo/common.h
+111
-10
security/tomoyo/domain.c
security/tomoyo/domain.c
+60
-83
security/tomoyo/file.c
security/tomoyo/file.c
+129
-121
security/tomoyo/gc.c
security/tomoyo/gc.c
+48
-7
security/tomoyo/path_group.c
security/tomoyo/path_group.c
+172
-0
security/tomoyo/realpath.c
security/tomoyo/realpath.c
+24
-6
No files found.
Documentation/credentials.txt
View file @
539c99fd
...
...
@@ -408,9 +408,6 @@ This should be used inside the RCU read lock, as in the following example:
...
}
A function need not get RCU read lock to use __task_cred() if it is holding a
spinlock at the time as this implicitly holds the RCU read lock.
Should it be necessary to hold another task's credentials for a long period of
time, and possibly to sleep whilst doing so, then the caller should get a
reference on them using:
...
...
@@ -426,17 +423,16 @@ credentials, hiding the RCU magic from the caller:
uid_t task_uid(task) Task's real UID
uid_t task_euid(task) Task's effective UID
If the caller is holding a spinlock or the RCU read lock at the time anyway,
then:
If the caller is holding the RCU read lock at the time anyway, then:
__task_cred(task)->uid
__task_cred(task)->euid
should be used instead. Similarly, if multiple aspects of a task's credentials
need to be accessed, RCU read lock
or a spinlock should be used, __task_cred()
called, the result stored in a temporary pointer and then the credential
aspects called from that before dropping the lock. This prevents th
e
potentially expensive
RCU magic from being invoked multiple times.
need to be accessed, RCU read lock
should be used, __task_cred() called, the
result stored in a temporary pointer and then the credential aspects called
from that before dropping the lock. This prevents the potentially expensiv
e
RCU magic from being invoked multiple times.
Should some other single aspect of another task's credentials need to be
accessed, then this can be used:
...
...
Documentation/kernel-parameters.txt
View file @
539c99fd
...
...
@@ -99,6 +99,7 @@ parameter is applicable:
SWSUSP Software suspend (hibernation) is enabled.
SUSPEND System suspend states are enabled.
FTRACE Function tracing enabled.
TPM TPM drivers are enabled.
TS Appropriate touchscreen support is enabled.
UMS USB Mass Storage support is enabled.
USB USB support is enabled.
...
...
@@ -2610,6 +2611,15 @@ and is between 256 and 4096 characters. It is defined in the file
tp720= [HW,PS2]
tpm_suspend_pcr=[HW,TPM]
Format: integer pcr id
Specify that at suspend time, the tpm driver
should extend the specified pcr with zeros,
as a workaround for some chips which fail to
flush the last written pcr on TPM_SaveState.
This will guarantee that all the other pcrs
are saved.
trace_buf_size=nn[KMG]
[FTRACE] will set tracing buffer size.
...
...
drivers/char/tpm/Kconfig
View file @
539c99fd
...
...
@@ -17,14 +17,16 @@ menuconfig TCG_TPM
obtained at: <http://sourceforge.net/projects/trousers>. To
compile this driver as a module, choose M here; the module
will be called tpm. If unsure, say N.
Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
Notes:
1) For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
and CONFIG_PNPACPI.
2) Without ACPI enabled, the BIOS event log won't be accessible,
which is required to validate the PCR 0-7 values.
if TCG_TPM
config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface"
depends on PNP
---help---
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification say Yes and it will be accessible
...
...
drivers/char/tpm/tpm.c
View file @
539c99fd
...
...
@@ -1068,6 +1068,27 @@ void tpm_remove_hardware(struct device *dev)
}
EXPORT_SYMBOL_GPL
(
tpm_remove_hardware
);
#define TPM_ORD_SAVESTATE cpu_to_be32(152)
#define SAVESTATE_RESULT_SIZE 10
static
struct
tpm_input_header
savestate_header
=
{
.
tag
=
TPM_TAG_RQU_COMMAND
,
.
length
=
cpu_to_be32
(
10
),
.
ordinal
=
TPM_ORD_SAVESTATE
};
/* Bug workaround - some TPM's don't flush the most
* recently changed pcr on suspend, so force the flush
* with an extend to the selected _unused_ non-volatile pcr.
*/
static
int
tpm_suspend_pcr
;
static
int
__init
tpm_suspend_setup
(
char
*
str
)
{
get_option
(
&
str
,
&
tpm_suspend_pcr
);
return
1
;
}
__setup
(
"tpm_suspend_pcr="
,
tpm_suspend_setup
);
/*
* We are about to suspend. Save the TPM state
* so that it can be restored.
...
...
@@ -1075,17 +1096,29 @@ EXPORT_SYMBOL_GPL(tpm_remove_hardware);
int
tpm_pm_suspend
(
struct
device
*
dev
,
pm_message_t
pm_state
)
{
struct
tpm_chip
*
chip
=
dev_get_drvdata
(
dev
);
u8
savestate
[]
=
{
0
,
193
,
/* TPM_TAG_RQU_COMMAND */
0
,
0
,
0
,
10
,
/* blob length (in bytes) */
0
,
0
,
0
,
152
/* TPM_ORD_SaveState */
};
struct
tpm_cmd_t
cmd
;
int
rc
;
u8
dummy_hash
[
TPM_DIGEST_SIZE
]
=
{
0
};
if
(
chip
==
NULL
)
return
-
ENODEV
;
tpm_transmit
(
chip
,
savestate
,
sizeof
(
savestate
));
return
0
;
/* for buggy tpm, flush pcrs with extend to selected dummy */
if
(
tpm_suspend_pcr
)
{
cmd
.
header
.
in
=
pcrextend_header
;
cmd
.
params
.
pcrextend_in
.
pcr_idx
=
cpu_to_be32
(
tpm_suspend_pcr
);
memcpy
(
cmd
.
params
.
pcrextend_in
.
hash
,
dummy_hash
,
TPM_DIGEST_SIZE
);
rc
=
transmit_cmd
(
chip
,
&
cmd
,
EXTEND_PCR_RESULT_SIZE
,
"extending dummy pcr before suspend"
);
}
/* now do the actual savestate */
cmd
.
header
.
in
=
savestate_header
;
rc
=
transmit_cmd
(
chip
,
&
cmd
,
SAVESTATE_RESULT_SIZE
,
"sending savestate before suspend"
);
return
rc
;
}
EXPORT_SYMBOL_GPL
(
tpm_pm_suspend
);
...
...
drivers/char/tpm/tpm_tis.c
View file @
539c99fd
...
...
@@ -598,7 +598,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
tpm_remove_hardware
(
chip
->
dev
);
return
rc
;
}
#ifdef CONFIG_PNP
static
int
__devinit
tpm_tis_pnp_init
(
struct
pnp_dev
*
pnp_dev
,
const
struct
pnp_device_id
*
pnp_id
)
{
...
...
@@ -663,7 +663,7 @@ static struct pnp_driver tis_pnp_driver = {
module_param_string
(
hid
,
tpm_pnp_tbl
[
TIS_HID_USR_IDX
].
id
,
sizeof
(
tpm_pnp_tbl
[
TIS_HID_USR_IDX
].
id
),
0444
);
MODULE_PARM_DESC
(
hid
,
"Set additional specific HID for this driver to probe"
);
#endif
static
int
tpm_tis_suspend
(
struct
platform_device
*
dev
,
pm_message_t
msg
)
{
return
tpm_pm_suspend
(
&
dev
->
dev
,
msg
);
...
...
@@ -690,21 +690,21 @@ MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
static
int
__init
init_tis
(
void
)
{
int
rc
;
#ifdef CONFIG_PNP
if
(
!
force
)
return
pnp_register_driver
(
&
tis_pnp_driver
);
#endif
if
(
force
)
{
rc
=
platform_driver_register
(
&
tis_drv
);
if
(
rc
<
0
)
return
rc
;
if
(
IS_ERR
(
pdev
=
platform_device_register_simple
(
"tpm_tis"
,
-
1
,
NULL
,
0
)))
return
PTR_ERR
(
pdev
);
if
((
rc
=
tpm_tis_init
(
&
pdev
->
dev
,
TIS_MEM_BASE
,
TIS_MEM_LEN
,
0
))
!=
0
)
{
platform_device_unregister
(
pdev
);
platform_driver_unregister
(
&
tis_drv
);
}
rc
=
platform_driver_register
(
&
tis_drv
);
if
(
rc
<
0
)
return
rc
;
if
(
IS_ERR
(
pdev
=
platform_device_register_simple
(
"tpm_tis"
,
-
1
,
NULL
,
0
)))
return
PTR_ERR
(
pdev
);
if
((
rc
=
tpm_tis_init
(
&
pdev
->
dev
,
TIS_MEM_BASE
,
TIS_MEM_LEN
,
0
))
!=
0
)
{
platform_device_unregister
(
pdev
);
platform_driver_unregister
(
&
tis_drv
);
}
return
pnp_register_driver
(
&
tis_pnp_driver
);
return
rc
;
}
static
void
__exit
cleanup_tis
(
void
)
...
...
@@ -728,12 +728,14 @@ static void __exit cleanup_tis(void)
list_del
(
&
i
->
list
);
}
spin_unlock
(
&
tis_lock
);
if
(
force
)
{
platform_device_unregister
(
pdev
);
platform_driver_unregister
(
&
tis_drv
);
}
else
#ifdef CONFIG_PNP
if
(
!
force
)
{
pnp_unregister_driver
(
&
tis_pnp_driver
);
return
;
}
#endif
platform_device_unregister
(
pdev
);
platform_driver_unregister
(
&
tis_drv
);
}
module_init
(
init_tis
);
...
...
fs/inode.c
View file @
539c99fd
...
...
@@ -1205,8 +1205,6 @@ void generic_delete_inode(struct inode *inode)
inodes_stat
.
nr_inodes
--
;
spin_unlock
(
&
inode_lock
);
security_inode_delete
(
inode
);
if
(
op
->
delete_inode
)
{
void
(
*
delete
)(
struct
inode
*
)
=
op
->
delete_inode
;
/* Filesystems implementing their own
...
...
fs/namespace.c
View file @
539c99fd
...
...
@@ -628,7 +628,6 @@ void mntput_no_expire(struct vfsmount *mnt)
mnt
->
mnt_pinned
=
0
;
spin_unlock
(
&
vfsmount_lock
);
acct_auto_close_mnt
(
mnt
);
security_sb_umount_close
(
mnt
);
goto
repeat
;
}
}
...
...
@@ -1117,8 +1116,6 @@ static int do_umount(struct vfsmount *mnt, int flags)
retval
=
0
;
}
spin_unlock
(
&
vfsmount_lock
);
if
(
retval
)
security_sb_umount_busy
(
mnt
);
up_write
(
&
namespace_sem
);
release_mounts
(
&
umount_list
);
return
retval
;
...
...
@@ -1435,17 +1432,10 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
if
(
cant_mount
(
path
->
dentry
))
goto
out_unlock
;
err
=
security_sb_check_sb
(
mnt
,
path
);
if
(
err
)
goto
out_unlock
;
err
=
-
ENOENT
;
if
(
!
d_unlinked
(
path
->
dentry
))
err
=
attach_recursive_mnt
(
mnt
,
path
,
NULL
);
out_unlock:
mutex_unlock
(
&
path
->
dentry
->
d_inode
->
i_mutex
);
if
(
!
err
)
security_sb_post_addmount
(
mnt
,
path
);
return
err
;
}
...
...
@@ -1581,8 +1571,6 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
}
up_write
(
&
sb
->
s_umount
);
if
(
!
err
)
{
security_sb_post_remount
(
path
->
mnt
,
flags
,
data
);
spin_lock
(
&
vfsmount_lock
);
touch_mnt_namespace
(
path
->
mnt
->
mnt_ns
);
spin_unlock
(
&
vfsmount_lock
);
...
...
@@ -2277,7 +2265,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
touch_mnt_namespace
(
current
->
nsproxy
->
mnt_ns
);
spin_unlock
(
&
vfsmount_lock
);
chroot_fs_refs
(
&
root
,
&
new
);
security_sb_post_pivotroot
(
&
root
,
&
new
);
error
=
0
;
path_put
(
&
root_parent
);
path_put
(
&
parent_path
);
...
...
include/linux/lsm_audit.h
View file @
539c99fd
...
...
@@ -33,7 +33,7 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_IPC 4
#define LSM_AUDIT_DATA_TASK 5
#define LSM_AUDIT_DATA_KEY 6
#define LSM_AUDIT_
NO_AUDIT
7
#define LSM_AUDIT_
DATA_NONE
7
#define LSM_AUDIT_DATA_KMOD 8
struct
task_struct
*
tsk
;
union
{
...
...
include/linux/security.h
View file @
539c99fd
This diff is collapsed.
Click to expand it.
kernel/acct.c
View file @
539c99fd
...
...
@@ -216,7 +216,6 @@ static int acct_on(char *name)
{
struct
file
*
file
;
struct
vfsmount
*
mnt
;
int
error
;
struct
pid_namespace
*
ns
;
struct
bsd_acct_struct
*
acct
=
NULL
;
...
...
@@ -244,13 +243,6 @@ static int acct_on(char *name)
}
}
error
=
security_acct
(
file
);
if
(
error
)
{
kfree
(
acct
);
filp_close
(
file
,
NULL
);
return
error
;
}
spin_lock
(
&
acct_lock
);
if
(
ns
->
bacct
==
NULL
)
{
ns
->
bacct
=
acct
;
...
...
@@ -281,7 +273,7 @@ static int acct_on(char *name)
*/
SYSCALL_DEFINE1
(
acct
,
const
char
__user
*
,
name
)
{
int
error
;
int
error
=
0
;
if
(
!
capable
(
CAP_SYS_PACCT
))
return
-
EPERM
;
...
...
@@ -299,13 +291,11 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
if
(
acct
==
NULL
)
return
0
;
error
=
security_acct
(
NULL
);
if
(
!
error
)
{
spin_lock
(
&
acct_lock
);
acct_file_reopen
(
acct
,
NULL
,
NULL
);
spin_unlock
(
&
acct_lock
);
}
spin_lock
(
&
acct_lock
);
acct_file_reopen
(
acct
,
NULL
,
NULL
);
spin_unlock
(
&
acct_lock
);
}
return
error
;
}
...
...
kernel/cred.c
View file @
539c99fd
...
...
@@ -523,8 +523,6 @@ int commit_creds(struct cred *new)
#endif
BUG_ON
(
atomic_read
(
&
new
->
usage
)
<
1
);
security_commit_creds
(
new
,
old
);
get_cred
(
new
);
/* we will require a ref for the subj creds too */
/* dumpability changes */
...
...
kernel/groups.c
View file @
539c99fd
...
...
@@ -164,12 +164,6 @@ int groups_search(const struct group_info *group_info, gid_t grp)
*/
int
set_groups
(
struct
cred
*
new
,
struct
group_info
*
group_info
)
{
int
retval
;
retval
=
security_task_setgroups
(
group_info
);
if
(
retval
)
return
retval
;
put_group_info
(
new
->
group_info
);
groups_sort
(
group_info
);
get_group_info
(
group_info
);
...
...
kernel/sys.c
View file @
539c99fd
...
...
@@ -492,10 +492,6 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
return
-
ENOMEM
;
old
=
current_cred
();
retval
=
security_task_setgid
(
rgid
,
egid
,
(
gid_t
)
-
1
,
LSM_SETID_RE
);
if
(
retval
)
goto
error
;
retval
=
-
EPERM
;
if
(
rgid
!=
(
gid_t
)
-
1
)
{
if
(
old
->
gid
==
rgid
||
...
...
@@ -543,10 +539,6 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
return
-
ENOMEM
;
old
=
current_cred
();
retval
=
security_task_setgid
(
gid
,
(
gid_t
)
-
1
,
(
gid_t
)
-
1
,
LSM_SETID_ID
);
if
(
retval
)
goto
error
;
retval
=
-
EPERM
;
if
(
capable
(
CAP_SETGID
))
new
->
gid
=
new
->
egid
=
new
->
sgid
=
new
->
fsgid
=
gid
;
...
...
@@ -610,10 +602,6 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
return
-
ENOMEM
;
old
=
current_cred
();
retval
=
security_task_setuid
(
ruid
,
euid
,
(
uid_t
)
-
1
,
LSM_SETID_RE
);
if
(
retval
)
goto
error
;
retval
=
-
EPERM
;
if
(
ruid
!=
(
uid_t
)
-
1
)
{
new
->
uid
=
ruid
;
...
...
@@ -675,10 +663,6 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
return
-
ENOMEM
;
old
=
current_cred
();
retval
=
security_task_setuid
(
uid
,
(
uid_t
)
-
1
,
(
uid_t
)
-
1
,
LSM_SETID_ID
);
if
(
retval
)
goto
error
;
retval
=
-
EPERM
;
if
(
capable
(
CAP_SETUID
))
{
new
->
suid
=
new
->
uid
=
uid
;
...
...
@@ -719,9 +703,6 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
if
(
!
new
)
return
-
ENOMEM
;
retval
=
security_task_setuid
(
ruid
,
euid
,
suid
,
LSM_SETID_RES
);
if
(
retval
)
goto
error
;
old
=
current_cred
();
retval
=
-
EPERM
;
...
...
@@ -788,10 +769,6 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
return
-
ENOMEM
;
old
=
current_cred
();
retval
=
security_task_setgid
(
rgid
,
egid
,
sgid
,
LSM_SETID_RES
);
if
(
retval
)
goto
error
;
retval
=
-
EPERM
;
if
(
!
capable
(
CAP_SETGID
))
{
if
(
rgid
!=
(
gid_t
)
-
1
&&
rgid
!=
old
->
gid
&&
...
...
@@ -851,9 +828,6 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
old
=
current_cred
();
old_fsuid
=
old
->
fsuid
;
if
(
security_task_setuid
(
uid
,
(
uid_t
)
-
1
,
(
uid_t
)
-
1
,
LSM_SETID_FS
)
<
0
)
goto
error
;
if
(
uid
==
old
->
uid
||
uid
==
old
->
euid
||
uid
==
old
->
suid
||
uid
==
old
->
fsuid
||
capable
(
CAP_SETUID
))
{
...
...
@@ -864,7 +838,6 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
}
}
error:
abort_creds
(
new
);
return
old_fsuid
;
...
...
@@ -888,9 +861,6 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
old
=
current_cred
();
old_fsgid
=
old
->
fsgid
;
if
(
security_task_setgid
(
gid
,
(
gid_t
)
-
1
,
(
gid_t
)
-
1
,
LSM_SETID_FS
))
goto
error
;
if
(
gid
==
old
->
gid
||
gid
==
old
->
egid
||
gid
==
old
->
sgid
||
gid
==
old
->
fsgid
||
capable
(
CAP_SETGID
))
{
...
...
@@ -900,7 +870,6 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
}
}
error:
abort_creds
(
new
);
return
old_fsgid
;
...
...
scripts/selinux/genheaders/genheaders.c
View file @
539c99fd
...
...
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
fprintf
(
fout
,
"
\n
"
);
for
(
i
=
1
;
i
<
isids_len
;
i
++
)
{
char
*
s
=
initial_sid_to_string
[
i
];
c
onst
c
har
*
s
=
initial_sid_to_string
[
i
];
fprintf
(
fout
,
"#define SECINITSID_%s"
,
s
);
for
(
j
=
0
;
j
<
max
(
1
,
40
-
strlen
(
s
));
j
++
)
fprintf
(
fout
,
" "
);
...
...
security/capability.c
View file @
539c99fd
...
...
@@ -12,11 +12,6 @@
#include <linux/security.h>
static
int
cap_acct
(
struct
file
*
file
)
{
return
0
;
}
static
int
cap_sysctl
(
ctl_table
*
table
,
int
op
)
{
return
0
;
...
...
@@ -80,42 +75,16 @@ static int cap_sb_mount(char *dev_name, struct path *path, char *type,
return
0
;
}
static
int
cap_sb_check_sb
(
struct
vfsmount
*
mnt
,
struct
path
*
path
)
{
return
0
;
}
static
int
cap_sb_umount
(
struct
vfsmount
*
mnt
,
int
flags
)
{
return
0
;
}
static
void
cap_sb_umount_close
(
struct
vfsmount
*
mnt
)
{
}
static
void
cap_sb_umount_busy
(
struct
vfsmount
*
mnt
)
{
}
static
void
cap_sb_post_remount
(
struct
vfsmount
*
mnt
,
unsigned
long
flags
,
void
*
data
)
{
}
static
void
cap_sb_post_addmount
(
struct
vfsmount
*
mnt
,
struct
path
*
path
)
{
}
static
int
cap_sb_pivotroot
(
struct
path
*
old_path
,
struct
path
*
new_path
)
{
return
0
;
}
static
void
cap_sb_post_pivotroot
(
struct
path
*
old_path
,
struct
path
*
new_path
)
{
}
static
int
cap_sb_set_mnt_opts
(
struct
super_block
*
sb
,
struct
security_mnt_opts
*
opts
)
{
...
...
@@ -221,10 +190,6 @@ static int cap_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
return
0
;
}
static
void
cap_inode_delete
(
struct
inode
*
ino
)
{
}
static
void
cap_inode_post_setxattr
(
struct
dentry
*
dentry
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
...
...
@@ -403,10 +368,6 @@ static int cap_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
return
0
;
}
static
void
cap_cred_commit
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
}
static
void
cap_cred_transfer
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
}
...
...
@@ -426,16 +387,6 @@ static int cap_kernel_module_request(char *kmod_name)
return
0
;
}
static
int
cap_task_setuid
(
uid_t
id0
,
uid_t
id1
,
uid_t
id2
,
int
flags
)
{
return
0
;
}
static
int
cap_task_setgid
(
gid_t
id0
,
gid_t
id1
,
gid_t
id2
,
int
flags
)
{
return
0
;
}
static
int
cap_task_setpgid
(
struct
task_struct
*
p
,
pid_t
pgid
)
{
return
0
;
...
...
@@ -456,11 +407,6 @@ static void cap_task_getsecid(struct task_struct *p, u32 *secid)
*
secid
=
0
;
}
static
int
cap_task_setgroups
(
struct
group_info
*
group_info
)
{
return
0
;
}
static
int
cap_task_getioprio
(
struct
task_struct
*
p
)
{
return
0
;
...
...
@@ -875,13 +821,6 @@ static int cap_key_getsecurity(struct key *key, char **_buffer)
return
0
;
}
static
int
cap_key_session_to_parent
(
const
struct
cred
*
cred
,
const
struct
cred
*
parent_cred
,
struct
key
*
key
)
{
return
0
;
}
#endif
/* CONFIG_KEYS */
#ifdef CONFIG_AUDIT
...
...
@@ -915,13 +854,12 @@ static void cap_audit_rule_free(void *lsmrule)
} \
} while (0)
void
security_fixup_ops
(
struct
security_operations
*
ops
)
void
__init
security_fixup_ops
(
struct
security_operations
*
ops
)
{
set_to_cap_if_null
(
ops
,
ptrace_access_check
);
set_to_cap_if_null
(
ops
,
ptrace_traceme
);
set_to_cap_if_null
(
ops
,
capget
);
set_to_cap_if_null
(
ops
,
capset
);
set_to_cap_if_null
(
ops
,
acct
);
set_to_cap_if_null
(
ops
,
capable
);
set_to_cap_if_null
(
ops
,
quotactl
);
set_to_cap_if_null
(
ops
,
quota_on
);
...
...
@@ -941,14 +879,8 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null
(
ops
,
sb_show_options
);
set_to_cap_if_null
(
ops
,
sb_statfs
);
set_to_cap_if_null
(
ops
,
sb_mount
);
set_to_cap_if_null
(
ops
,
sb_check_sb
);
set_to_cap_if_null
(
ops
,
sb_umount
);
set_to_cap_if_null
(
ops
,
sb_umount_close
);
set_to_cap_if_null
(
ops
,
sb_umount_busy
);
set_to_cap_if_null
(
ops
,
sb_post_remount
);
set_to_cap_if_null
(
ops
,
sb_post_addmount
);
set_to_cap_if_null
(
ops
,
sb_pivotroot
);
set_to_cap_if_null
(
ops
,
sb_post_pivotroot
);
set_to_cap_if_null
(
ops
,
sb_set_mnt_opts
);
set_to_cap_if_null
(
ops
,
sb_clone_mnt_opts
);
set_to_cap_if_null
(
ops
,
sb_parse_opts_str
);
...
...
@@ -968,7 +900,6 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null
(
ops
,
inode_permission
);
set_to_cap_if_null
(
ops
,
inode_setattr
);
set_to_cap_if_null
(
ops
,
inode_getattr
);
set_to_cap_if_null
(
ops
,
inode_delete
);
set_to_cap_if_null
(
ops
,
inode_setxattr
);
set_to_cap_if_null
(
ops
,
inode_post_setxattr
);
set_to_cap_if_null
(
ops
,
inode_getxattr
);
...
...
@@ -1009,19 +940,15 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null
(
ops
,
cred_alloc_blank
);
set_to_cap_if_null
(
ops
,
cred_free
);
set_to_cap_if_null
(
ops
,
cred_prepare
);
set_to_cap_if_null
(
ops
,
cred_commit
);
set_to_cap_if_null
(
ops
,
cred_transfer
);
set_to_cap_if_null
(
ops
,
kernel_act_as
);
set_to_cap_if_null
(
ops
,
kernel_create_files_as
);
set_to_cap_if_null
(
ops
,
kernel_module_request
);
set_to_cap_if_null
(
ops
,
task_setuid
);
set_to_cap_if_null
(
ops
,
task_fix_setuid
);
set_to_cap_if_null
(
ops
,
task_setgid
);
set_to_cap_if_null
(
ops
,
task_setpgid
);
set_to_cap_if_null
(
ops
,
task_getpgid
);
set_to_cap_if_null
(
ops
,
task_getsid
);
set_to_cap_if_null
(
ops
,
task_getsecid
);
set_to_cap_if_null
(
ops
,
task_setgroups
);
set_to_cap_if_null
(
ops
,
task_setnice
);
set_to_cap_if_null
(
ops
,
task_setioprio
);
set_to_cap_if_null
(
ops
,
task_getioprio
);
...
...
@@ -1113,7 +1040,6 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null
(
ops
,
key_free
);
set_to_cap_if_null
(
ops
,
key_permission
);
set_to_cap_if_null
(
ops
,
key_getsecurity
);
set_to_cap_if_null
(
ops
,
key_session_to_parent
);
#endif
/* CONFIG_KEYS */
#ifdef CONFIG_AUDIT
set_to_cap_if_null
(
ops
,
audit_rule_init
);
...
...
security/commoncap.c
View file @
539c99fd
...
...
@@ -570,7 +570,7 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name,
}
if
(
!
strncmp
(
name
,
XATTR_SECURITY_PREFIX
,
sizeof
(
XATTR_SECURITY_PREFIX
)
-
1
)
&&
sizeof
(
XATTR_SECURITY_PREFIX
)
-
1
)
&&
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
return
0
;
...
...
@@ -596,7 +596,7 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name)
}
if
(
!
strncmp
(
name
,
XATTR_SECURITY_PREFIX
,
sizeof
(
XATTR_SECURITY_PREFIX
)
-
1
)
&&
sizeof
(
XATTR_SECURITY_PREFIX
)
-
1
)
&&
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
return
0
;
...
...
@@ -931,7 +931,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
* @addr: address attempting to be mapped
* @addr_only: unused
*
* If the process is attempting to map memory below mmap_min_addr they need
* If the process is attempting to map memory below
dac_
mmap_min_addr they need
* CAP_SYS_RAWIO. The other parameters to this function are unused by the
* capability security module. Returns 0 if this mapping should be allowed
* -EPERM if not.
...
...
security/device_cgroup.c
View file @
539c99fd
...
...
@@ -470,7 +470,7 @@ struct cgroup_subsys devices_subsys = {
.
name
=
"devices"
,
.
can_attach
=
devcgroup_can_attach
,
.
create
=
devcgroup_create
,
.
destroy
=
devcgroup_destroy
,
.
destroy
=
devcgroup_destroy
,
.
populate
=
devcgroup_populate
,
.
subsys_id
=
devices_subsys_id
,
};
...
...
security/integrity/ima/Kconfig
View file @
539c99fd
...
...
@@ -2,15 +2,14 @@
#
config IMA
bool "Integrity Measurement Architecture(IMA)"
depends on ACPI
depends on SECURITY
select SECURITYFS
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
select TCG_TPM
select TCG_TIS
select TCG_TPM
if !S390
select TCG_TIS
if TCG_TPM
help
The Trusted Computing Group(TCG) runtime Integrity
Measurement Architecture(IMA) maintains a list of hash
...
...
security/integrity/ima/ima.h
View file @
539c99fd
...
...
@@ -135,7 +135,7 @@ enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
int
ima_match_policy
(
struct
inode
*
inode
,
enum
ima_hooks
func
,
int
mask
);
void
ima_init_policy
(
void
);
void
ima_update_policy
(
void
);
in
t
ima_parse_add_rule
(
char
*
);
ssize_
t
ima_parse_add_rule
(
char
*
);
void
ima_delete_rules
(
void
);
/* LSM based policy rules require audit */
...
...
security/integrity/ima/ima_audit.c
View file @
539c99fd
...
...
@@ -41,7 +41,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
return
;
ab
=
audit_log_start
(
current
->
audit_context
,
GFP_KERNEL
,
audit_msgno
);
audit_log_format
(
ab
,
"
integrity:
pid=%d uid=%u auid=%u ses=%u"
,
audit_log_format
(
ab
,
"pid=%d uid=%u auid=%u ses=%u"
,
current
->
pid
,
current_cred
()
->
uid
,
audit_get_loginuid
(
current
),
audit_get_sessionid
(
current
));
...
...
security/integrity/ima/ima_crypto.c
View file @
539c99fd
...
...
@@ -27,7 +27,7 @@ static int init_desc(struct hash_desc *desc)
desc
->
tfm
=
crypto_alloc_hash
(
ima_hash
,
0
,
CRYPTO_ALG_ASYNC
);
if
(
IS_ERR
(
desc
->
tfm
))
{
pr_info
(
"failed to load %s transform: %ld
\n
"
,
pr_info
(
"
IMA:
failed to load %s transform: %ld
\n
"
,
ima_hash
,
PTR_ERR
(
desc
->
tfm
));
rc
=
PTR_ERR
(
desc
->
tfm
);
return
rc
;
...
...
@@ -112,7 +112,7 @@ static void __init ima_pcrread(int idx, u8 *pcr)
return
;
if
(
tpm_pcr_read
(
TPM_ANY_NUM
,
idx
,
pcr
)
!=
0
)
pr_err
(
"Error Communicating to TPM chip
\n
"
);
pr_err
(
"
IMA:
Error Communicating to TPM chip
\n
"
);
}
/*
...
...
security/integrity/ima/ima_fs.c
View file @
539c99fd
...
...
@@ -244,32 +244,34 @@ static const struct file_operations ima_ascii_measurements_ops = {
static
ssize_t
ima_write_policy
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
datalen
,
loff_t
*
ppos
)
{
char
*
data
;
int
rc
;
char
*
data
=
NULL
;
ssize_t
result
;
if
(
datalen
>=
PAGE_SIZE
)
return
-
ENOMEM
;
if
(
*
ppos
!=
0
)
{
/* No partial writes. */
return
-
EINVAL
;
}
datalen
=
PAGE_SIZE
-
1
;
/* No partial writes. */
result
=
-
EINVAL
;
if
(
*
ppos
!=
0
)
goto
out
;
result
=
-
ENOMEM
;
data
=
kmalloc
(
datalen
+
1
,
GFP_KERNEL
);
if
(
!
data
)
return
-
ENOMEM
;
goto
out
;
if
(
copy_from_user
(
data
,
buf
,
datalen
))
{
kfree
(
data
);
return
-
EFAULT
;
}
*
(
data
+
datalen
)
=
'\0'
;
rc
=
ima_parse_add_rule
(
data
);
if
(
rc
<
0
)
{
datalen
=
-
EINVAL
;
valid_policy
=
0
;
}
result
=
-
EFAULT
;
if
(
copy_from_user
(
data
,
buf
,
datalen
))
goto
out
;
result
=
ima_parse_add_rule
(
data
);
out:
if
(
result
<
0
)
valid_policy
=
0
;
kfree
(
data
);
return
datalen
;
return
result
;
}
static
struct
dentry
*
ima_dir
;
...
...
security/integrity/ima/ima_iint.c
View file @
539c99fd
...
...
@@ -80,17 +80,17 @@ void iint_free(struct kref *kref)
iint
->
version
=
0
;
iint
->
flags
=
0UL
;
if
(
iint
->
readcount
!=
0
)
{
printk
(
KERN_INFO
"%s: readcount: %ld
\n
"
,
__
FUNCTION
__
,
printk
(
KERN_INFO
"%s: readcount: %ld
\n
"
,
__
func
__
,
iint
->
readcount
);
iint
->
readcount
=
0
;
}
if
(
iint
->
writecount
!=
0
)
{
printk
(
KERN_INFO
"%s: writecount: %ld
\n
"
,
__
FUNCTION
__
,
printk
(
KERN_INFO
"%s: writecount: %ld
\n
"
,
__
func
__
,
iint
->
writecount
);
iint
->
writecount
=
0
;
}
if
(
iint
->
opencount
!=
0
)
{
printk
(
KERN_INFO
"%s: opencount: %ld
\n
"
,
__
FUNCTION
__
,
printk
(
KERN_INFO
"%s: opencount: %ld
\n
"
,
__
func
__
,
iint
->
opencount
);
iint
->
opencount
=
0
;
}
...
...
security/integrity/ima/ima_init.c
View file @
539c99fd
...
...
@@ -83,7 +83,7 @@ int __init ima_init(void)
ima_used_chip
=
1
;
if
(
!
ima_used_chip
)
pr_info
(
"No TPM chip found, activating TPM-bypass!
\n
"
);
pr_info
(
"
IMA:
No TPM chip found, activating TPM-bypass!
\n
"
);
ima_add_boot_aggregate
();
/* boot aggregate must be first entry */
ima_init_policy
();
...
...
security/integrity/ima/ima_main.c
View file @
539c99fd
...
...
@@ -195,7 +195,7 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
(
iint
->
writecount
<
0
))
&&
!
ima_limit_imbalance
(
file
))
{
printk
(
KERN_INFO
"%s: open/free imbalance (r:%ld w:%ld o:%ld)
\n
"
,
__
FUNCTION
__
,
iint
->
readcount
,
iint
->
writecount
,
__
func
__
,
iint
->
readcount
,
iint
->
writecount
,
iint
->
opencount
);
dump_stack
();
}
...
...
security/integrity/ima/ima_policy.c
View file @
539c99fd
...
...
@@ -246,6 +246,9 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
{
int
result
;
if
(
entry
->
lsm
[
lsm_rule
].
rule
)
return
-
EINVAL
;
entry
->
lsm
[
lsm_rule
].
type
=
audit_type
;
result
=
security_filter_rule_init
(
entry
->
lsm
[
lsm_rule
].
type
,
Audit_equal
,
args
,
...
...
@@ -253,6 +256,13 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
return
result
;
}
static
void
ima_log_string
(
struct
audit_buffer
*
ab
,
char
*
key
,
char
*
value
)
{
audit_log_format
(
ab
,
"%s="
,
key
);
audit_log_untrustedstring
(
ab
,
value
);
audit_log_format
(
ab
,
" "
);
}
static
int
ima_parse_rule
(
char
*
rule
,
struct
ima_measure_rule_entry
*
entry
)
{
struct
audit_buffer
*
ab
;
...
...
@@ -261,28 +271,41 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
ab
=
audit_log_start
(
NULL
,
GFP_KERNEL
,
AUDIT_INTEGRITY_RULE
);
entry
->
action
=
-
1
;
while
((
p
=
strsep
(
&
rule
,
"
\n
"
))
!=
NULL
)
{
entry
->
uid
=
-
1
;
entry
->
action
=
UNKNOWN
;
while
((
p
=
strsep
(
&
rule
,
"
\t
"
))
!=
NULL
)
{
substring_t
args
[
MAX_OPT_ARGS
];
int
token
;
unsigned
long
lnum
;
if
(
result
<
0
)
break
;
if
(
!*
p
)
if
(
(
*
p
==
'\0'
)
||
(
*
p
==
' '
)
||
(
*
p
==
'\t'
)
)
continue
;
token
=
match_token
(
p
,
policy_tokens
,
args
);
switch
(
token
)
{
case
Opt_measure
:
audit_log_format
(
ab
,
"%s "
,
"measure"
);
ima_log_string
(
ab
,
"action"
,
"measure"
);
if
(
entry
->
action
!=
UNKNOWN
)
result
=
-
EINVAL
;
entry
->
action
=
MEASURE
;
break
;
case
Opt_dont_measure
:
audit_log_format
(
ab
,
"%s "
,
"dont_measure"
);
ima_log_string
(
ab
,
"action"
,
"dont_measure"
);
if
(
entry
->
action
!=
UNKNOWN
)
result
=
-
EINVAL
;
entry
->
action
=
DONT_MEASURE
;
break
;
case
Opt_func
:
audit_log_format
(
ab
,
"func=%s "
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"func"
,
args
[
0
].
from
);
if
(
entry
->
func
)
result
=
-
EINVAL
;
if
(
strcmp
(
args
[
0
].
from
,
"FILE_CHECK"
)
==
0
)
entry
->
func
=
FILE_CHECK
;
/* PATH_CHECK is for backwards compat */
...
...
@@ -298,7 +321,11 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
entry
->
flags
|=
IMA_FUNC
;
break
;
case
Opt_mask
:
audit_log_format
(
ab
,
"mask=%s "
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"mask"
,
args
[
0
].
from
);
if
(
entry
->
mask
)
result
=
-
EINVAL
;
if
((
strcmp
(
args
[
0
].
from
,
"MAY_EXEC"
))
==
0
)
entry
->
mask
=
MAY_EXEC
;
else
if
(
strcmp
(
args
[
0
].
from
,
"MAY_WRITE"
)
==
0
)
...
...
@@ -313,14 +340,26 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
entry
->
flags
|=
IMA_MASK
;
break
;
case
Opt_fsmagic
:
audit_log_format
(
ab
,
"fsmagic=%s "
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"fsmagic"
,
args
[
0
].
from
);
if
(
entry
->
fsmagic
)
{
result
=
-
EINVAL
;
break
;
}
result
=
strict_strtoul
(
args
[
0
].
from
,
16
,
&
entry
->
fsmagic
);
if
(
!
result
)
entry
->
flags
|=
IMA_FSMAGIC
;
break
;
case
Opt_uid
:
audit_log_format
(
ab
,
"uid=%s "
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"uid"
,
args
[
0
].
from
);
if
(
entry
->
uid
!=
-
1
)
{
result
=
-
EINVAL
;
break
;
}
result
=
strict_strtoul
(
args
[
0
].
from
,
10
,
&
lnum
);
if
(
!
result
)
{
entry
->
uid
=
(
uid_t
)
lnum
;
...
...
@@ -331,50 +370,51 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
}
break
;
case
Opt_obj_user
:
audit_log_format
(
ab
,
"obj_user=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"obj_user
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_OBJ_USER
,
AUDIT_OBJ_USER
);
break
;
case
Opt_obj_role
:
audit_log_format
(
ab
,
"obj_role=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"obj_role
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_OBJ_ROLE
,
AUDIT_OBJ_ROLE
);
break
;
case
Opt_obj_type
:
audit_log_format
(
ab
,
"obj_type=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"obj_type
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_OBJ_TYPE
,
AUDIT_OBJ_TYPE
);
break
;
case
Opt_subj_user
:
audit_log_format
(
ab
,
"subj_user=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"subj_user
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_SUBJ_USER
,
AUDIT_SUBJ_USER
);
break
;
case
Opt_subj_role
:
audit_log_format
(
ab
,
"subj_role=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"subj_role
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_SUBJ_ROLE
,
AUDIT_SUBJ_ROLE
);
break
;
case
Opt_subj_type
:
audit_log_format
(
ab
,
"subj_type=%s
"
,
args
[
0
].
from
);
ima_log_string
(
ab
,
"subj_type
"
,
args
[
0
].
from
);
result
=
ima_lsm_rule_init
(
entry
,
args
[
0
].
from
,
LSM_SUBJ_TYPE
,
AUDIT_SUBJ_TYPE
);
break
;
case
Opt_err
:
audit_log_format
(
ab
,
"UNKNOWN=%s "
,
p
);
ima_log_string
(
ab
,
"UNKNOWN"
,
p
);
result
=
-
EINVAL
;
break
;
}
}
if
(
entry
->
action
==
UNKNOWN
)
if
(
!
result
&&
(
entry
->
action
==
UNKNOWN
)
)
result
=
-
EINVAL
;
audit_log_format
(
ab
,
"res=%d"
,
!
result
?
0
:
1
);
audit_log_format
(
ab
,
"res=%d"
,
!
!
result
);
audit_log_end
(
ab
);
return
result
;
}
...
...
@@ -384,13 +424,14 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
* @rule - ima measurement policy rule
*
* Uses a mutex to protect the policy list from multiple concurrent writers.
* Returns
0 on success, an error code on failure.
* Returns
the length of the rule parsed, an error code on failure
*/
in
t
ima_parse_add_rule
(
char
*
rule
)
ssize_
t
ima_parse_add_rule
(
char
*
rule
)
{
const
char
*
op
=
"update_policy"
;
char
*
p
;
struct
ima_measure_rule_entry
*
entry
;
int
result
=
0
;
ssize_t
result
,
len
;
int
audit_info
=
0
;
/* Prevent installed policy from changing */
...
...
@@ -410,18 +451,28 @@ int ima_parse_add_rule(char *rule)
INIT_LIST_HEAD
(
&
entry
->
list
);
result
=
ima_parse_rule
(
rule
,
entry
);
if
(
!
result
)
{
mutex_lock
(
&
ima_measure_mutex
);
list_add_tail
(
&
entry
->
list
,
&
measure_policy_rules
);
mutex_unlock
(
&
ima_measure_mutex
);
}
else
{
p
=
strsep
(
&
rule
,
"
\n
"
);
len
=
strlen
(
p
)
+
1
;
if
(
*
p
==
'#'
)
{
kfree
(
entry
);
return
len
;
}
result
=
ima_parse_rule
(
p
,
entry
);
if
(
result
)
{
kfree
(
entry
);
integrity_audit_msg
(
AUDIT_INTEGRITY_STATUS
,
NULL
,
NULL
,
op
,
"invalid policy"
,
result
,
audit_info
);
return
result
;
}
return
result
;
mutex_lock
(
&
ima_measure_mutex
);
list_add_tail
(
&
entry
->
list
,
&
measure_policy_rules
);
mutex_unlock
(
&
ima_measure_mutex
);
return
len
;
}
/* ima_delete_rules called to cleanup invalid policy */
...
...
security/integrity/ima/ima_queue.c
View file @
539c99fd
...
...
@@ -71,7 +71,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry)
qe
=
kmalloc
(
sizeof
(
*
qe
),
GFP_KERNEL
);
if
(
qe
==
NULL
)
{
pr_err
(
"OUT OF MEMORY ERROR creating queue entry.
\n
"
);
pr_err
(
"
IMA:
OUT OF MEMORY ERROR creating queue entry.
\n
"
);
return
-
ENOMEM
;
}
qe
->
entry
=
entry
;
...
...
@@ -94,7 +94,7 @@ static int ima_pcr_extend(const u8 *hash)
result
=
tpm_pcr_extend
(
TPM_ANY_NUM
,
CONFIG_IMA_MEASURE_PCR_IDX
,
hash
);
if
(
result
!=
0
)
pr_err
(
"Error Communicating to TPM chip
\n
"
);
pr_err
(
"
IMA:
Error Communicating to TPM chip
\n
"
);
return
result
;
}
...
...
security/keys/internal.h
View file @
539c99fd
...
...
@@ -87,7 +87,16 @@ extern wait_queue_head_t request_key_conswq;
extern
struct
key_type
*
key_type_lookup
(
const
char
*
type
);
extern
void
key_type_put
(
struct
key_type
*
ktype
);
extern
int
__key_link
(
struct
key
*
keyring
,
struct
key
*
key
);
extern
int
__key_link_begin
(
struct
key
*
keyring
,
const
struct
key_type
*
type
,
const
char
*
description
,
struct
keyring_list
**
_prealloc
);
extern
int
__key_link_check_live_key
(
struct
key
*
keyring
,
struct
key
*
key
);
extern
void
__key_link
(
struct
key
*
keyring
,
struct
key
*
key
,
struct
keyring_list
**
_prealloc
);
extern
void
__key_link_end
(
struct
key
*
keyring
,
struct
key_type
*
type
,
struct
keyring_list
*
prealloc
);
extern
key_ref_t
__keyring_search_one
(
key_ref_t
keyring_ref
,
const
struct
key_type
*
type
,
...
...
security/keys/key.c
View file @
539c99fd
...
...
@@ -355,7 +355,7 @@ EXPORT_SYMBOL(key_alloc);
*/
int
key_payload_reserve
(
struct
key
*
key
,
size_t
datalen
)
{
int
delta
=
(
int
)
datalen
-
key
->
datalen
;
int
delta
=
(
int
)
datalen
-
key
->
datalen
;
int
ret
=
0
;
key_check
(
key
);
...
...
@@ -398,7 +398,8 @@ static int __key_instantiate_and_link(struct key *key,
const
void
*
data
,
size_t
datalen
,
struct
key
*
keyring
,
struct
key
*
authkey
)
struct
key
*
authkey
,
struct
keyring_list
**
_prealloc
)
{
int
ret
,
awaken
;
...
...
@@ -425,7 +426,7 @@ static int __key_instantiate_and_link(struct key *key,
/* and link it into the destination keyring */
if
(
keyring
)
ret
=
__key_link
(
keyring
,
key
);
__key_link
(
keyring
,
key
,
_prealloc
);
/* disable the authorisation key */
if
(
authkey
)
...
...
@@ -453,15 +454,21 @@ int key_instantiate_and_link(struct key *key,
struct
key
*
keyring
,
struct
key
*
authkey
)
{
struct
keyring_list
*
prealloc
;
int
ret
;
if
(
keyring
)
down_write
(
&
keyring
->
sem
);
if
(
keyring
)
{
ret
=
__key_link_begin
(
keyring
,
key
->
type
,
key
->
description
,
&
prealloc
);
if
(
ret
<
0
)
return
ret
;
}
ret
=
__key_instantiate_and_link
(
key
,
data
,
datalen
,
keyring
,
authkey
);
ret
=
__key_instantiate_and_link
(
key
,
data
,
datalen
,
keyring
,
authkey
,
&
prealloc
);
if
(
keyring
)
up_write
(
&
keyring
->
sem
);
__key_link_end
(
keyring
,
key
->
type
,
prealloc
);
return
ret
;
...
...
@@ -478,8 +485,9 @@ int key_negate_and_link(struct key *key,
struct
key
*
keyring
,
struct
key
*
authkey
)
{
struct
keyring_list
*
prealloc
;
struct
timespec
now
;
int
ret
,
awaken
;
int
ret
,
awaken
,
link_ret
=
0
;
key_check
(
key
);
key_check
(
keyring
);
...
...
@@ -488,7 +496,8 @@ int key_negate_and_link(struct key *key,
ret
=
-
EBUSY
;
if
(
keyring
)
down_write
(
&
keyring
->
sem
);
link_ret
=
__key_link_begin
(
keyring
,
key
->
type
,
key
->
description
,
&
prealloc
);
mutex_lock
(
&
key_construction_mutex
);
...
...
@@ -508,8 +517,8 @@ int key_negate_and_link(struct key *key,
ret
=
0
;
/* and link it into the destination keyring */
if
(
keyring
)
ret
=
__key_link
(
keyring
,
key
);
if
(
keyring
&&
link_ret
==
0
)
__key_link
(
keyring
,
key
,
&
prealloc
);
/* disable the authorisation key */
if
(
authkey
)
...
...
@@ -519,13 +528,13 @@ int key_negate_and_link(struct key *key,
mutex_unlock
(
&
key_construction_mutex
);
if
(
keyring
)
up_write
(
&
keyring
->
sem
);
__key_link_end
(
keyring
,
key
->
type
,
prealloc
);
/* wake up anyone waiting for a key to be constructed */
if
(
awaken
)
wake_up_bit
(
&
key
->
flags
,
KEY_FLAG_USER_CONSTRUCT
);
return
ret
;
return
ret
==
0
?
link_ret
:
ret
;
}
/* end key_negate_and_link() */
...
...
@@ -749,6 +758,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
key_perm_t
perm
,
unsigned
long
flags
)
{
struct
keyring_list
*
prealloc
;
const
struct
cred
*
cred
=
current_cred
();
struct
key_type
*
ktype
;
struct
key
*
keyring
,
*
key
=
NULL
;
...
...
@@ -775,7 +785,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
if
(
keyring
->
type
!=
&
key_type_keyring
)
goto
error_2
;
down_write
(
&
keyring
->
sem
);
ret
=
__key_link_begin
(
keyring
,
ktype
,
description
,
&
prealloc
);
if
(
ret
<
0
)
goto
error_2
;
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
...
...
@@ -817,7 +829,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
}
/* instantiate it and link it into the target keyring */
ret
=
__key_instantiate_and_link
(
key
,
payload
,
plen
,
keyring
,
NULL
);
ret
=
__key_instantiate_and_link
(
key
,
payload
,
plen
,
keyring
,
NULL
,
&
prealloc
);
if
(
ret
<
0
)
{
key_put
(
key
);
key_ref
=
ERR_PTR
(
ret
);
...
...
@@ -827,7 +840,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
key_ref
=
make_key_ref
(
key
,
is_key_possessed
(
keyring_ref
));
error_3:
up_write
(
&
keyring
->
sem
);
__key_link_end
(
keyring
,
ktype
,
prealloc
);
error_2:
key_type_put
(
ktype
);
error:
...
...
@@ -837,7 +850,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
/* we found a matching key, so we're going to try to update it
* - we can drop the locks first as we have the key pinned
*/
up_write
(
&
keyring
->
sem
);
__key_link_end
(
keyring
,
ktype
,
prealloc
);
key_type_put
(
ktype
);
key_ref
=
__key_update
(
key_ref
,
payload
,
plen
);
...
...
security/keys/keyctl.c
View file @
539c99fd
...
...
@@ -212,15 +212,15 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
ret
=
key
->
serial
;
key_put
(
key
);
error5:
error5:
key_type_put
(
ktype
);
error4:
error4:
key_ref_put
(
dest_ref
);
error3:
error3:
kfree
(
callout_info
);
error2:
error2:
kfree
(
description
);
error:
error:
return
ret
;
}
/* end sys_request_key() */
...
...
@@ -246,7 +246,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
ret
=
key_ref_to_ptr
(
key_ref
)
->
serial
;
key_ref_put
(
key_ref
);
error:
error:
return
ret
;
}
/* end keyctl_get_keyring_ID() */
...
...
@@ -275,7 +275,7 @@ long keyctl_join_session_keyring(const char __user *_name)
ret
=
join_session_keyring
(
name
);
kfree
(
name
);
error:
error:
return
ret
;
}
/* end keyctl_join_session_keyring() */
...
...
@@ -322,9 +322,9 @@ long keyctl_update_key(key_serial_t id,
ret
=
key_update
(
key_ref
,
payload
,
plen
);
key_ref_put
(
key_ref
);
error2:
error2:
kfree
(
payload
);
error:
error:
return
ret
;
}
/* end keyctl_update_key() */
...
...
@@ -356,7 +356,7 @@ long keyctl_revoke_key(key_serial_t id)
ret
=
0
;
key_ref_put
(
key_ref
);
error:
error:
return
ret
;
}
/* end keyctl_revoke_key() */
...
...
@@ -381,7 +381,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
ret
=
keyring_clear
(
key_ref_to_ptr
(
keyring_ref
));
key_ref_put
(
keyring_ref
);
error:
error:
return
ret
;
}
/* end keyctl_keyring_clear() */
...
...
@@ -413,9 +413,9 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
ret
=
key_link
(
key_ref_to_ptr
(
keyring_ref
),
key_ref_to_ptr
(
key_ref
));
key_ref_put
(
key_ref
);
error2:
error2:
key_ref_put
(
keyring_ref
);
error:
error:
return
ret
;
}
/* end keyctl_keyring_link() */
...
...
@@ -447,9 +447,9 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
ret
=
key_unlink
(
key_ref_to_ptr
(
keyring_ref
),
key_ref_to_ptr
(
key_ref
));
key_ref_put
(
key_ref
);
error2:
error2:
key_ref_put
(
keyring_ref
);
error:
error:
return
ret
;
}
/* end keyctl_keyring_unlink() */
...
...
@@ -529,9 +529,9 @@ long keyctl_describe_key(key_serial_t keyid,
}
kfree
(
tmpbuf
);
error2:
error2:
key_ref_put
(
key_ref
);
error:
error:
return
ret
;
}
/* end keyctl_describe_key() */
...
...
@@ -616,17 +616,17 @@ long keyctl_keyring_search(key_serial_t ringid,
ret
=
key_ref_to_ptr
(
key_ref
)
->
serial
;
error6:
error6:
key_ref_put
(
key_ref
);
error5:
error5:
key_type_put
(
ktype
);
error4:
error4:
key_ref_put
(
dest_ref
);
error3:
error3:
key_ref_put
(
keyring_ref
);
error2:
error2:
kfree
(
description
);
error:
error:
return
ret
;
}
/* end keyctl_keyring_search() */
...
...
@@ -673,7 +673,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
}
/* the key is probably readable - now try to read it */
can_read_key:
can_read_key:
ret
=
key_validate
(
key
);
if
(
ret
==
0
)
{
ret
=
-
EOPNOTSUPP
;
...
...
@@ -686,9 +686,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
}
}
error2:
error2:
key_put
(
key
);
error:
error:
return
ret
;
}
/* end keyctl_read_key() */
...
...
@@ -1282,26 +1282,19 @@ long keyctl_session_to_parent(void)
/* the parent must have the same effective ownership and mustn't be
* SUID/SGID */
if
(
pcred
->
uid
!=
mycred
->
euid
||
if
(
pcred
->
uid
!=
mycred
->
euid
||
pcred
->
euid
!=
mycred
->
euid
||
pcred
->
suid
!=
mycred
->
euid
||
pcred
->
gid
!=
mycred
->
egid
||
pcred
->
gid
!=
mycred
->
egid
||
pcred
->
egid
!=
mycred
->
egid
||
pcred
->
sgid
!=
mycred
->
egid
)
goto
not_permitted
;
/* the keyrings must have the same UID */
if
(
pcred
->
tgcred
->
session_keyring
->
uid
!=
mycred
->
euid
||
if
(
pcred
->
tgcred
->
session_keyring
->
uid
!=
mycred
->
euid
||
mycred
->
tgcred
->
session_keyring
->
uid
!=
mycred
->
euid
)
goto
not_permitted
;
/* the LSM must permit the replacement of the parent's keyring with the
* keyring from this process */
ret
=
security_key_session_to_parent
(
mycred
,
pcred
,
key_ref_to_ptr
(
keyring_r
));
if
(
ret
<
0
)
goto
not_permitted
;
/* if there's an already pending keyring replacement, then we replace
* that */
oldcred
=
parent
->
replacement_session_keyring
;
...
...
security/keys/keyring.c
View file @
539c99fd
This diff is collapsed.
Click to expand it.
security/keys/permission.c
View file @
539c99fd
...
...
@@ -109,7 +109,7 @@ int key_validate(struct key *key)
}
}
error:
error:
return
ret
;
}
/* end key_validate() */
...
...
security/keys/proc.c
View file @
539c99fd
...
...
@@ -306,7 +306,7 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
static
void
*
proc_key_users_next
(
struct
seq_file
*
p
,
void
*
v
,
loff_t
*
_pos
)
{
(
*
_pos
)
++
;
return
key_user_next
((
struct
rb_node
*
)
v
);
return
key_user_next
((
struct
rb_node
*
)
v
);
}
static
void
proc_key_users_stop
(
struct
seq_file
*
p
,
void
*
v
)
...
...
security/keys/process_keys.c
View file @
539c99fd
...
...
@@ -508,7 +508,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
ret
=
install_thread_keyring
();
if
(
ret
<
0
)
{
key
=
ERR_PTR
(
ret
);
key
_ref
=
ERR_PTR
(
ret
);
goto
error
;
}
goto
reget_creds
;
...
...
@@ -526,7 +526,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
ret
=
install_process_keyring
();
if
(
ret
<
0
)
{
key
=
ERR_PTR
(
ret
);
key
_ref
=
ERR_PTR
(
ret
);
goto
error
;
}
goto
reget_creds
;
...
...
@@ -585,7 +585,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
case
KEY_SPEC_GROUP_KEYRING
:
/* group keyrings are not yet supported */
key
=
ERR_PTR
(
-
EINVAL
);
key
_ref
=
ERR_PTR
(
-
EINVAL
);
goto
error
;
case
KEY_SPEC_REQKEY_AUTH_KEY
:
...
...
security/keys/request_key.c
View file @
539c99fd
...
...
@@ -299,12 +299,15 @@ static int construct_alloc_key(struct key_type *type,
struct
key_user
*
user
,
struct
key
**
_key
)
{
struct
keyring_list
*
prealloc
;
const
struct
cred
*
cred
=
current_cred
();
struct
key
*
key
;
key_ref_t
key_ref
;
int
ret
;
kenter
(
"%s,%s,,,"
,
type
->
name
,
description
);
*
_key
=
NULL
;
mutex_lock
(
&
user
->
cons_lock
);
key
=
key_alloc
(
type
,
description
,
cred
->
fsuid
,
cred
->
fsgid
,
cred
,
...
...
@@ -314,8 +317,12 @@ static int construct_alloc_key(struct key_type *type,
set_bit
(
KEY_FLAG_USER_CONSTRUCT
,
&
key
->
flags
);
if
(
dest_keyring
)
down_write
(
&
dest_keyring
->
sem
);
if
(
dest_keyring
)
{
ret
=
__key_link_begin
(
dest_keyring
,
type
,
description
,
&
prealloc
);
if
(
ret
<
0
)
goto
link_prealloc_failed
;
}
/* attach the key to the destination keyring under lock, but we do need
* to do another check just in case someone beat us to it whilst we
...
...
@@ -327,31 +334,49 @@ static int construct_alloc_key(struct key_type *type,
goto
key_already_present
;
if
(
dest_keyring
)
__key_link
(
dest_keyring
,
key
);
__key_link
(
dest_keyring
,
key
,
&
prealloc
);
mutex_unlock
(
&
key_construction_mutex
);
if
(
dest_keyring
)
up_write
(
&
dest_keyring
->
sem
);
__key_link_end
(
dest_keyring
,
type
,
prealloc
);
mutex_unlock
(
&
user
->
cons_lock
);
*
_key
=
key
;
kleave
(
" = 0 [%d]"
,
key_serial
(
key
));
return
0
;
/* the key is now present - we tell the caller that we found it by
* returning -EINPROGRESS */
key_already_present:
key_put
(
key
);
mutex_unlock
(
&
key_construction_mutex
);
key
=
key_ref_to_ptr
(
key_ref
);
if
(
dest_keyring
)
{
__key_link
(
dest_keyring
,
key_ref_to_ptr
(
key_ref
));
up_write
(
&
dest_keyring
->
sem
);
ret
=
__key_link_check_live_key
(
dest_keyring
,
key
);
if
(
ret
==
0
)
__key_link
(
dest_keyring
,
key
,
&
prealloc
);
__key_link_end
(
dest_keyring
,
type
,
prealloc
);
if
(
ret
<
0
)
goto
link_check_failed
;
}
mutex_unlock
(
&
user
->
cons_lock
);
key_put
(
key
);
*
_key
=
key
=
key_ref_to_ptr
(
key_ref
);
*
_key
=
key
;
kleave
(
" = -EINPROGRESS [%d]"
,
key_serial
(
key
));
return
-
EINPROGRESS
;
link_check_failed:
mutex_unlock
(
&
user
->
cons_lock
);
key_put
(
key
);
kleave
(
" = %d [linkcheck]"
,
ret
);
return
ret
;
link_prealloc_failed:
up_write
(
&
dest_keyring
->
sem
);
mutex_unlock
(
&
user
->
cons_lock
);
kleave
(
" = %d [prelink]"
,
ret
);
return
ret
;
alloc_failed:
mutex_unlock
(
&
user
->
cons_lock
);
*
_key
=
NULL
;
kleave
(
" = %ld"
,
PTR_ERR
(
key
));
return
PTR_ERR
(
key
);
}
...
...
@@ -390,6 +415,10 @@ static struct key *construct_key_and_link(struct key_type *type,
kdebug
(
"cons failed"
);
goto
construction_failed
;
}
}
else
if
(
ret
==
-
EINPROGRESS
)
{
ret
=
0
;
}
else
{
key
=
ERR_PTR
(
ret
);
}
key_put
(
dest_keyring
);
...
...
@@ -422,6 +451,7 @@ struct key *request_key_and_link(struct key_type *type,
const
struct
cred
*
cred
=
current_cred
();
struct
key
*
key
;
key_ref_t
key_ref
;
int
ret
;
kenter
(
"%s,%s,%p,%zu,%p,%p,%lx"
,
type
->
name
,
description
,
callout_info
,
callout_len
,
aux
,
...
...
@@ -435,8 +465,13 @@ struct key *request_key_and_link(struct key_type *type,
key
=
key_ref_to_ptr
(
key_ref
);
if
(
dest_keyring
)
{
construct_get_dest_keyring
(
&
dest_keyring
);
key_link
(
dest_keyring
,
key
);
ret
=
key_link
(
dest_keyring
,
key
);
key_put
(
dest_keyring
);
if
(
ret
<
0
)
{
key_put
(
key
);
key
=
ERR_PTR
(
ret
);
goto
error
;
}
}
}
else
if
(
PTR_ERR
(
key_ref
)
!=
-
EAGAIN
)
{
key
=
ERR_CAST
(
key_ref
);
...
...
security/lsm_audit.c
View file @
539c99fd
...
...
@@ -221,7 +221,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
switch
(
a
->
type
)
{
case
LSM_AUDIT_
NO_AUDIT
:
case
LSM_AUDIT_
DATA_NONE
:
return
;
case
LSM_AUDIT_DATA_IPC
:
audit_log_format
(
ab
,
" key=%d "
,
a
->
u
.
ipc_id
);
...
...
security/security.c
View file @
539c99fd
...
...
@@ -23,14 +23,14 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY
;
/* things that live in capability.c */
extern
void
security_fixup_ops
(
struct
security_operations
*
ops
);
extern
void
__init
security_fixup_ops
(
struct
security_operations
*
ops
);
static
struct
security_operations
*
security_ops
;
static
struct
security_operations
default_security_ops
=
{
.
name
=
"default"
,
};
static
inline
int
verify
(
struct
security_operations
*
ops
)
static
inline
int
__init
verify
(
struct
security_operations
*
ops
)
{
/* verify the security_operations structure exists */
if
(
!
ops
)
...
...
@@ -117,7 +117,7 @@ int __init security_module_enable(struct security_operations *ops)
* If there is already a security module registered with the kernel,
* an error will be returned. Otherwise %0 is returned on success.
*/
int
register_security
(
struct
security_operations
*
ops
)
int
__init
register_security
(
struct
security_operations
*
ops
)
{
if
(
verify
(
ops
))
{
printk
(
KERN_DEBUG
"%s could not verify "
...
...
@@ -190,11 +190,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap)
return
ret
;
}
int
security_acct
(
struct
file
*
file
)
{
return
security_ops
->
acct
(
file
);
}
int
security_sysctl
(
struct
ctl_table
*
table
,
int
op
)
{
return
security_ops
->
sysctl
(
table
,
op
);
...
...
@@ -306,46 +301,16 @@ int security_sb_mount(char *dev_name, struct path *path,
return
security_ops
->
sb_mount
(
dev_name
,
path
,
type
,
flags
,
data
);
}
int
security_sb_check_sb
(
struct
vfsmount
*
mnt
,
struct
path
*
path
)
{
return
security_ops
->
sb_check_sb
(
mnt
,
path
);
}
int
security_sb_umount
(
struct
vfsmount
*
mnt
,
int
flags
)
{
return
security_ops
->
sb_umount
(
mnt
,
flags
);
}
void
security_sb_umount_close
(
struct
vfsmount
*
mnt
)
{
security_ops
->
sb_umount_close
(
mnt
);
}
void
security_sb_umount_busy
(
struct
vfsmount
*
mnt
)
{
security_ops
->
sb_umount_busy
(
mnt
);
}
void
security_sb_post_remount
(
struct
vfsmount
*
mnt
,
unsigned
long
flags
,
void
*
data
)
{
security_ops
->
sb_post_remount
(
mnt
,
flags
,
data
);
}
void
security_sb_post_addmount
(
struct
vfsmount
*
mnt
,
struct
path
*
mountpoint
)
{
security_ops
->
sb_post_addmount
(
mnt
,
mountpoint
);
}
int
security_sb_pivotroot
(
struct
path
*
old_path
,
struct
path
*
new_path
)
{
return
security_ops
->
sb_pivotroot
(
old_path
,
new_path
);
}
void
security_sb_post_pivotroot
(
struct
path
*
old_path
,
struct
path
*
new_path
)
{
security_ops
->
sb_post_pivotroot
(
old_path
,
new_path
);
}
int
security_sb_set_mnt_opts
(
struct
super_block
*
sb
,
struct
security_mnt_opts
*
opts
)
{
...
...
@@ -580,13 +545,6 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
return
security_ops
->
inode_getattr
(
mnt
,
dentry
);
}
void
security_inode_delete
(
struct
inode
*
inode
)
{
if
(
unlikely
(
IS_PRIVATE
(
inode
)))
return
;
security_ops
->
inode_delete
(
inode
);
}
int
security_inode_setxattr
(
struct
dentry
*
dentry
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
...
...
@@ -749,11 +707,6 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
return
security_ops
->
cred_prepare
(
new
,
old
,
gfp
);
}
void
security_commit_creds
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
security_ops
->
cred_commit
(
new
,
old
);
}
void
security_transfer_creds
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
security_ops
->
cred_transfer
(
new
,
old
);
...
...
@@ -774,22 +727,12 @@ int security_kernel_module_request(char *kmod_name)
return
security_ops
->
kernel_module_request
(
kmod_name
);
}
int
security_task_setuid
(
uid_t
id0
,
uid_t
id1
,
uid_t
id2
,
int
flags
)
{
return
security_ops
->
task_setuid
(
id0
,
id1
,
id2
,
flags
);
}
int
security_task_fix_setuid
(
struct
cred
*
new
,
const
struct
cred
*
old
,
int
flags
)
{
return
security_ops
->
task_fix_setuid
(
new
,
old
,
flags
);
}
int
security_task_setgid
(
gid_t
id0
,
gid_t
id1
,
gid_t
id2
,
int
flags
)
{
return
security_ops
->
task_setgid
(
id0
,
id1
,
id2
,
flags
);
}
int
security_task_setpgid
(
struct
task_struct
*
p
,
pid_t
pgid
)
{
return
security_ops
->
task_setpgid
(
p
,
pgid
);
...
...
@@ -811,11 +754,6 @@ void security_task_getsecid(struct task_struct *p, u32 *secid)
}
EXPORT_SYMBOL
(
security_task_getsecid
);
int
security_task_setgroups
(
struct
group_info
*
group_info
)
{
return
security_ops
->
task_setgroups
(
group_info
);
}
int
security_task_setnice
(
struct
task_struct
*
p
,
int
nice
)
{
return
security_ops
->
task_setnice
(
p
,
nice
);
...
...
@@ -1319,13 +1257,6 @@ int security_key_getsecurity(struct key *key, char **_buffer)
return
security_ops
->
key_getsecurity
(
key
,
_buffer
);
}
int
security_key_session_to_parent
(
const
struct
cred
*
cred
,
const
struct
cred
*
parent_cred
,
struct
key
*
key
)
{
return
security_ops
->
key_session_to_parent
(
cred
,
parent_cred
,
key
);
}
#endif
/* CONFIG_KEYS */
#ifdef CONFIG_AUDIT
...
...
security/selinux/avc.c
View file @
539c99fd
...
...
@@ -499,8 +499,7 @@ void avc_audit(u32 ssid, u32 tsid,
return
;
if
(
!
a
)
{
a
=
&
stack_data
;
memset
(
a
,
0
,
sizeof
(
*
a
));
a
->
type
=
LSM_AUDIT_NO_AUDIT
;
COMMON_AUDIT_DATA_INIT
(
a
,
NONE
);
}
a
->
selinux_audit_data
.
tclass
=
tclass
;
a
->
selinux_audit_data
.
requested
=
requested
;
...
...
security/selinux/hooks.c
View file @
539c99fd
...
...
@@ -293,28 +293,28 @@ static void superblock_free_security(struct super_block *sb)
static
int
sk_alloc_security
(
struct
sock
*
sk
,
int
family
,
gfp_t
priority
)
{
struct
sk_security_struct
*
ssec
;
struct
sk_security_struct
*
s
k
sec
;
s
sec
=
kzalloc
(
sizeof
(
*
s
sec
),
priority
);
if
(
!
ssec
)
s
ksec
=
kzalloc
(
sizeof
(
*
sk
sec
),
priority
);
if
(
!
s
k
sec
)
return
-
ENOMEM
;
ssec
->
peer_sid
=
SECINITSID_UNLABELED
;
ssec
->
sid
=
SECINITSID_UNLABELED
;
sk
->
sk_security
=
ssec
;
s
k
sec
->
peer_sid
=
SECINITSID_UNLABELED
;
s
k
sec
->
sid
=
SECINITSID_UNLABELED
;
sk
->
sk_security
=
s
k
sec
;
selinux_netlbl_sk_security_reset
(
ssec
);
selinux_netlbl_sk_security_reset
(
s
k
sec
);
return
0
;
}
static
void
sk_free_security
(
struct
sock
*
sk
)
{
struct
sk_security_struct
*
ssec
=
sk
->
sk_security
;
struct
sk_security_struct
*
s
k
sec
=
sk
->
sk_security
;
sk
->
sk_security
=
NULL
;
selinux_netlbl_sk_security_free
(
ssec
);
kfree
(
ssec
);
selinux_netlbl_sk_security_free
(
s
k
sec
);
kfree
(
s
k
sec
);
}
/* The security server must be initialized before
...
...
@@ -323,7 +323,7 @@ extern int ss_initialized;
/* The file system's label must be initialized prior to use. */
static
char
*
labeling_behaviors
[
6
]
=
{
static
c
onst
c
har
*
labeling_behaviors
[
6
]
=
{
"uses xattr"
,
"uses transition SIDs"
,
"uses task SIDs"
,
...
...
@@ -2999,13 +2999,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
return
file_has_perm
(
cred
,
file
,
av
);
}
static
int
default_noexec
;
static
int
file_map_prot_check
(
struct
file
*
file
,
unsigned
long
prot
,
int
shared
)
{
const
struct
cred
*
cred
=
current_cred
();
int
rc
=
0
;
#ifndef CONFIG_PPC32
if
(
(
prot
&
PROT_EXEC
)
&&
(
!
file
||
(
!
shared
&&
(
prot
&
PROT_WRITE
))))
{
if
(
default_noexec
&&
(
prot
&
PROT_EXEC
)
&&
(
!
file
||
(
!
shared
&&
(
prot
&
PROT_WRITE
))))
{
/*
* We are making executable an anonymous mapping or a
* private file mapping that will also be writable.
...
...
@@ -3015,7 +3017,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
if
(
rc
)
goto
error
;
}
#endif
if
(
file
)
{
/* read access is always possible with a mapping */
...
...
@@ -3076,8 +3077,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if
(
selinux_checkreqprot
)
prot
=
reqprot
;
#ifndef CONFIG_PPC32
if
(
(
prot
&
PROT_EXEC
)
&&
!
(
vma
->
vm_flags
&
VM_EXEC
))
{
if
(
default_noexec
&&
(
prot
&
PROT_EXEC
)
&&
!
(
vma
->
vm_flags
&
VM_EXEC
))
{
int
rc
=
0
;
if
(
vma
->
vm_start
>=
vma
->
vm_mm
->
start_brk
&&
vma
->
vm_end
<=
vma
->
vm_mm
->
brk
)
{
...
...
@@ -3099,7 +3100,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if
(
rc
)
return
rc
;
}
#endif
return
file_map_prot_check
(
vma
->
vm_file
,
prot
,
vma
->
vm_flags
&
VM_SHARED
);
}
...
...
@@ -4002,7 +4002,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
struct
socket
*
other
,
struct
sock
*
newsk
)
{
struct
sk_security_struct
*
ssec
;
struct
sk_security_struct
*
s
k
sec
;
struct
inode_security_struct
*
isec
;
struct
inode_security_struct
*
other_isec
;
struct
common_audit_data
ad
;
...
...
@@ -4021,13 +4021,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
return
err
;
/* connecting socket */
ssec
=
sock
->
sk
->
sk_security
;
ssec
->
peer_sid
=
other_isec
->
sid
;
s
k
sec
=
sock
->
sk
->
sk_security
;
s
k
sec
->
peer_sid
=
other_isec
->
sid
;
/* server child socket */
ssec
=
newsk
->
sk_security
;
ssec
->
peer_sid
=
isec
->
sid
;
err
=
security_sid_mls_copy
(
other_isec
->
sid
,
s
sec
->
peer_sid
,
&
s
sec
->
sid
);
s
k
sec
=
newsk
->
sk_security
;
s
k
sec
->
peer_sid
=
isec
->
sid
;
err
=
security_sid_mls_copy
(
other_isec
->
sid
,
s
ksec
->
peer_sid
,
&
sk
sec
->
sid
);
return
err
;
}
...
...
@@ -4190,7 +4190,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
int
err
=
0
;
char
*
scontext
;
u32
scontext_len
;
struct
sk_security_struct
*
ssec
;
struct
sk_security_struct
*
s
k
sec
;
struct
inode_security_struct
*
isec
;
u32
peer_sid
=
SECSID_NULL
;
...
...
@@ -4198,8 +4198,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
if
(
isec
->
sclass
==
SECCLASS_UNIX_STREAM_SOCKET
||
isec
->
sclass
==
SECCLASS_TCP_SOCKET
)
{
ssec
=
sock
->
sk
->
sk_security
;
peer_sid
=
ssec
->
peer_sid
;
s
k
sec
=
sock
->
sk
->
sk_security
;
peer_sid
=
s
k
sec
->
peer_sid
;
}
if
(
peer_sid
==
SECSID_NULL
)
{
err
=
-
ENOPROTOOPT
;
...
...
@@ -4266,14 +4266,14 @@ static void selinux_sk_free_security(struct sock *sk)
static
void
selinux_sk_clone_security
(
const
struct
sock
*
sk
,
struct
sock
*
newsk
)
{
struct
sk_security_struct
*
ssec
=
sk
->
sk_security
;
struct
sk_security_struct
*
newssec
=
newsk
->
sk_security
;
struct
sk_security_struct
*
s
k
sec
=
sk
->
sk_security
;
struct
sk_security_struct
*
news
k
sec
=
newsk
->
sk_security
;
news
sec
->
sid
=
s
sec
->
sid
;
news
sec
->
peer_sid
=
s
sec
->
peer_sid
;
news
sec
->
sclass
=
s
sec
->
sclass
;
news
ksec
->
sid
=
sk
sec
->
sid
;
news
ksec
->
peer_sid
=
sk
sec
->
peer_sid
;
news
ksec
->
sclass
=
sk
sec
->
sclass
;
selinux_netlbl_sk_security_reset
(
newssec
);
selinux_netlbl_sk_security_reset
(
news
k
sec
);
}
static
void
selinux_sk_getsecid
(
struct
sock
*
sk
,
u32
*
secid
)
...
...
@@ -5662,6 +5662,8 @@ static __init int selinux_init(void)
/* Set the security state for the initial task. */
cred_init_security
();
default_noexec
=
!
(
VM_DATA_DEFAULT_FLAGS
&
VM_EXEC
);
sel_inode_cache
=
kmem_cache_create
(
"selinux_inode_security"
,
sizeof
(
struct
inode_security_struct
),
0
,
SLAB_PANIC
,
NULL
);
...
...
security/selinux/include/initial_sid_to_string.h
View file @
539c99fd
/* This file is automatically generated. Do not edit. */
static
char
*
initial_sid_to_string
[]
=
static
c
onst
c
har
*
initial_sid_to_string
[]
=
{
"null"
,
"kernel"
,
...
...
security/selinux/include/netlabel.h
View file @
539c99fd
...
...
@@ -42,8 +42,8 @@ void selinux_netlbl_cache_invalidate(void);
void
selinux_netlbl_err
(
struct
sk_buff
*
skb
,
int
error
,
int
gateway
);
void
selinux_netlbl_sk_security_free
(
struct
sk_security_struct
*
ssec
);
void
selinux_netlbl_sk_security_reset
(
struct
sk_security_struct
*
ssec
);
void
selinux_netlbl_sk_security_free
(
struct
sk_security_struct
*
s
k
sec
);
void
selinux_netlbl_sk_security_reset
(
struct
sk_security_struct
*
s
k
sec
);
int
selinux_netlbl_skbuff_getsid
(
struct
sk_buff
*
skb
,
u16
family
,
...
...
@@ -79,13 +79,13 @@ static inline void selinux_netlbl_err(struct sk_buff *skb,
}
static
inline
void
selinux_netlbl_sk_security_free
(
struct
sk_security_struct
*
ssec
)
struct
sk_security_struct
*
s
k
sec
)
{
return
;
}
static
inline
void
selinux_netlbl_sk_security_reset
(
struct
sk_security_struct
*
ssec
)
struct
sk_security_struct
*
s
k
sec
)
{
return
;
}
...
...
security/selinux/netlabel.c
View file @
539c99fd
...
...
@@ -132,21 +132,21 @@ void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
/**
* selinux_netlbl_sk_security_free - Free the NetLabel fields
* @s
s
sec: the sk_security_struct
* @s
k
sec: the sk_security_struct
*
* Description:
* Free all of the memory in the NetLabel fields of a sk_security_struct.
*
*/
void
selinux_netlbl_sk_security_free
(
struct
sk_security_struct
*
ssec
)
void
selinux_netlbl_sk_security_free
(
struct
sk_security_struct
*
s
k
sec
)
{
if
(
ssec
->
nlbl_secattr
!=
NULL
)
netlbl_secattr_free
(
ssec
->
nlbl_secattr
);
if
(
s
k
sec
->
nlbl_secattr
!=
NULL
)
netlbl_secattr_free
(
s
k
sec
->
nlbl_secattr
);
}
/**
* selinux_netlbl_sk_security_reset - Reset the NetLabel fields
* @ssec: the sk_security_struct
* @s
k
sec: the sk_security_struct
* @family: the socket family
*
* Description:
...
...
@@ -154,9 +154,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
* The caller is responsibile for all the NetLabel sk_security_struct locking.
*
*/
void
selinux_netlbl_sk_security_reset
(
struct
sk_security_struct
*
ssec
)
void
selinux_netlbl_sk_security_reset
(
struct
sk_security_struct
*
s
k
sec
)
{
ssec
->
nlbl_state
=
NLBL_UNSET
;
s
k
sec
->
nlbl_state
=
NLBL_UNSET
;
}
/**
...
...
security/selinux/netlink.c
View file @
539c99fd
...
...
@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/selinux_netlink.h>
...
...
security/selinux/nlmsgtab.c
View file @
539c99fd
...
...
@@ -11,7 +11,6 @@
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if.h>
...
...
security/selinux/selinuxfs.c
View file @
539c99fd
...
...
@@ -503,11 +503,11 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
return
length
;
length
=
-
ENOMEM
;
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
scon
)
return
length
;
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
tcon
)
goto
out
;
...
...
@@ -515,10 +515,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
if
(
sscanf
(
buf
,
"%s %s %hu"
,
scon
,
tcon
,
&
tclass
)
!=
3
)
goto
out2
;
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
if
(
length
<
0
)
goto
out2
;
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
if
(
length
<
0
)
goto
out2
;
...
...
@@ -550,11 +550,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
return
length
;
length
=
-
ENOMEM
;
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
scon
)
return
length
;
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
tcon
)
goto
out
;
...
...
@@ -562,10 +562,10 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if
(
sscanf
(
buf
,
"%s %s %hu"
,
scon
,
tcon
,
&
tclass
)
!=
3
)
goto
out2
;
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
if
(
length
<
0
)
goto
out2
;
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
if
(
length
<
0
)
goto
out2
;
...
...
@@ -609,11 +609,11 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
return
length
;
length
=
-
ENOMEM
;
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
scon
)
return
length
;
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
tcon
)
goto
out
;
...
...
@@ -621,10 +621,10 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
if
(
sscanf
(
buf
,
"%s %s %hu"
,
scon
,
tcon
,
&
tclass
)
!=
3
)
goto
out2
;
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
if
(
length
<
0
)
goto
out2
;
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
if
(
length
<
0
)
goto
out2
;
...
...
@@ -666,11 +666,11 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
return
length
;
length
=
-
ENOMEM
;
con
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
con
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
con
)
return
length
;
user
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
user
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
user
)
goto
out
;
...
...
@@ -678,7 +678,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
if
(
sscanf
(
buf
,
"%s %s"
,
con
,
user
)
!=
2
)
goto
out2
;
length
=
security_context_to_sid
(
con
,
strlen
(
con
)
+
1
,
&
sid
);
length
=
security_context_to_sid
(
con
,
strlen
(
con
)
+
1
,
&
sid
);
if
(
length
<
0
)
goto
out2
;
...
...
@@ -727,11 +727,11 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
return
length
;
length
=
-
ENOMEM
;
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
scon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
scon
)
return
length
;
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
tcon
=
kzalloc
(
size
+
1
,
GFP_KERNEL
);
if
(
!
tcon
)
goto
out
;
...
...
@@ -739,10 +739,10 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
if
(
sscanf
(
buf
,
"%s %s %hu"
,
scon
,
tcon
,
&
tclass
)
!=
3
)
goto
out2
;
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
length
=
security_context_to_sid
(
scon
,
strlen
(
scon
)
+
1
,
&
ssid
);
if
(
length
<
0
)
goto
out2
;
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
length
=
security_context_to_sid
(
tcon
,
strlen
(
tcon
)
+
1
,
&
tsid
);
if
(
length
<
0
)
goto
out2
;
...
...
@@ -1401,7 +1401,7 @@ static int sel_make_perm_files(char *objclass, int classvalue,
}
inode
->
i_fop
=
&
sel_perm_ops
;
/* i+1 since perm values are 1-indexed */
inode
->
i_ino
=
sel_perm_to_ino
(
classvalue
,
i
+
1
);
inode
->
i_ino
=
sel_perm_to_ino
(
classvalue
,
i
+
1
);
d_add
(
dentry
,
inode
);
}
...
...
@@ -1489,7 +1489,7 @@ static int sel_make_classes(void)
goto
out
;
/* +2 since classes are 1-indexed */
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
;
...
...
@@ -1506,7 +1506,7 @@ static int sel_make_classes(void)
goto
out1
;
/* i+1 since class values are 1-indexed */
rc
=
sel_make_class_dir_entries
(
classes
[
i
],
i
+
1
,
rc
=
sel_make_class_dir_entries
(
classes
[
i
],
i
+
1
,
class_name_dir
);
if
(
rc
)
goto
out1
;
...
...
security/selinux/ss/mls.c
View file @
539c99fd
...
...
@@ -255,7 +255,7 @@ int mls_context_to_sid(struct policydb *pol,
if
(
!
pol
->
mls_enabled
)
{
if
(
def_sid
!=
SECSID_NULL
&&
oldc
)
*
scontext
+=
strlen
(
*
scontext
)
+
1
;
*
scontext
+=
strlen
(
*
scontext
)
+
1
;
return
0
;
}
...
...
security/selinux/ss/policydb.c
View file @
539c99fd
...
...
@@ -40,7 +40,7 @@
#define _DEBUG_HASHES
#ifdef DEBUG_HASHES
static
char
*
symtab_name
[
SYM_NUM
]
=
{
static
c
onst
c
har
*
symtab_name
[
SYM_NUM
]
=
{
"common prefixes"
,
"classes"
,
"roles"
,
...
...
@@ -156,12 +156,11 @@ static int roles_init(struct policydb *p)
rc
=
-
EINVAL
;
goto
out_free_role
;
}
key
=
k
malloc
(
strlen
(
OBJECT_R
)
+
1
,
GFP_KERNEL
);
key
=
k
strdup
(
OBJECT_R
,
GFP_KERNEL
);
if
(
!
key
)
{
rc
=
-
ENOMEM
;
goto
out_free_role
;
}
strcpy
(
key
,
OBJECT_R
);
rc
=
hashtab_insert
(
p
->
p_roles
.
table
,
key
,
role
);
if
(
rc
)
goto
out_free_key
;
...
...
@@ -2195,7 +2194,7 @@ int policydb_read(struct policydb *p, void *fp)
rangetr_hash_eval
(
p
->
range_tr
);
}
p
->
type_attr_map
=
kmalloc
(
p
->
p_types
.
nprim
*
sizeof
(
struct
ebitmap
),
GFP_KERNEL
);
p
->
type_attr_map
=
kmalloc
(
p
->
p_types
.
nprim
*
sizeof
(
struct
ebitmap
),
GFP_KERNEL
);
if
(
!
p
->
type_attr_map
)
goto
bad
;
...
...
security/selinux/ss/services.c
View file @
539c99fd
...
...
@@ -274,15 +274,15 @@ static int constraint_expr_eval(struct context *scontext,
case
CEXPR_AND
:
BUG_ON
(
sp
<
1
);
sp
--
;
s
[
sp
]
&=
s
[
sp
+
1
];
s
[
sp
]
&=
s
[
sp
+
1
];
break
;
case
CEXPR_OR
:
BUG_ON
(
sp
<
1
);
sp
--
;
s
[
sp
]
|=
s
[
sp
+
1
];
s
[
sp
]
|=
s
[
sp
+
1
];
break
;
case
CEXPR_ATTR
:
if
(
sp
==
(
CEXPR_MAXDEPTH
-
1
))
if
(
sp
==
(
CEXPR_MAXDEPTH
-
1
))
return
0
;
switch
(
e
->
attr
)
{
case
CEXPR_USER
:
...
...
@@ -1216,7 +1216,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
*
sid
=
SECSID_NULL
;
/* Copy the string so that we can modify the copy as we parse it. */
scontext2
=
kmalloc
(
scontext_len
+
1
,
gfp_flags
);
scontext2
=
kmalloc
(
scontext_len
+
1
,
gfp_flags
);
if
(
!
scontext2
)
return
-
ENOMEM
;
memcpy
(
scontext2
,
scontext
,
scontext_len
);
...
...
@@ -1760,22 +1760,28 @@ int security_load_policy(void *data, size_t len)
if
(
!
ss_initialized
)
{
avtab_cache_init
();
if
(
policydb_read
(
&
policydb
,
fp
))
{
rc
=
policydb_read
(
&
policydb
,
fp
);
if
(
rc
)
{
avtab_cache_destroy
();
return
-
EINVAL
;
return
rc
;
}
if
(
selinux_set_mapping
(
&
policydb
,
secclass_map
,
&
current_mapping
,
&
current_mapping_size
))
{
rc
=
selinux_set_mapping
(
&
policydb
,
secclass_map
,
&
current_mapping
,
&
current_mapping_size
);
if
(
rc
)
{
policydb_destroy
(
&
policydb
);
avtab_cache_destroy
();
return
-
EINVAL
;
return
rc
;
}
if
(
policydb_load_isids
(
&
policydb
,
&
sidtab
))
{
rc
=
policydb_load_isids
(
&
policydb
,
&
sidtab
);
if
(
rc
)
{
policydb_destroy
(
&
policydb
);
avtab_cache_destroy
();
return
-
EINVAL
;
return
rc
;
}
security_load_policycaps
();
ss_initialized
=
1
;
seqno
=
++
latest_granting
;
...
...
@@ -1791,8 +1797,9 @@ int security_load_policy(void *data, size_t len)
sidtab_hash_eval(&sidtab, "sids");
#endif
if
(
policydb_read
(
&
newpolicydb
,
fp
))
return
-
EINVAL
;
rc
=
policydb_read
(
&
newpolicydb
,
fp
);
if
(
rc
)
return
rc
;
/* If switching between different policy types, log MLS status */
if
(
policydb
.
mls_enabled
&&
!
newpolicydb
.
mls_enabled
)
...
...
@@ -1807,8 +1814,8 @@ int security_load_policy(void *data, size_t len)
return
rc
;
}
if
(
selinux_set_mapping
(
&
newpolicydb
,
secclass_map
,
&
map
,
&
map_size
)
)
rc
=
selinux_set_mapping
(
&
newpolicydb
,
secclass_map
,
&
map
,
&
map_size
);
if
(
rc
)
goto
err
;
rc
=
security_preserve_bools
(
&
newpolicydb
);
...
...
@@ -1819,10 +1826,10 @@ int security_load_policy(void *data, size_t len)
/* Clone the SID table. */
sidtab_shutdown
(
&
sidtab
);
if
(
sidtab_map
(
&
sidtab
,
clone_sid
,
&
newsidtab
))
{
rc
=
-
ENOMEM
;
rc
=
sidtab_map
(
&
sidtab
,
clone_sid
,
&
newsidtab
);
if
(
rc
)
goto
err
;
}
/*
* Convert the internal representations of contexts
...
...
@@ -2101,9 +2108,9 @@ int security_get_user_sids(u32 fromsid,
ebitmap_for_each_positive_bit
(
&
user
->
roles
,
rnode
,
i
)
{
role
=
policydb
.
role_val_to_struct
[
i
];
usercon
.
role
=
i
+
1
;
usercon
.
role
=
i
+
1
;
ebitmap_for_each_positive_bit
(
&
role
->
types
,
tnode
,
j
)
{
usercon
.
type
=
j
+
1
;
usercon
.
type
=
j
+
1
;
if
(
mls_setup_user_range
(
fromcon
,
user
,
&
usercon
))
continue
;
...
...
security/smack/smack_lsm.c
View file @
539c99fd
...
...
@@ -19,7 +19,6 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/stat.h>
#include <linux/ext2_fs.h>
#include <linux/kd.h>
#include <asm/ioctls.h>
#include <linux/ip.h>
...
...
@@ -1118,15 +1117,6 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
return
0
;
}
/**
* smack_cred_commit - commit new credentials
* @new: the new credentials
* @old: the original credentials
*/
static
void
smack_cred_commit
(
struct
cred
*
new
,
const
struct
cred
*
old
)
{
}
/**
* smack_cred_transfer - Transfer the old credentials to the new credentials
* @new: the new credentials
...
...
@@ -3121,7 +3111,6 @@ struct security_operations smack_ops = {
.
cred_alloc_blank
=
smack_cred_alloc_blank
,
.
cred_free
=
smack_cred_free
,
.
cred_prepare
=
smack_cred_prepare
,
.
cred_commit
=
smack_cred_commit
,
.
cred_transfer
=
smack_cred_transfer
,
.
kernel_act_as
=
smack_kernel_act_as
,
.
kernel_create_files_as
=
smack_kernel_create_files_as
,
...
...
security/tomoyo/Makefile
View file @
539c99fd
obj-y
=
common.o realpath.o tomoyo.o domain.o file.o gc.o
obj-y
=
common.o realpath.o tomoyo.o domain.o file.o gc.o
path_group.o
security/tomoyo/common.c
View file @
539c99fd
...
...
@@ -75,6 +75,49 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
static
int
tomoyo_write_control
(
struct
file
*
file
,
const
char
__user
*
buffer
,
const
int
buffer_len
);
/**
* tomoyo_parse_name_union - Parse a tomoyo_name_union.
*
* @filename: Name or name group.
* @ptr: Pointer to "struct tomoyo_name_union".
*
* Returns true on success, false otherwise.
*/
bool
tomoyo_parse_name_union
(
const
char
*
filename
,
struct
tomoyo_name_union
*
ptr
)
{
if
(
!
tomoyo_is_correct_path
(
filename
,
0
,
0
,
0
))
return
false
;
if
(
filename
[
0
]
==
'@'
)
{
ptr
->
group
=
tomoyo_get_path_group
(
filename
+
1
);
ptr
->
is_group
=
true
;
return
ptr
->
group
!=
NULL
;
}
ptr
->
filename
=
tomoyo_get_name
(
filename
);
ptr
->
is_group
=
false
;
return
ptr
->
filename
!=
NULL
;
}
/**
* tomoyo_print_name_union - Print a tomoyo_name_union.
*
* @head: Pointer to "struct tomoyo_io_buffer".
* @ptr: Pointer to "struct tomoyo_name_union".
*
* Returns true on success, false otherwise.
*/
static
bool
tomoyo_print_name_union
(
struct
tomoyo_io_buffer
*
head
,
const
struct
tomoyo_name_union
*
ptr
)
{
int
pos
=
head
->
read_avail
;
if
(
pos
&&
head
->
read_buf
[
pos
-
1
]
==
' '
)
head
->
read_avail
--
;
if
(
ptr
->
is_group
)
return
tomoyo_io_printf
(
head
,
" @%s"
,
ptr
->
group
->
group_name
->
name
);
return
tomoyo_io_printf
(
head
,
" %s"
,
ptr
->
filename
->
name
);
}
/**
* tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
*
...
...
@@ -171,6 +214,33 @@ static void tomoyo_normalize_line(unsigned char *buffer)
*
dp
=
'\0'
;
}
/**
* tomoyo_tokenize - Tokenize string.
*
* @buffer: The line to tokenize.
* @w: Pointer to "char *".
* @size: Sizeof @w .
*
* Returns true on success, false otherwise.
*/
bool
tomoyo_tokenize
(
char
*
buffer
,
char
*
w
[],
size_t
size
)
{
int
count
=
size
/
sizeof
(
char
*
);
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
w
[
i
]
=
""
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
char
*
cp
=
strchr
(
buffer
,
' '
);
if
(
cp
)
*
cp
=
'\0'
;
w
[
i
]
=
buffer
;
if
(
!
cp
)
break
;
buffer
=
cp
+
1
;
}
return
i
<
count
||
!*
buffer
;
}
/**
* tomoyo_is_correct_path - Validate a pathname.
* @filename: The pathname to check.
...
...
@@ -874,17 +944,17 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
static
struct
tomoyo_profile
*
tomoyo_find_or_assign_new_profile
(
const
unsigned
int
profile
)
{
static
DEFINE_MUTEX
(
lock
);
struct
tomoyo_profile
*
ptr
=
NULL
;
int
i
;
if
(
profile
>=
TOMOYO_MAX_PROFILES
)
return
NULL
;
mutex_lock
(
&
lock
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
return
NULL
;
ptr
=
tomoyo_profile_ptr
[
profile
];
if
(
ptr
)
goto
ok
;
ptr
=
kmalloc
(
sizeof
(
*
ptr
),
GFP_
KERNEL
);
ptr
=
kmalloc
(
sizeof
(
*
ptr
),
GFP_
NOFS
);
if
(
!
tomoyo_memory_ok
(
ptr
))
{
kfree
(
ptr
);
ptr
=
NULL
;
...
...
@@ -895,7 +965,7 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
mb
();
/* Avoid out-of-order execution. */
tomoyo_profile_ptr
[
profile
]
=
ptr
;
ok:
mutex_unlock
(
&
lock
);
mutex_unlock
(
&
tomoyo_policy_
lock
);
return
ptr
;
}
...
...
@@ -1071,44 +1141,42 @@ LIST_HEAD(tomoyo_policy_manager_list);
static
int
tomoyo_update_manager_entry
(
const
char
*
manager
,
const
bool
is_delete
)
{
struct
tomoyo_policy_manager_entry
*
entry
=
NULL
;
struct
tomoyo_policy_manager_entry
*
ptr
;
const
struct
tomoyo_path_info
*
saved_manager
;
struct
tomoyo_policy_manager_entry
e
=
{
}
;
int
error
=
is_delete
?
-
ENOENT
:
-
ENOMEM
;
bool
is_domain
=
false
;
if
(
tomoyo_is_domain_def
(
manager
))
{
if
(
!
tomoyo_is_correct_domain
(
manager
))
return
-
EINVAL
;
is_domain
=
true
;
e
.
is_domain
=
true
;
}
else
{
if
(
!
tomoyo_is_correct_path
(
manager
,
1
,
-
1
,
-
1
))
return
-
EINVAL
;
}
saved_
manager
=
tomoyo_get_name
(
manager
);
if
(
!
saved_
manager
)
e
.
manager
=
tomoyo_get_name
(
manager
);
if
(
!
e
.
manager
)
return
-
ENOMEM
;
if
(
!
is_delete
)
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
mutex_lock
(
&
tomoyo_policy_lock
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
list_for_each_entry_rcu
(
ptr
,
&
tomoyo_policy_manager_list
,
list
)
{
if
(
ptr
->
manager
!=
saved_
manager
)
if
(
ptr
->
manager
!=
e
.
manager
)
continue
;
ptr
->
is_deleted
=
is_delete
;
error
=
0
;
break
;
}
if
(
!
is_delete
&&
error
&&
tomoyo_memory_ok
(
entry
))
{
entry
->
manager
=
saved_manager
;
saved_manager
=
NULL
;
entry
->
is_domain
=
is_domain
;
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_policy_manager_list
);
entry
=
NULL
;
error
=
0
;
if
(
!
is_delete
&&
error
)
{
struct
tomoyo_policy_manager_entry
*
entry
=
tomoyo_commit_ok
(
&
e
,
sizeof
(
e
));
if
(
entry
)
{
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_policy_manager_list
);
error
=
0
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
tomoyo_put_name
(
saved_manager
);
kfree
(
entry
);
out:
tomoyo_put_name
(
e
.
manager
);
return
error
;
}
...
...
@@ -1287,7 +1355,8 @@ static int tomoyo_delete_domain(char *domainname)
name
.
name
=
domainname
;
tomoyo_fill_path_info
(
&
name
);
mutex_lock
(
&
tomoyo_policy_lock
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
return
0
;
/* Is there an active domain? */
list_for_each_entry_rcu
(
domain
,
&
tomoyo_domain_list
,
list
)
{
/* Never delete tomoyo_kernel_domain */
...
...
@@ -1369,23 +1438,20 @@ static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
{
int
pos
;
u8
bit
;
const
char
*
atmark
=
""
;
const
char
*
filename
;
const
u32
perm
=
ptr
->
perm
|
(((
u32
)
ptr
->
perm_high
)
<<
16
);
filename
=
ptr
->
filename
->
name
;
for
(
bit
=
head
->
read_bit
;
bit
<
TOMOYO_MAX_PATH_OPERATION
;
bit
++
)
{
const
char
*
msg
;
if
(
!
(
perm
&
(
1
<<
bit
)))
continue
;
/* Print "read/write" instead of "read" and "write". */
if
((
bit
==
TOMOYO_TYPE_READ
||
bit
==
TOMOYO_TYPE_WRITE
)
&&
(
perm
&
(
1
<<
TOMOYO_TYPE_READ_WRITE
)))
continue
;
msg
=
tomoyo_path2keyword
(
bit
);
pos
=
head
->
read_avail
;
if
(
!
tomoyo_io_printf
(
head
,
"allow_%s %s%s
\n
"
,
msg
,
atmark
,
filename
))
if
(
!
tomoyo_io_printf
(
head
,
"allow_%s "
,
tomoyo_path2keyword
(
bit
))
||
!
tomoyo_print_name_union
(
head
,
&
ptr
->
name
)
||
!
tomoyo_io_printf
(
head
,
"
\n
"
))
goto
out
;
}
head
->
read_bit
=
0
;
...
...
@@ -1408,23 +1474,18 @@ static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
struct
tomoyo_path2_acl
*
ptr
)
{
int
pos
;
const
char
*
atmark1
=
""
;
const
char
*
atmark2
=
""
;
const
char
*
filename1
;
const
char
*
filename2
;
const
u8
perm
=
ptr
->
perm
;
u8
bit
;
filename1
=
ptr
->
filename1
->
name
;
filename2
=
ptr
->
filename2
->
name
;
for
(
bit
=
head
->
read_bit
;
bit
<
TOMOYO_MAX_PATH2_OPERATION
;
bit
++
)
{
const
char
*
msg
;
if
(
!
(
perm
&
(
1
<<
bit
)))
continue
;
msg
=
tomoyo_path22keyword
(
bit
);
pos
=
head
->
read_avail
;
if
(
!
tomoyo_io_printf
(
head
,
"allow_%s %s%s %s%s
\n
"
,
msg
,
atmark1
,
filename1
,
atmark2
,
filename2
))
if
(
!
tomoyo_io_printf
(
head
,
"allow_%s "
,
tomoyo_path22keyword
(
bit
))
||
!
tomoyo_print_name_union
(
head
,
&
ptr
->
name1
)
||
!
tomoyo_print_name_union
(
head
,
&
ptr
->
name2
)
||
!
tomoyo_io_printf
(
head
,
"
\n
"
))
goto
out
;
}
head
->
read_bit
=
0
;
...
...
@@ -1687,6 +1748,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
return
tomoyo_write_pattern_policy
(
data
,
is_delete
);
if
(
tomoyo_str_starts
(
&
data
,
TOMOYO_KEYWORD_DENY_REWRITE
))
return
tomoyo_write_no_rewrite_policy
(
data
,
is_delete
);
if
(
tomoyo_str_starts
(
&
data
,
TOMOYO_KEYWORD_PATH_GROUP
))
return
tomoyo_write_path_group_policy
(
data
,
is_delete
);
return
-
EINVAL
;
}
...
...
@@ -1743,6 +1806,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
head
->
read_var2
=
NULL
;
head
->
read_step
=
9
;
case
9
:
if
(
!
tomoyo_read_path_group_policy
(
head
))
break
;
head
->
read_var1
=
NULL
;
head
->
read_var2
=
NULL
;
head
->
read_step
=
10
;
case
10
:
head
->
read_eof
=
true
;
break
;
default:
...
...
@@ -1886,7 +1955,7 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
*/
static
int
tomoyo_open_control
(
const
u8
type
,
struct
file
*
file
)
{
struct
tomoyo_io_buffer
*
head
=
kzalloc
(
sizeof
(
*
head
),
GFP_
KERNEL
);
struct
tomoyo_io_buffer
*
head
=
kzalloc
(
sizeof
(
*
head
),
GFP_
NOFS
);
if
(
!
head
)
return
-
ENOMEM
;
...
...
@@ -1947,7 +2016,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
}
else
{
if
(
!
head
->
readbuf_size
)
head
->
readbuf_size
=
4096
*
2
;
head
->
read_buf
=
kzalloc
(
head
->
readbuf_size
,
GFP_
KERNEL
);
head
->
read_buf
=
kzalloc
(
head
->
readbuf_size
,
GFP_
NOFS
);
if
(
!
head
->
read_buf
)
{
kfree
(
head
);
return
-
ENOMEM
;
...
...
@@ -1961,7 +2030,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
head
->
write
=
NULL
;
}
else
if
(
head
->
write
)
{
head
->
writebuf_size
=
4096
*
2
;
head
->
write_buf
=
kzalloc
(
head
->
writebuf_size
,
GFP_
KERNEL
);
head
->
write_buf
=
kzalloc
(
head
->
writebuf_size
,
GFP_
NOFS
);
if
(
!
head
->
write_buf
)
{
kfree
(
head
->
read_buf
);
kfree
(
head
);
...
...
security/tomoyo/common.h
View file @
539c99fd
...
...
@@ -54,6 +54,7 @@ struct linux_binprm;
#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
#define TOMOYO_KEYWORD_PATH_GROUP "path_group "
#define TOMOYO_KEYWORD_SELECT "select "
#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
...
...
@@ -204,6 +205,27 @@ struct tomoyo_path_info_with_data {
char
barrier2
[
16
];
/* Safeguard for overrun. */
};
struct
tomoyo_name_union
{
const
struct
tomoyo_path_info
*
filename
;
struct
tomoyo_path_group
*
group
;
u8
is_group
;
};
/* Structure for "path_group" directive. */
struct
tomoyo_path_group
{
struct
list_head
list
;
const
struct
tomoyo_path_info
*
group_name
;
struct
list_head
member_list
;
atomic_t
users
;
};
/* Structure for "path_group" directive. */
struct
tomoyo_path_group_member
{
struct
list_head
list
;
bool
is_deleted
;
const
struct
tomoyo_path_info
*
member_name
;
};
/*
* tomoyo_acl_info is a structure which is used for holding
*
...
...
@@ -274,7 +296,7 @@ struct tomoyo_domain_info {
*
* (1) "head" which is a "struct tomoyo_acl_info".
* (2) "perm" which is a bitmask of permitted operations.
* (3) "
file
name" is the pathname.
* (3) "name" is the pathname.
*
* Directives held by this structure are "allow_read/write", "allow_execute",
* "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
...
...
@@ -287,8 +309,7 @@ struct tomoyo_path_acl {
struct
tomoyo_acl_info
head
;
/* type = TOMOYO_TYPE_PATH_ACL */
u8
perm_high
;
u16
perm
;
/* Pointer to single pathname. */
const
struct
tomoyo_path_info
*
filename
;
struct
tomoyo_name_union
name
;
};
/*
...
...
@@ -298,8 +319,8 @@ struct tomoyo_path_acl {
*
* (1) "head" which is a "struct tomoyo_acl_info".
* (2) "perm" which is a bitmask of permitted operations.
* (3) "
file
name1" is the source/old pathname.
* (4) "
file
name2" is the destination/new pathname.
* (3) "name1" is the source/old pathname.
* (4) "name2" is the destination/new pathname.
*
* Directives held by this structure are "allow_rename", "allow_link" and
* "allow_pivot_root".
...
...
@@ -307,10 +328,8 @@ struct tomoyo_path_acl {
struct
tomoyo_path2_acl
{
struct
tomoyo_acl_info
head
;
/* type = TOMOYO_TYPE_PATH2_ACL */
u8
perm
;
/* Pointer to single pathname. */
const
struct
tomoyo_path_info
*
filename1
;
/* Pointer to single pathname. */
const
struct
tomoyo_path_info
*
filename2
;
struct
tomoyo_name_union
name1
;
struct
tomoyo_name_union
name2
;
};
/*
...
...
@@ -514,6 +533,9 @@ struct tomoyo_policy_manager_entry {
/********** Function prototypes. **********/
/* Check whether the given name matches the given name_union. */
bool
tomoyo_compare_name_union
(
const
struct
tomoyo_path_info
*
name
,
const
struct
tomoyo_name_union
*
ptr
);
/* Check whether the domain has too many ACL entries to hold. */
bool
tomoyo_domain_quota_is_ok
(
struct
tomoyo_domain_info
*
const
domain
);
/* Transactional sprintf() for policy dump. */
...
...
@@ -526,6 +548,12 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
const
s8
pattern_type
,
const
s8
end_type
);
/* Check whether the token can be a domainname. */
bool
tomoyo_is_domain_def
(
const
unsigned
char
*
buffer
);
bool
tomoyo_parse_name_union
(
const
char
*
filename
,
struct
tomoyo_name_union
*
ptr
);
/* Check whether the given filename matches the given path_group. */
bool
tomoyo_path_matches_group
(
const
struct
tomoyo_path_info
*
pathname
,
const
struct
tomoyo_path_group
*
group
,
const
bool
may_use_pattern
);
/* Check whether the given filename matches the given pattern. */
bool
tomoyo_path_matches_pattern
(
const
struct
tomoyo_path_info
*
filename
,
const
struct
tomoyo_path_info
*
pattern
);
...
...
@@ -540,10 +568,14 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head);
bool
tomoyo_read_domain_keeper_policy
(
struct
tomoyo_io_buffer
*
head
);
/* Read "file_pattern" entry in exception policy. */
bool
tomoyo_read_file_pattern
(
struct
tomoyo_io_buffer
*
head
);
/* Read "path_group" entry in exception policy. */
bool
tomoyo_read_path_group_policy
(
struct
tomoyo_io_buffer
*
head
);
/* Read "allow_read" entry in exception policy. */
bool
tomoyo_read_globally_readable_policy
(
struct
tomoyo_io_buffer
*
head
);
/* Read "deny_rewrite" entry in exception policy. */
bool
tomoyo_read_no_rewrite_policy
(
struct
tomoyo_io_buffer
*
head
);
/* Tokenize a line. */
bool
tomoyo_tokenize
(
char
*
buffer
,
char
*
w
[],
size_t
size
);
/* Write domain policy violation warning message to console? */
bool
tomoyo_verbose_mode
(
const
struct
tomoyo_domain_info
*
domain
);
/* Convert double path operation to operation name. */
...
...
@@ -580,12 +612,18 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete);
int
tomoyo_write_no_rewrite_policy
(
char
*
data
,
const
bool
is_delete
);
/* Create "file_pattern" entry in exception policy. */
int
tomoyo_write_pattern_policy
(
char
*
data
,
const
bool
is_delete
);
/* Create "path_group" entry in exception policy. */
int
tomoyo_write_path_group_policy
(
char
*
data
,
const
bool
is_delete
);
/* Find a domain by the given name. */
struct
tomoyo_domain_info
*
tomoyo_find_domain
(
const
char
*
domainname
);
/* Find or create a domain by the given name. */
struct
tomoyo_domain_info
*
tomoyo_find_or_assign_new_domain
(
const
char
*
domainname
,
const
u8
profile
);
/* Allocate memory for "struct tomoyo_path_group". */
struct
tomoyo_path_group
*
tomoyo_get_path_group
(
const
char
*
group_name
);
/* Check mode for specified functionality. */
unsigned
int
tomoyo_check_flags
(
const
struct
tomoyo_domain_info
*
domain
,
const
u8
index
);
...
...
@@ -616,6 +654,7 @@ char *tomoyo_realpath_from_path(struct path *path);
/* Check memory quota. */
bool
tomoyo_memory_ok
(
void
*
ptr
);
void
*
tomoyo_commit_ok
(
void
*
data
,
const
unsigned
int
size
);
/*
* Keep the given name on the RAM.
...
...
@@ -641,6 +680,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
int
tomoyo_check_rewrite_permission
(
struct
file
*
filp
);
int
tomoyo_find_next_domain
(
struct
linux_binprm
*
bprm
);
/* Drop refcount on tomoyo_name_union. */
void
tomoyo_put_name_union
(
struct
tomoyo_name_union
*
ptr
);
/* Run garbage collector. */
void
tomoyo_run_gc
(
void
);
...
...
@@ -654,6 +696,7 @@ extern struct srcu_struct tomoyo_ss;
/* The list for "struct tomoyo_domain_info". */
extern
struct
list_head
tomoyo_domain_list
;
extern
struct
list_head
tomoyo_path_group_list
;
extern
struct
list_head
tomoyo_domain_initializer_list
;
extern
struct
list_head
tomoyo_domain_keeper_list
;
extern
struct
list_head
tomoyo_alias_list
;
...
...
@@ -662,7 +705,6 @@ extern struct list_head tomoyo_pattern_list;
extern
struct
list_head
tomoyo_no_rewrite_list
;
extern
struct
list_head
tomoyo_policy_manager_list
;
extern
struct
list_head
tomoyo_name_list
[
TOMOYO_MAX_HASH
];
extern
struct
mutex
tomoyo_name_list_lock
;
/* Lock for protecting policy. */
extern
struct
mutex
tomoyo_policy_lock
;
...
...
@@ -725,6 +767,12 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
}
}
static
inline
void
tomoyo_put_path_group
(
struct
tomoyo_path_group
*
group
)
{
if
(
group
)
atomic_dec
(
&
group
->
users
);
}
static
inline
struct
tomoyo_domain_info
*
tomoyo_domain
(
void
)
{
return
current_cred
()
->
security
;
...
...
@@ -736,6 +784,59 @@ static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
return
task_cred_xxx
(
task
,
security
);
}
static
inline
bool
tomoyo_is_same_acl_head
(
const
struct
tomoyo_acl_info
*
p1
,
const
struct
tomoyo_acl_info
*
p2
)
{
return
p1
->
type
==
p2
->
type
;
}
static
inline
bool
tomoyo_is_same_name_union
(
const
struct
tomoyo_name_union
*
p1
,
const
struct
tomoyo_name_union
*
p2
)
{
return
p1
->
filename
==
p2
->
filename
&&
p1
->
group
==
p2
->
group
&&
p1
->
is_group
==
p2
->
is_group
;
}
static
inline
bool
tomoyo_is_same_path_acl
(
const
struct
tomoyo_path_acl
*
p1
,
const
struct
tomoyo_path_acl
*
p2
)
{
return
tomoyo_is_same_acl_head
(
&
p1
->
head
,
&
p2
->
head
)
&&
tomoyo_is_same_name_union
(
&
p1
->
name
,
&
p2
->
name
);
}
static
inline
bool
tomoyo_is_same_path2_acl
(
const
struct
tomoyo_path2_acl
*
p1
,
const
struct
tomoyo_path2_acl
*
p2
)
{
return
tomoyo_is_same_acl_head
(
&
p1
->
head
,
&
p2
->
head
)
&&
tomoyo_is_same_name_union
(
&
p1
->
name1
,
&
p2
->
name1
)
&&
tomoyo_is_same_name_union
(
&
p1
->
name2
,
&
p2
->
name2
);
}
static
inline
bool
tomoyo_is_same_domain_initializer_entry
(
const
struct
tomoyo_domain_initializer_entry
*
p1
,
const
struct
tomoyo_domain_initializer_entry
*
p2
)
{
return
p1
->
is_not
==
p2
->
is_not
&&
p1
->
is_last_name
==
p2
->
is_last_name
&&
p1
->
domainname
==
p2
->
domainname
&&
p1
->
program
==
p2
->
program
;
}
static
inline
bool
tomoyo_is_same_domain_keeper_entry
(
const
struct
tomoyo_domain_keeper_entry
*
p1
,
const
struct
tomoyo_domain_keeper_entry
*
p2
)
{
return
p1
->
is_not
==
p2
->
is_not
&&
p1
->
is_last_name
==
p2
->
is_last_name
&&
p1
->
domainname
==
p2
->
domainname
&&
p1
->
program
==
p2
->
program
;
}
static
inline
bool
tomoyo_is_same_alias_entry
(
const
struct
tomoyo_alias_entry
*
p1
,
const
struct
tomoyo_alias_entry
*
p2
)
{
return
p1
->
original_name
==
p2
->
original_name
&&
p1
->
aliased_name
==
p2
->
aliased_name
;
}
/**
* list_for_each_cookie - iterate over a list with cookie.
* @pos: the &struct list_head to use as a loop cursor.
...
...
security/tomoyo/domain.c
View file @
539c99fd
...
...
@@ -130,57 +130,47 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
const
bool
is_not
,
const
bool
is_delete
)
{
struct
tomoyo_domain_initializer_entry
*
entry
=
NULL
;
struct
tomoyo_domain_initializer_entry
*
ptr
;
const
struct
tomoyo_path_info
*
saved_program
=
NULL
;
const
struct
tomoyo_path_info
*
saved_domainname
=
NULL
;
struct
tomoyo_domain_initializer_entry
e
=
{
.
is_not
=
is_not
};
int
error
=
is_delete
?
-
ENOENT
:
-
ENOMEM
;
bool
is_last_name
=
false
;
if
(
!
tomoyo_is_correct_path
(
program
,
1
,
-
1
,
-
1
))
return
-
EINVAL
;
/* No patterns allowed. */
if
(
domainname
)
{
if
(
!
tomoyo_is_domain_def
(
domainname
)
&&
tomoyo_is_correct_path
(
domainname
,
1
,
-
1
,
-
1
))
is_last_name
=
true
;
e
.
is_last_name
=
true
;
else
if
(
!
tomoyo_is_correct_domain
(
domainname
))
return
-
EINVAL
;
saved_
domainname
=
tomoyo_get_name
(
domainname
);
if
(
!
saved_
domainname
)
e
.
domainname
=
tomoyo_get_name
(
domainname
);
if
(
!
e
.
domainname
)
goto
out
;
}
saved_program
=
tomoyo_get_name
(
program
);
if
(
!
saved_program
)
e
.
program
=
tomoyo_get_name
(
program
);
if
(
!
e
.
program
)
goto
out
;
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
if
(
!
is_delete
)
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
mutex_lock
(
&
tomoyo_policy_lock
);
list_for_each_entry_rcu
(
ptr
,
&
tomoyo_domain_initializer_list
,
list
)
{
if
(
ptr
->
is_not
!=
is_not
||
ptr
->
domainname
!=
saved_domainname
||
ptr
->
program
!=
saved_program
)
if
(
!
tomoyo_is_same_domain_initializer_entry
(
ptr
,
&
e
))
continue
;
ptr
->
is_deleted
=
is_delete
;
error
=
0
;
break
;
}
if
(
!
is_delete
&&
error
&&
tomoyo_memory_ok
(
entry
))
{
entry
->
domainname
=
saved_domainname
;
saved_domainname
=
NULL
;
entry
->
program
=
saved_program
;
saved_program
=
NULL
;
entry
->
is_not
=
is_not
;
entry
->
is_last_name
=
is_last_name
;
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_domain_initializer_list
);
entry
=
NULL
;
error
=
0
;
if
(
!
is_delete
&&
error
)
{
struct
tomoyo_domain_initializer_entry
*
entry
=
tomoyo_commit_ok
(
&
e
,
sizeof
(
e
));
if
(
entry
)
{
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_domain_initializer_list
);
error
=
0
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
saved_domainname
);
tomoyo_put_name
(
saved_program
);
kfree
(
entry
);
tomoyo_put_name
(
e
.
domainname
);
tomoyo_put_name
(
e
.
program
);
return
error
;
}
...
...
@@ -350,56 +340,47 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
const
bool
is_not
,
const
bool
is_delete
)
{
struct
tomoyo_domain_keeper_entry
*
entry
=
NULL
;
struct
tomoyo_domain_keeper_entry
*
ptr
;
const
struct
tomoyo_path_info
*
saved_domainname
=
NULL
;
const
struct
tomoyo_path_info
*
saved_program
=
NULL
;
struct
tomoyo_domain_keeper_entry
e
=
{
.
is_not
=
is_not
};
int
error
=
is_delete
?
-
ENOENT
:
-
ENOMEM
;
bool
is_last_name
=
false
;
if
(
!
tomoyo_is_domain_def
(
domainname
)
&&
tomoyo_is_correct_path
(
domainname
,
1
,
-
1
,
-
1
))
is_last_name
=
true
;
e
.
is_last_name
=
true
;
else
if
(
!
tomoyo_is_correct_domain
(
domainname
))
return
-
EINVAL
;
if
(
program
)
{
if
(
!
tomoyo_is_correct_path
(
program
,
1
,
-
1
,
-
1
))
return
-
EINVAL
;
saved_
program
=
tomoyo_get_name
(
program
);
if
(
!
saved_
program
)
e
.
program
=
tomoyo_get_name
(
program
);
if
(
!
e
.
program
)
goto
out
;
}
saved_domainname
=
tomoyo_get_name
(
domainname
);
if
(
!
saved_domainname
)
e
.
domainname
=
tomoyo_get_name
(
domainname
);
if
(
!
e
.
domainname
)
goto
out
;
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
if
(
!
is_delete
)
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
mutex_lock
(
&
tomoyo_policy_lock
);
list_for_each_entry_rcu
(
ptr
,
&
tomoyo_domain_keeper_list
,
list
)
{
if
(
ptr
->
is_not
!=
is_not
||
ptr
->
domainname
!=
saved_domainname
||
ptr
->
program
!=
saved_program
)
if
(
!
tomoyo_is_same_domain_keeper_entry
(
ptr
,
&
e
))
continue
;
ptr
->
is_deleted
=
is_delete
;
error
=
0
;
break
;
}
if
(
!
is_delete
&&
error
&&
tomoyo_memory_ok
(
entry
))
{
entry
->
domainname
=
saved_domainname
;
saved_domainname
=
NULL
;
entry
->
program
=
saved_program
;
saved_program
=
NULL
;
entry
->
is_not
=
is_not
;
entry
->
is_last_name
=
is_last_name
;
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_domain_keeper_list
);
entry
=
NULL
;
error
=
0
;
if
(
!
is_delete
&&
error
)
{
struct
tomoyo_domain_keeper_entry
*
entry
=
tomoyo_commit_ok
(
&
e
,
sizeof
(
e
));
if
(
entry
)
{
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_domain_keeper_list
);
error
=
0
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
saved_domainname
);
tomoyo_put_name
(
saved_program
);
kfree
(
entry
);
tomoyo_put_name
(
e
.
domainname
);
tomoyo_put_name
(
e
.
program
);
return
error
;
}
...
...
@@ -551,44 +532,38 @@ static int tomoyo_update_alias_entry(const char *original_name,
const
char
*
aliased_name
,
const
bool
is_delete
)
{
struct
tomoyo_alias_entry
*
entry
=
NULL
;
struct
tomoyo_alias_entry
*
ptr
;
const
struct
tomoyo_path_info
*
saved_original_name
;
const
struct
tomoyo_path_info
*
saved_aliased_name
;
struct
tomoyo_alias_entry
e
=
{
};
int
error
=
is_delete
?
-
ENOENT
:
-
ENOMEM
;
if
(
!
tomoyo_is_correct_path
(
original_name
,
1
,
-
1
,
-
1
)
||
!
tomoyo_is_correct_path
(
aliased_name
,
1
,
-
1
,
-
1
))
return
-
EINVAL
;
/* No patterns allowed. */
saved_original_name
=
tomoyo_get_name
(
original_name
);
saved_aliased_name
=
tomoyo_get_name
(
aliased_name
);
if
(
!
saved_original_name
||
!
saved_aliased_name
)
e
.
original_name
=
tomoyo_get_name
(
original_name
);
e
.
aliased_name
=
tomoyo_get_name
(
aliased_name
);
if
(
!
e
.
original_name
||
!
e
.
aliased_name
)
goto
out
;
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
if
(
!
is_delete
)
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
mutex_lock
(
&
tomoyo_policy_lock
);
list_for_each_entry_rcu
(
ptr
,
&
tomoyo_alias_list
,
list
)
{
if
(
ptr
->
original_name
!=
saved_original_name
||
ptr
->
aliased_name
!=
saved_aliased_name
)
if
(
!
tomoyo_is_same_alias_entry
(
ptr
,
&
e
))
continue
;
ptr
->
is_deleted
=
is_delete
;
error
=
0
;
break
;
}
if
(
!
is_delete
&&
error
&&
tomoyo_memory_ok
(
entry
))
{
entry
->
original_name
=
saved_original_name
;
saved_original_name
=
NULL
;
entry
->
aliased_name
=
saved_aliased_name
;
saved_aliased_name
=
NULL
;
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_alias_list
);
entry
=
NULL
;
error
=
0
;
if
(
!
is_delete
&&
error
)
{
struct
tomoyo_alias_entry
*
entry
=
tomoyo_commit_ok
(
&
e
,
sizeof
(
e
));
if
(
entry
)
{
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_alias_list
);
error
=
0
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
saved_original_name
);
tomoyo_put_name
(
saved_aliased_name
);
kfree
(
entry
);
tomoyo_put_name
(
e
.
original_name
);
tomoyo_put_name
(
e
.
aliased_name
);
return
error
;
}
...
...
@@ -656,7 +631,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
const
u8
profile
)
{
struct
tomoyo_domain_info
*
entry
;
struct
tomoyo_domain_info
*
domain
;
struct
tomoyo_domain_info
*
domain
=
NULL
;
const
struct
tomoyo_path_info
*
saved_domainname
;
bool
found
=
false
;
...
...
@@ -665,8 +640,9 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
saved_domainname
=
tomoyo_get_name
(
domainname
);
if
(
!
saved_domainname
)
return
NULL
;
entry
=
kzalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
mutex_lock
(
&
tomoyo_policy_lock
);
entry
=
kzalloc
(
sizeof
(
*
entry
),
GFP_NOFS
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
list_for_each_entry_rcu
(
domain
,
&
tomoyo_domain_list
,
list
)
{
if
(
domain
->
is_deleted
||
tomoyo_pathcmp
(
saved_domainname
,
domain
->
domainname
))
...
...
@@ -685,6 +661,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
found
=
true
;
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
saved_domainname
);
kfree
(
entry
);
return
found
?
domain
:
NULL
;
...
...
@@ -705,7 +682,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
* This function assumes that the size of buffer returned by
* tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
*/
struct
tomoyo_page_buffer
*
tmp
=
kzalloc
(
sizeof
(
*
tmp
),
GFP_
KERNEL
);
struct
tomoyo_page_buffer
*
tmp
=
kzalloc
(
sizeof
(
*
tmp
),
GFP_
NOFS
);
struct
tomoyo_domain_info
*
old_domain
=
tomoyo_domain
();
struct
tomoyo_domain_info
*
domain
=
NULL
;
const
char
*
old_domain_name
=
old_domain
->
domainname
->
name
;
...
...
security/tomoyo/file.c
View file @
539c99fd
This diff is collapsed.
Click to expand it.
security/tomoyo/gc.c
View file @
539c99fd
...
...
@@ -12,6 +12,8 @@
#include <linux/slab.h>
enum
tomoyo_gc_id
{
TOMOYO_ID_PATH_GROUP
,
TOMOYO_ID_PATH_GROUP_MEMBER
,
TOMOYO_ID_DOMAIN_INITIALIZER
,
TOMOYO_ID_DOMAIN_KEEPER
,
TOMOYO_ID_ALIAS
,
...
...
@@ -91,15 +93,15 @@ static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
{
struct
tomoyo_path_acl
*
entry
=
container_of
(
acl
,
typeof
(
*
entry
),
head
);
tomoyo_put_name
(
entry
->
file
name
);
tomoyo_put_name
_union
(
&
entry
->
name
);
}
break
;
case
TOMOYO_TYPE_PATH2_ACL
:
{
struct
tomoyo_path2_acl
*
entry
=
container_of
(
acl
,
typeof
(
*
entry
),
head
);
tomoyo_put_name
(
entry
->
file
name1
);
tomoyo_put_name
(
entry
->
file
name2
);
tomoyo_put_name
_union
(
&
entry
->
name1
);
tomoyo_put_name
_union
(
&
entry
->
name2
);
}
break
;
default:
...
...
@@ -149,9 +151,21 @@ static void tomoyo_del_name(const struct tomoyo_name_entry *ptr)
{
}
static
void
tomoyo_del_path_group_member
(
struct
tomoyo_path_group_member
*
member
)
{
tomoyo_put_name
(
member
->
member_name
);
}
static
void
tomoyo_del_path_group
(
struct
tomoyo_path_group
*
group
)
{
tomoyo_put_name
(
group
->
group_name
);
}
static
void
tomoyo_collect_entry
(
void
)
{
mutex_lock
(
&
tomoyo_policy_lock
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
return
;
{
struct
tomoyo_globally_readable_file_entry
*
ptr
;
list_for_each_entry_rcu
(
ptr
,
&
tomoyo_globally_readable_list
,
...
...
@@ -275,8 +289,6 @@ static void tomoyo_collect_entry(void)
break
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
mutex_lock
(
&
tomoyo_name_list_lock
);
{
int
i
;
for
(
i
=
0
;
i
<
TOMOYO_MAX_HASH
;
i
++
)
{
...
...
@@ -294,7 +306,30 @@ static void tomoyo_collect_entry(void)
}
}
}
mutex_unlock
(
&
tomoyo_name_list_lock
);
{
struct
tomoyo_path_group
*
group
;
list_for_each_entry_rcu
(
group
,
&
tomoyo_path_group_list
,
list
)
{
struct
tomoyo_path_group_member
*
member
;
list_for_each_entry_rcu
(
member
,
&
group
->
member_list
,
list
)
{
if
(
!
member
->
is_deleted
)
continue
;
if
(
tomoyo_add_to_gc
(
TOMOYO_ID_PATH_GROUP_MEMBER
,
member
))
list_del_rcu
(
&
member
->
list
);
else
break
;
}
if
(
!
list_empty
(
&
group
->
member_list
)
||
atomic_read
(
&
group
->
users
))
continue
;
if
(
tomoyo_add_to_gc
(
TOMOYO_ID_PATH_GROUP
,
group
))
list_del_rcu
(
&
group
->
list
);
else
break
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
}
static
void
tomoyo_kfree_entry
(
void
)
...
...
@@ -335,6 +370,12 @@ static void tomoyo_kfree_entry(void)
if
(
!
tomoyo_del_domain
(
p
->
element
))
continue
;
break
;
case
TOMOYO_ID_PATH_GROUP_MEMBER
:
tomoyo_del_path_group_member
(
p
->
element
);
break
;
case
TOMOYO_ID_PATH_GROUP
:
tomoyo_del_path_group
(
p
->
element
);
break
;
default:
printk
(
KERN_WARNING
"Unknown type
\n
"
);
break
;
...
...
security/tomoyo/path_group.c
0 → 100644
View file @
539c99fd
/*
* security/tomoyo/path_group.c
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*/
#include <linux/slab.h>
#include "common.h"
/* The list for "struct ccs_path_group". */
LIST_HEAD
(
tomoyo_path_group_list
);
/**
* tomoyo_get_path_group - Allocate memory for "struct tomoyo_path_group".
*
* @group_name: The name of pathname group.
*
* Returns pointer to "struct tomoyo_path_group" on success, NULL otherwise.
*/
struct
tomoyo_path_group
*
tomoyo_get_path_group
(
const
char
*
group_name
)
{
struct
tomoyo_path_group
*
entry
=
NULL
;
struct
tomoyo_path_group
*
group
=
NULL
;
const
struct
tomoyo_path_info
*
saved_group_name
;
int
error
=
-
ENOMEM
;
if
(
!
tomoyo_is_correct_path
(
group_name
,
0
,
0
,
0
)
||
!
group_name
[
0
])
return
NULL
;
saved_group_name
=
tomoyo_get_name
(
group_name
);
if
(
!
saved_group_name
)
return
NULL
;
entry
=
kzalloc
(
sizeof
(
*
entry
),
GFP_NOFS
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
list_for_each_entry_rcu
(
group
,
&
tomoyo_path_group_list
,
list
)
{
if
(
saved_group_name
!=
group
->
group_name
)
continue
;
atomic_inc
(
&
group
->
users
);
error
=
0
;
break
;
}
if
(
error
&&
tomoyo_memory_ok
(
entry
))
{
INIT_LIST_HEAD
(
&
entry
->
member_list
);
entry
->
group_name
=
saved_group_name
;
saved_group_name
=
NULL
;
atomic_set
(
&
entry
->
users
,
1
);
list_add_tail_rcu
(
&
entry
->
list
,
&
tomoyo_path_group_list
);
group
=
entry
;
entry
=
NULL
;
error
=
0
;
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
saved_group_name
);
kfree
(
entry
);
return
!
error
?
group
:
NULL
;
}
/**
* tomoyo_write_path_group_policy - Write "struct tomoyo_path_group" list.
*
* @data: String to parse.
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, nagative value otherwise.
*/
int
tomoyo_write_path_group_policy
(
char
*
data
,
const
bool
is_delete
)
{
struct
tomoyo_path_group
*
group
;
struct
tomoyo_path_group_member
*
member
;
struct
tomoyo_path_group_member
e
=
{
};
int
error
=
is_delete
?
-
ENOENT
:
-
ENOMEM
;
char
*
w
[
2
];
if
(
!
tomoyo_tokenize
(
data
,
w
,
sizeof
(
w
))
||
!
w
[
1
][
0
])
return
-
EINVAL
;
group
=
tomoyo_get_path_group
(
w
[
0
]);
if
(
!
group
)
return
-
ENOMEM
;
e
.
member_name
=
tomoyo_get_name
(
w
[
1
]);
if
(
!
e
.
member_name
)
goto
out
;
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
goto
out
;
list_for_each_entry_rcu
(
member
,
&
group
->
member_list
,
list
)
{
if
(
member
->
member_name
!=
e
.
member_name
)
continue
;
member
->
is_deleted
=
is_delete
;
error
=
0
;
break
;
}
if
(
!
is_delete
&&
error
)
{
struct
tomoyo_path_group_member
*
entry
=
tomoyo_commit_ok
(
&
e
,
sizeof
(
e
));
if
(
entry
)
{
list_add_tail_rcu
(
&
entry
->
list
,
&
group
->
member_list
);
error
=
0
;
}
}
mutex_unlock
(
&
tomoyo_policy_lock
);
out:
tomoyo_put_name
(
e
.
member_name
);
tomoyo_put_path_group
(
group
);
return
error
;
}
/**
* tomoyo_read_path_group_policy - Read "struct tomoyo_path_group" list.
*
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool
tomoyo_read_path_group_policy
(
struct
tomoyo_io_buffer
*
head
)
{
struct
list_head
*
gpos
;
struct
list_head
*
mpos
;
list_for_each_cookie
(
gpos
,
head
->
read_var1
,
&
tomoyo_path_group_list
)
{
struct
tomoyo_path_group
*
group
;
group
=
list_entry
(
gpos
,
struct
tomoyo_path_group
,
list
);
list_for_each_cookie
(
mpos
,
head
->
read_var2
,
&
group
->
member_list
)
{
struct
tomoyo_path_group_member
*
member
;
member
=
list_entry
(
mpos
,
struct
tomoyo_path_group_member
,
list
);
if
(
member
->
is_deleted
)
continue
;
if
(
!
tomoyo_io_printf
(
head
,
TOMOYO_KEYWORD_PATH_GROUP
"%s %s
\n
"
,
group
->
group_name
->
name
,
member
->
member_name
->
name
))
return
false
;
}
}
return
true
;
}
/**
* tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
*
* @pathname: The name of pathname.
* @group: Pointer to "struct tomoyo_path_group".
* @may_use_pattern: True if wild card is permitted.
*
* Returns true if @pathname matches pathnames in @group, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool
tomoyo_path_matches_group
(
const
struct
tomoyo_path_info
*
pathname
,
const
struct
tomoyo_path_group
*
group
,
const
bool
may_use_pattern
)
{
struct
tomoyo_path_group_member
*
member
;
bool
matched
=
false
;
list_for_each_entry_rcu
(
member
,
&
group
->
member_list
,
list
)
{
if
(
member
->
is_deleted
)
continue
;
if
(
!
member
->
member_name
->
is_patterned
)
{
if
(
tomoyo_pathcmp
(
pathname
,
member
->
member_name
))
continue
;
}
else
if
(
may_use_pattern
)
{
if
(
!
tomoyo_path_matches_pattern
(
pathname
,
member
->
member_name
))
continue
;
}
else
continue
;
matched
=
true
;
break
;
}
return
matched
;
}
security/tomoyo/realpath.c
View file @
539c99fd
...
...
@@ -139,7 +139,7 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
*/
char
*
tomoyo_realpath_from_path
(
struct
path
*
path
)
{
char
*
buf
=
kzalloc
(
sizeof
(
struct
tomoyo_page_buffer
),
GFP_
KERNEL
);
char
*
buf
=
kzalloc
(
sizeof
(
struct
tomoyo_page_buffer
),
GFP_
NOFS
);
BUILD_BUG_ON
(
sizeof
(
struct
tomoyo_page_buffer
)
<=
TOMOYO_MAX_PATHNAME_LEN
-
1
);
...
...
@@ -222,6 +222,25 @@ bool tomoyo_memory_ok(void *ptr)
return
false
;
}
/**
* tomoyo_commit_ok - Check memory quota.
*
* @data: Data to copy from.
* @size: Size in byte.
*
* Returns pointer to allocated memory on success, NULL otherwise.
*/
void
*
tomoyo_commit_ok
(
void
*
data
,
const
unsigned
int
size
)
{
void
*
ptr
=
kzalloc
(
size
,
GFP_NOFS
);
if
(
tomoyo_memory_ok
(
ptr
))
{
memmove
(
ptr
,
data
,
size
);
memset
(
data
,
0
,
size
);
return
ptr
;
}
return
NULL
;
}
/**
* tomoyo_memory_free - Free memory for elements.
*
...
...
@@ -240,8 +259,6 @@ void tomoyo_memory_free(void *ptr)
* "const struct tomoyo_path_info *".
*/
struct
list_head
tomoyo_name_list
[
TOMOYO_MAX_HASH
];
/* Lock for protecting tomoyo_name_list . */
DEFINE_MUTEX
(
tomoyo_name_list_lock
);
/**
* tomoyo_get_name - Allocate permanent memory for string data.
...
...
@@ -263,14 +280,15 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
len
=
strlen
(
name
)
+
1
;
hash
=
full_name_hash
((
const
unsigned
char
*
)
name
,
len
-
1
);
head
=
&
tomoyo_name_list
[
hash_long
(
hash
,
TOMOYO_HASH_BITS
)];
mutex_lock
(
&
tomoyo_name_list_lock
);
if
(
mutex_lock_interruptible
(
&
tomoyo_policy_lock
))
return
NULL
;
list_for_each_entry
(
ptr
,
head
,
list
)
{
if
(
hash
!=
ptr
->
entry
.
hash
||
strcmp
(
name
,
ptr
->
entry
.
name
))
continue
;
atomic_inc
(
&
ptr
->
users
);
goto
out
;
}
ptr
=
kzalloc
(
sizeof
(
*
ptr
)
+
len
,
GFP_
KERNEL
);
ptr
=
kzalloc
(
sizeof
(
*
ptr
)
+
len
,
GFP_
NOFS
);
allocated_len
=
ptr
?
ksize
(
ptr
)
:
0
;
if
(
!
ptr
||
(
tomoyo_quota_for_policy
&&
atomic_read
(
&
tomoyo_policy_memory_size
)
+
allocated_len
...
...
@@ -290,7 +308,7 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
tomoyo_fill_path_info
(
&
ptr
->
entry
);
list_add_tail
(
&
ptr
->
list
,
head
);
out:
mutex_unlock
(
&
tomoyo_
name_list
_lock
);
mutex_unlock
(
&
tomoyo_
policy
_lock
);
return
ptr
?
&
ptr
->
entry
:
NULL
;
}
...
...
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