-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcve-2016-0728.stp
More file actions
85 lines (73 loc) · 2.56 KB
/
cve-2016-0728.stp
File metadata and controls
85 lines (73 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#! /usr/bin/stap -gv
/* A systemtap emergency band-aid for CVE-2016-0728.
fche@redhat.com & wmealing@redhat.com
*/
/* Default behavior: trace but don't fix problem. */
global trace_p = 1 /* or else: stap -G trace_p=0 */
global fix_p = 0 /* or else: stap -G fix_p=1 */
probe kernel.statement("join_session_keyring@*+44") !,
kernel.function("join_session_keyring").label("error2")
{
/* NB: if the DWARF debuginfo were more perfect, we should be able
to refer directly to $keyring/$new, local variables still
technically in scope. On some kernels/gcc combinations, that
works fine. On others, it doesn't, so this script tries to
support both. */
if (@defined($keyring))
keyring = $keyring
else {
if (! warned_keyrings_p++)
warn("Using find_keyring_by_name $return heuristic for $keyring")
keyring = keyrings[tid()]
}
if (@defined($new))
new = $new
else {
if (! warned_news_p++)
warn("Using prepare_creds $return heuristic for $new")
new = news[tid()]
}
/* The actual security band-aid payload. */
if (keyring == @cast(new,"struct cred")->session_keyring) {
if (trace_p) printf("%s[%d] rejoin keyring %s %p %s\n",
execname(), tid(), $name$,
keyring,
@cast(keyring,"struct key")->usage$$)
if (fix_p) do_key_put(keyring)
if (fix_p && trace_p) printf("-> %p %s\n",
keyring,
@cast(keyring,"struct key")->usage$$)
}
}
function do_key_put(ptr)
%{
if (STAP_ARG_ptr != 0)
key_put ((struct key *) STAP_ARG_ptr);
%}
/* We cache the last $keyring value for this thread. Relying on this
table instead of direct access to $keyring at the
join_session_keyring function label is undesirable. This is
because we don't have a very good way of keeping this table clean
(to remove old entries). (Extraordinary measures could include
catching thread deaths, or returns from *callers* of
find_keyring_by_name.) So what we do here instead is label keyrings%
as an auto-wrapping array, so *old* entries will be reused. */
global keyrings%, warned_keyrings_p
probe kernel.function("find_keyring_by_name").return
{
keyrings[tid()] = $return
}
/* And same for the $new variable. :-( */
global news%, warned_news_p
probe kernel.function("prepare_creds").return
{
news[tid()] = $return
}
/* Disable the automatic dumping of these globals. */
probe never
{
println(keyrings[0])
println(news[0])
println(warned_keyrings_p+1)
println(warned_news_p+1)
}