Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
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
bcc
Commits
22ea950f
Commit
22ea950f
authored
Apr 16, 2018
by
yonghong-song
Committed by
GitHub
Apr 16, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1682 from hMcLauchlan/inject-qol
QoL improvements for inject
parents
6f53be35
45bcfb7c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
58 additions
and
6 deletions
+58
-6
tools/inject.py
tools/inject.py
+43
-4
tools/inject_example.txt
tools/inject_example.txt
+15
-2
No files found.
tools/inject.py
View file @
22ea950f
...
...
@@ -33,6 +33,7 @@
# 16-Mar-2018 Howard McLauchlan Created this.
import
argparse
import
re
from
bcc
import
BPF
...
...
@@ -294,6 +295,21 @@ class Probe:
class
Tool
:
examples
=
"""
EXAMPLES:
# ./inject.py kmalloc -v 'SyS_mount()'
Fails all calls to syscall mount
# ./inject.py kmalloc -v '(true) => SyS_mount()(true)'
Explicit rewriting of above
# ./inject.py kmalloc -v 'mount_subtree() => btrfs_mount()'
Fails btrfs mounts only
# ./inject.py kmalloc -v 'd_alloc_parallel(struct dentry *parent, const struct
\
\
qstr *name)(STRCMP(name->name, 'bananas'))'
Fails dentry allocations of files named 'bananas'
# ./inject.py kmalloc -v -P 0.01 'SyS_mount()'
Fails calls to syscall mount with 1% probability
"""
# add cases as necessary
error_injection_mapping
=
{
"kmalloc"
:
"should_failslab(struct kmem_cache *s, gfp_t gfpflags)"
,
...
...
@@ -303,8 +319,9 @@ class Tool:
def
__init__
(
self
):
parser
=
argparse
.
ArgumentParser
(
description
=
"Fail specified kernel"
+
" functionality when call chain and predicates are met"
,
formatter_class
=
argparse
.
RawDescriptionHelpFormatter
)
parser
.
add_argument
(
metavar
=
"mode"
,
dest
=
"mode"
,
formatter_class
=
argparse
.
RawDescriptionHelpFormatter
,
epilog
=
Tool
.
examples
)
parser
.
add_argument
(
dest
=
"mode"
,
choices
=
[
'kmalloc'
,
'bio'
],
help
=
"indicate which base kernel function to fail"
)
parser
.
add_argument
(
metavar
=
"spec"
,
dest
=
"spec"
,
help
=
"specify call chain"
)
...
...
@@ -315,7 +332,7 @@ class Tool:
metavar
=
"probability"
,
type
=
float
,
help
=
"probability that this call chain will fail"
)
parser
.
add_argument
(
"-v"
,
"--verbose"
,
action
=
"store_true"
,
help
=
"print BPF program"
)
help
=
"print BPF program"
)
self
.
args
=
parser
.
parse_args
()
self
.
program
=
""
...
...
@@ -350,6 +367,7 @@ class Tool:
frames
=
[]
cur_frame
=
[]
i
=
0
last_frame_added
=
0
while
i
<
len
(
data
):
# improper input
...
...
@@ -360,6 +378,10 @@ class Tool:
count
-=
c
==
')'
if
not
count
:
if
c
==
'
\
0
'
or
(
c
==
'='
and
data
[
i
+
1
]
==
'>'
):
# This block is closing a chunk. This means cur_frame must
# have something in it.
if
not
cur_frame
:
raise
Exception
(
"Cannot parse spec, missing parens"
)
if
len
(
cur_frame
)
==
2
:
frame
=
tuple
(
cur_frame
)
elif
cur_frame
[
0
][
0
]
==
'('
:
...
...
@@ -373,7 +395,12 @@ class Tool:
elif
c
==
')'
:
cur_frame
.
append
(
data
[
start
:
i
+
1
].
strip
())
start
=
i
+
1
last_frame_added
=
start
i
+=
1
# We only permit spaces after the last frame
if
self
.
spec
[
last_frame_added
:].
strip
():
raise
Exception
(
"Invalid characters found after last frame"
);
# improper input
if
count
:
raise
Exception
(
"Check your parentheses"
)
...
...
@@ -389,7 +416,9 @@ class Tool:
func
,
pred
=
f
[
0
],
f
[
1
]
if
not
self
.
_validate_predicate
(
pred
):
raise
Exception
raise
Exception
(
"Invalid predicate"
)
if
not
self
.
_validate_identifier
(
func
):
raise
Exception
(
"Invalid function identifier"
)
tup
=
(
pred
,
absolute_order
)
if
func
not
in
self
.
map
:
...
...
@@ -405,6 +434,16 @@ class Tool:
self
.
length
=
absolute_order
def
_validate_identifier
(
self
,
func
):
# We've already established paren balancing. We will only look for
# identifier validity here.
paren_index
=
func
.
find
(
"("
)
potential_id
=
func
[:
paren_index
]
pattern
=
'[_a-zA-z][_a-zA-Z0-9]*$'
if
re
.
match
(
pattern
,
potential_id
):
return
True
return
False
def
_validate_predicate
(
self
,
pred
):
if
len
(
pred
)
>
0
and
pred
[
0
]
==
"("
:
...
...
tools/inject_example.txt
View file @
22ea950f
...
...
@@ -115,12 +115,12 @@ fail our mounts half the time:
# ./inject.py kmalloc -v -P 0.01 'SyS_mount()'
USAGE message:
usage: inject.py [-h] [-I header] [-P probability] [-v]
mode
spec
usage: inject.py [-h] [-I header] [-P probability] [-v]
{kmalloc,bio}
spec
Fail specified kernel functionality when call chain and predicates are met
positional arguments:
mode
indicate which base kernel function to fail
{kmalloc,bio}
indicate which base kernel function to fail
spec specify call chain
optional arguments:
...
...
@@ -130,3 +130,16 @@ optional arguments:
-P probability, --probability probability
probability that this call chain will fail
-v, --verbose print BPF program
EXAMPLES:
# ./inject.py kmalloc -v 'SyS_mount()'
Fails all calls to syscall mount
# ./inject.py kmalloc -v '(true) => SyS_mount()(true)'
Explicit rewriting of above
# ./inject.py kmalloc -v 'mount_subtree() => btrfs_mount()'
Fails btrfs mounts only
# ./inject.py kmalloc -v 'd_alloc_parallel(struct dentry *parent, const struct \
qstr *name)(STRCMP(name->name, 'bananas'))'
Fails dentry allocations of files named 'bananas'
# ./inject.py kmalloc -v -P 0.01 'SyS_mount()'
Fails calls to syscall mount with 1% probability
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