Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Simon Ruderich
passt-mac
Commits
dda9b53f
Commit
dda9b53f
authored
Apr 15, 2016
by
Simon Ruderich
Browse files
slsm: add protect flag disallowing LD_PRELOAD and ptrace
Tests still missing.
parent
30ba7b2b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Documentation/security/slsm.txt
View file @
dda9b53f
...
...
@@ -33,6 +33,8 @@ bits (`x` is not necessary to `cd`) and a set of SLSM-specific flags:
* If a program `A` execs program `B` and the `inherit` flag applies for `A` at
`B`, the process inherits `A`s permissions. `B` is then confined to those
permissions in the above sense.
* The `protect` flag prevents other programs from ptracing or injecting
functions using `LD_PRELOAD` into the protected process.
# Interface #
...
...
@@ -45,7 +47,7 @@ Currently available flags are
* `m` bit mask indicating the access mode (read is 4, write is 2, execute is 1)
* `a` the absolute path to the program this rule should apply to (optional)
* `f` SLSM-specific flags described above, `inherit` is 1, `confine` is 2,
`exact` is 4
`exact` is 4
, `protect` is 8 (optional)
# Examples #
...
...
@@ -53,7 +55,9 @@ Currently available flags are
For convenience, we store all our private keys in a separate directory
`~/.ssh/private` and want to prevent all programs except `/usr/bin/ssh-add`
from reading the files contained therein, but allow listing the keys:
from reading the files contained therein, but allow listing the keys. Also
nobody must be able to debug/inject code into `ssh-add` or the protection can
easily be circumvented.
1. shut everyone out:
p=/home/user/.ssh/private\0m=0\0\0
...
...
@@ -61,11 +65,13 @@ from reading the files contained therein, but allow listing the keys:
p=/home/user/.ssh/private\0m=4\0f=4\0\0
3. allow `ssh-add` to read file contents:
p=/home/user/.ssh/private\0m=4\0a=/usr/bin/ssh-add\0\0
4. prevent anybody from ptracing/`LD_PRELOAD`ing ssh-add
p=/usr/bin/ssh-add\0m=7\0f=8\0\0
To apply this setup, run something like the following (replace user with your
user name):
printf 'p=/home/user/.ssh/private\0m=0\0\0p=/home/user/.ssh/private\0m=4\0f=4\0\0p=/home/user/.ssh/private\0m=4\0a=/usr/bin/ssh-add\0\0' >/sys/kernel/security/slsm/profiles
printf 'p=/home/user/.ssh/private\0m=0\0\0p=/home/user/.ssh/private\0m=4\0f=4\0\0p=/home/user/.ssh/private\0m=4\0a=/usr/bin/ssh-add\0\
0p=/usr/bin/ssh-add\0m=7\0f=8\0\
0' >/sys/kernel/security/slsm/profiles
## Restricting a media player ##
...
...
security/slsm/lsm.c
View file @
dda9b53f
...
...
@@ -25,6 +25,15 @@ struct passt_task {
};
static
struct
passt_task
*
task_security
(
const
struct
task_struct
*
t
)
{
struct
passt_task
*
s
;
rcu_read_lock
();
s
=
__task_cred
(
t
)
->
security
;
rcu_read_unlock
();
return
s
;
}
/**
* passt_dup_task - duplicates all resources related to @old_pt
*
...
...
@@ -96,6 +105,7 @@ static int passt_bprm_set_creds(struct linux_binprm *bprm) {
char
*
buffer
=
NULL
;
const
char
*
name
=
NULL
;
int
error
=
0
;
const
char
*
reason
=
""
;
struct
slsm_perms
perms
;
if
(
bprm
->
cred_prepared
)
...
...
@@ -111,6 +121,34 @@ static int passt_bprm_set_creds(struct linux_binprm *bprm) {
perms
=
slsm_query_perms
(
name
,
pt
->
label
);
if
(
perms
.
mode
&
SLSM_MODE_X
)
{
int
unsafe
=
bprm
->
unsafe
;
int
ptrace_mask
=
LSM_UNSAFE_PTRACE
|
LSM_UNSAFE_PTRACE_CAP
;
if
((
unsafe
&
ptrace_mask
)
&&
(
perms
.
flags
&
SLSM_FLAG_PROTECT
))
{
error
=
-
EPERM
;
reason
=
" (ptrace not allowed)"
;
goto
audit
;
}
unsafe
&=
~
ptrace_mask
;
/* TODO: LSM_UNSAFE_SHARE is set for init on boot, ignore then
* but respect (-> -EPERM) later? */
unsafe
&=
~
LSM_UNSAFE_SHARE
;
/* Ensure processes which use prctl(PR_SET_NO_NEW_PRIVS) will
* never get more privileges. */
if
(
unsafe
&
LSM_UNSAFE_NO_NEW_PRIVS
)
{
pt
->
confined
=
1
;
}
unsafe
&=
~
LSM_UNSAFE_NO_NEW_PRIVS
;
/* Any other unchecked unsafe bits left? */
if
(
unsafe
)
{
error
=
-
EPERM
;
reason
=
" (unsafe)"
;
goto
audit
;
}
if
(
pt
->
confined
||
(
perms
.
flags
&
SLSM_FLAG_INHERIT
))
{
pt
->
confined
=
1
;
printk
(
KERN_INFO
"slsm: %s inherited %s
\n
"
,
name
,
pt
->
label
);
...
...
@@ -136,7 +174,7 @@ static int passt_bprm_set_creds(struct linux_binprm *bprm) {
audit:
/* TODO: log stuff properly */
printk
(
KERN_INFO
"DENIED: %s exec %s
\n
"
,
pt
->
label
,
name
);
printk
(
KERN_INFO
"DENIED: %s exec
%s
%s
\n
"
,
pt
->
label
,
name
,
reason
);
cleanup:
kfree
(
buffer
);
...
...
@@ -153,14 +191,69 @@ static void passt_bprm_committing_creds(struct linux_binprm *bprm) {
}
/**
* passt_bprm_secureexec - determine if secureexec is needed
* passt_bprm_secureexec - determine if secureexec is needed which disables
* e.g. LD_PRELOAD
* @bprm: binprm for exec (NOT NULL)
*
* Returns: %1 if secureexec is needed else %0
*/
static
int
passt_bprm_secureexec
(
struct
linux_binprm
*
bprm
)
{
// TODO: what's secureexec?
struct
passt_task
*
pt
=
current_security
();
char
*
buffer
=
NULL
;
const
char
*
name
=
NULL
;
struct
slsm_perms
perms
;
int
ret
=
0
;
/* buffer freed below, name is pointer into buffer */
name
=
passt_get_path
(
&
bprm
->
file
->
f_path
,
&
buffer
);
if
(
IS_ERR
(
name
))
{
ret
=
1
;
/* set secureexec to prevent possible attacks */
name
=
bprm
->
filename
;
goto
cleanup
;
}
perms
=
slsm_query_perms
(
name
,
pt
->
label
);
if
(
perms
.
flags
&
SLSM_FLAG_PROTECT
)
{
ret
=
1
;
/* set secureexec */
}
cleanup:
kfree
(
buffer
);
if
(
ret
)
{
printk
(
KERN_INFO
"slsm: secureexec for %s
\n
"
,
name
);
}
return
ret
;
}
static
int
passt_ptrace_access_check
(
struct
task_struct
*
child
,
unsigned
int
mode
)
{
struct
passt_task
*
pt
=
current_security
();
struct
passt_task
*
pt_child
=
task_security
(
child
);
struct
slsm_perms
perms
;
/* NOTE: We're using the (inherited) program label here, not the
* actual path to the binary. */
perms
=
slsm_query_perms
(
pt_child
->
label
,
pt
->
label
);
if
(
perms
.
flags
&
SLSM_FLAG_PROTECT
)
{
printk
(
KERN_INFO
"slsm: preventing ptrace of %s (label)
\n
"
,
pt_child
->
label
);
return
-
EPERM
;
}
return
0
;
}
static
int
passt_ptrace_traceme
(
struct
task_struct
*
parent
)
{
struct
passt_task
*
pt
=
current_security
();
struct
passt_task
*
pt_parent
=
task_security
(
parent
);
struct
slsm_perms
perms
;
/* NOTE: We're using the (inherited) program label here, not the
* actual path to the binary. */
perms
=
slsm_query_perms
(
pt
->
label
,
pt_parent
->
label
);
if
(
perms
.
flags
&
SLSM_FLAG_PROTECT
)
{
printk
(
KERN_INFO
"slsm: preventing ptrace of %s (label)
\n
"
,
pt
->
label
);
return
-
EPERM
;
}
return
0
;
}
...
...
@@ -306,8 +399,8 @@ static int passt_unix_may_send(struct socket *sock, struct socket *other) {
static
struct
security_hook_list
passt_hooks
[]
=
{
/*
LSM_HOOK_INIT(ptrace_access_check, passt_ptrace_access_check),
*/
/*
LSM_HOOK_INIT(ptrace_traceme, passt_ptrace_traceme),
*/
LSM_HOOK_INIT
(
ptrace_access_check
,
passt_ptrace_access_check
),
LSM_HOOK_INIT
(
ptrace_traceme
,
passt_ptrace_traceme
),
/* LSM_HOOK_INIT(capget, passt_capget), */
/* LSM_HOOK_INIT(capable, passt_capable), */
...
...
security/slsm/tree.c
View file @
dda9b53f
...
...
@@ -157,7 +157,7 @@ unsigned slsm_perms_mode_grant(struct slsm_perms perms, struct slsm_perms perms_
unsigned
slsm_perms_would_elevate
(
struct
slsm_perms
perms
,
struct
slsm_perms
perms_would_get
)
{
unsigned
flags
,
flags_would_get
;
unsigned
restrictions
=
SLSM_FLAG_INHERIT
|
SLSM_FLAG_CONFINE
;
unsigned
restrictions
=
SLSM_FLAG_INHERIT
|
SLSM_FLAG_CONFINE
|
SLSM_FLAG_PROTECT
;
if
(
!
slsm_perms_mode_grant
(
perms
,
perms_would_get
))
return
1
;
...
...
security/slsm/tree.h
View file @
dda9b53f
...
...
@@ -43,6 +43,7 @@ struct tree_node {
#define SLSM_FLAG_INHERIT (1 << 0)
#define SLSM_FLAG_CONFINE (1 << 1)
#define SLSM_FLAG_EXACT (1 << 2)
#define SLSM_FLAG_PROTECT (1 << 3)
/* NOTE: when adding new flags adapt slsm_perms_would_elevate() */
struct
slsm_perms
{
...
...
Write
Preview
Supports
Markdown
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