vivarium 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/examples/env_access_external_demo.rb +52 -0
- data/examples/env_access_ruby_demo.rb +52 -0
- data/lib/vivarium/version.rb +1 -1
- data/lib/vivarium.rb +165 -5
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be07034ab56d73e0aaa4fe9e124d67888ae2006cc5f6cb632cf4b93b20855422
|
|
4
|
+
data.tar.gz: 5f95cdaa111a56415f4fed08da0c638a87f5c08f01e51db2b5b818c04c256bc4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 49e166adbaca6231263d10255779ce4ff16a98ba9905a4afc48da012382d21fe1635b4f3bfff3990125bcb9718f7e1e5f3c5168a3a7f39b7fd8981be312bc3a4
|
|
7
|
+
data.tar.gz: a85783ba20a6eb866bd8215f55a4edb6890bef1b0b3e3e7af6d11bfcc0fda77adbfa2e7ea465e201c424d6fc9f883bcb20d7846e3c051c294560151ac0078d30
|
data/README.md
CHANGED
|
@@ -139,6 +139,22 @@ bundle exec ruby examples/privilege_event_demo.rb
|
|
|
139
139
|
|
|
140
140
|
This demo attempts setuid/setgid changes, sensitive file access, and `sudo` exec to trigger privilege-related events such as `setid_change`, `capable_check`, and `bprm_creds`.
|
|
141
141
|
|
|
142
|
+
8) Ruby internal ENV access demo client:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
bundle exec ruby examples/env_access_ruby_demo.rb
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This demo triggers Ruby-side ENV methods (`[]`, `fetch`, `key?`, `[]=`, `store`, `delete`, `clear`, `replace`) and is intended to produce SPAN events.
|
|
149
|
+
|
|
150
|
+
9) External command ENV libc access demo client:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
bundle exec ruby examples/env_access_external_demo.rb
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This demo spawns an external process that directly calls libc `getenv`, `setenv`, `unsetenv`, `putenv`, and `clearenv`, intended to trigger `env_caccess` eBPF events.
|
|
157
|
+
|
|
142
158
|
You can also start top-level observation without a block (it keeps observing until process exit):
|
|
143
159
|
|
|
144
160
|
```ruby
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "rbconfig"
|
|
5
|
+
require "vivarium"
|
|
6
|
+
|
|
7
|
+
# Usage:
|
|
8
|
+
# 1) In another shell (root): sudo bundle exec vivariumd
|
|
9
|
+
# 2) Run this script: bundle exec ruby examples/env_access_external_demo.rb
|
|
10
|
+
#
|
|
11
|
+
# This demo launches an external Ruby process and forces direct libc calls to
|
|
12
|
+
# getenv/setenv/unsetenv/putenv/clearenv through Fiddle.
|
|
13
|
+
# These should appear as eBPF events with event_name=env_caccess.
|
|
14
|
+
|
|
15
|
+
FILTER = {
|
|
16
|
+
include_events: %w[env_caccess proc_fork proc_exec]
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
CHILD_CODE = <<~RUBY
|
|
20
|
+
require "fiddle"
|
|
21
|
+
|
|
22
|
+
libc = begin
|
|
23
|
+
Fiddle.dlopen("libc.so.6")
|
|
24
|
+
rescue Fiddle::DLError
|
|
25
|
+
Fiddle.dlopen(nil)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
getenv = Fiddle::Function.new(libc["getenv"], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP)
|
|
29
|
+
setenv = Fiddle::Function.new(libc["setenv"], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT], Fiddle::TYPE_INT)
|
|
30
|
+
unsetenv = Fiddle::Function.new(libc["unsetenv"], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
|
31
|
+
putenv = Fiddle::Function.new(libc["putenv"], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
|
32
|
+
clearenv = Fiddle::Function.new(libc["clearenv"], [], Fiddle::TYPE_INT)
|
|
33
|
+
|
|
34
|
+
key = "VIVARIUM_ENV_EXT_DEMO"
|
|
35
|
+
putenv_buf = "VIVARIUM_ENV_EXT_PUT=from_putenv"
|
|
36
|
+
|
|
37
|
+
getenv.call("HOME")
|
|
38
|
+
setenv.call(key, "from_setenv", 1)
|
|
39
|
+
getenv.call(key)
|
|
40
|
+
putenv.call(putenv_buf)
|
|
41
|
+
unsetenv.call(key)
|
|
42
|
+
clearenv.call
|
|
43
|
+
RUBY
|
|
44
|
+
|
|
45
|
+
Vivarium.observe(filter: FILTER) do
|
|
46
|
+
puts "[env-external-demo] spawning external child"
|
|
47
|
+
pid = Process.spawn(RbConfig.ruby, "-e", CHILD_CODE)
|
|
48
|
+
Process.wait(pid)
|
|
49
|
+
puts "[env-external-demo] child exit status=#{Process.last_status.exitstatus}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
puts "[env-external-demo] done"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "vivarium"
|
|
5
|
+
|
|
6
|
+
# Usage:
|
|
7
|
+
# 1) In another shell (root): sudo bundle exec vivariumd
|
|
8
|
+
# 2) Run this script: bundle exec ruby examples/env_access_ruby_demo.rb
|
|
9
|
+
#
|
|
10
|
+
# This demo intentionally triggers Ruby-side ENV access methods so they are
|
|
11
|
+
# observed through TracePoint -> SPAN (USDT) path.
|
|
12
|
+
|
|
13
|
+
FILTER = {
|
|
14
|
+
include_events: %w[span_start span_stop env_caccess]
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
def safe_fetch(key)
|
|
18
|
+
ENV.fetch(key)
|
|
19
|
+
rescue KeyError
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def demo_env_reads
|
|
24
|
+
ENV["HOME"]
|
|
25
|
+
safe_fetch("PATH")
|
|
26
|
+
ENV.key?("SHELL")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def demo_env_writes
|
|
30
|
+
ENV["VIVARIUM_ENV_DEMO_A"] = "1"
|
|
31
|
+
ENV.store("VIVARIUM_ENV_DEMO_B", "2")
|
|
32
|
+
ENV.delete("VIVARIUM_ENV_DEMO_A")
|
|
33
|
+
ENV.replace(ENV.to_h.merge("VIVARIUM_ENV_DEMO_C" => "3"))
|
|
34
|
+
ENV.delete("VIVARIUM_ENV_DEMO_B")
|
|
35
|
+
ENV.delete("VIVARIUM_ENV_DEMO_C")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Vivarium.observe(filter: FILTER) do
|
|
39
|
+
original_env = ENV.to_h
|
|
40
|
+
|
|
41
|
+
puts "[env-ruby-demo] read methods"
|
|
42
|
+
demo_env_reads
|
|
43
|
+
|
|
44
|
+
puts "[env-ruby-demo] write methods"
|
|
45
|
+
demo_env_writes
|
|
46
|
+
|
|
47
|
+
puts "[env-ruby-demo] clear"
|
|
48
|
+
ENV.clear
|
|
49
|
+
ENV.replace(original_env)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
puts "[env-ruby-demo] done"
|
data/lib/vivarium/version.rb
CHANGED
data/lib/vivarium.rb
CHANGED
|
@@ -95,7 +95,20 @@ module Vivarium
|
|
|
95
95
|
"Kernel#eval",
|
|
96
96
|
"Object#instance_eval",
|
|
97
97
|
"Object#instance_exec",
|
|
98
|
+
"ENV#[]",
|
|
99
|
+
"ENV#fetch",
|
|
100
|
+
"ENV#key?",
|
|
101
|
+
"ENV#[]=",
|
|
102
|
+
"ENV#store",
|
|
103
|
+
"ENV#delete",
|
|
104
|
+
"ENV#clear",
|
|
105
|
+
"ENV#replace",
|
|
98
106
|
].freeze
|
|
107
|
+
|
|
108
|
+
ENV_PAYLOAD_OP_SIZE = 16
|
|
109
|
+
ENV_PAYLOAD_KEY_OFFSET = ENV_PAYLOAD_OP_SIZE
|
|
110
|
+
ENV_PAYLOAD_KEY_SIZE = EVENT_PAYLOAD_SIZE - ENV_PAYLOAD_KEY_OFFSET
|
|
111
|
+
|
|
99
112
|
EVENT_SEVERITY_HIGH = %w[
|
|
100
113
|
capable_check bprm_creds setid_change task_kill
|
|
101
114
|
ptrace_check sb_mount kernel_read_file
|
|
@@ -407,6 +420,20 @@ module Vivarium
|
|
|
407
420
|
{ data_len: data_len, cap_len: cap_len, data: data }
|
|
408
421
|
end
|
|
409
422
|
|
|
423
|
+
def self.decode_env_payload(raw_payload)
|
|
424
|
+
bytes = raw_payload.to_s.b
|
|
425
|
+
return "" if bytes.bytesize < ENV_PAYLOAD_OP_SIZE
|
|
426
|
+
|
|
427
|
+
op = c_string(bytes[0, ENV_PAYLOAD_OP_SIZE])
|
|
428
|
+
key = c_string(bytes[ENV_PAYLOAD_KEY_OFFSET, ENV_PAYLOAD_KEY_SIZE])
|
|
429
|
+
|
|
430
|
+
return "" if op.empty?
|
|
431
|
+
return "op=#{op}" if key.empty?
|
|
432
|
+
|
|
433
|
+
key = key.split("=", 2).first if op == "putenv"
|
|
434
|
+
"op=#{op} key=#{key.inspect}"
|
|
435
|
+
end
|
|
436
|
+
|
|
410
437
|
def self.decode_span_raise_payload(raw_payload)
|
|
411
438
|
bytes = raw_payload.to_s.b
|
|
412
439
|
return "" if bytes.bytesize < 8
|
|
@@ -494,6 +521,9 @@ module Vivarium
|
|
|
494
521
|
when "ssl_write"
|
|
495
522
|
decoded = decode_ssl_write_payload(event.payload)
|
|
496
523
|
"data_len=#{decoded[:data_len]} cap_len=#{decoded[:cap_len]}"
|
|
524
|
+
when "env_caccess"
|
|
525
|
+
decoded = decode_env_payload(event.payload)
|
|
526
|
+
decoded.empty? ? event.payload.inspect : decoded
|
|
497
527
|
when "dlopen", "mmap_exec"
|
|
498
528
|
strip_to_first_null(event.payload).inspect
|
|
499
529
|
else
|
|
@@ -726,6 +756,26 @@ module Vivarium
|
|
|
726
756
|
events.ringbuf_submit(ev, 0);
|
|
727
757
|
}
|
|
728
758
|
|
|
759
|
+
static __always_inline void submit_env_event(u32 pid, const char *op, u32 op_len, const char *name_ptr)
|
|
760
|
+
{
|
|
761
|
+
struct event_t ev = {};
|
|
762
|
+
ev.pid = pid;
|
|
763
|
+
__builtin_memcpy(ev.event_name, "env_caccess", 12);
|
|
764
|
+
|
|
765
|
+
if (op && op_len > 0) {
|
|
766
|
+
if (op_len > #{ENV_PAYLOAD_OP_SIZE} - 1) {
|
|
767
|
+
op_len = #{ENV_PAYLOAD_OP_SIZE} - 1;
|
|
768
|
+
}
|
|
769
|
+
__builtin_memcpy(&ev.payload[0], op, op_len);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (name_ptr) {
|
|
773
|
+
bpf_probe_read_user_str(&ev.payload[#{ENV_PAYLOAD_KEY_OFFSET}], #{ENV_PAYLOAD_KEY_SIZE}, name_ptr);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
submit_event(&ev);
|
|
777
|
+
}
|
|
778
|
+
|
|
729
779
|
static __always_inline int is_dns_destination(void *addr)
|
|
730
780
|
{
|
|
731
781
|
u16 family = 0;
|
|
@@ -1519,6 +1569,80 @@ module Vivarium
|
|
|
1519
1569
|
return 0;
|
|
1520
1570
|
}
|
|
1521
1571
|
|
|
1572
|
+
int on_getenv(struct pt_regs *ctx)
|
|
1573
|
+
{
|
|
1574
|
+
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
1575
|
+
u32 pid = pid_tgid >> 32;
|
|
1576
|
+
u32 tid = (u32)pid_tgid;
|
|
1577
|
+
const char *name = (const char *)PT_REGS_PARM1(ctx);
|
|
1578
|
+
|
|
1579
|
+
if (!target_enabled(pid, tid) || !name) {
|
|
1580
|
+
return 0;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
submit_env_event(pid, "getenv", 6, name);
|
|
1584
|
+
return 0;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
int on_setenv(struct pt_regs *ctx)
|
|
1588
|
+
{
|
|
1589
|
+
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
1590
|
+
u32 pid = pid_tgid >> 32;
|
|
1591
|
+
u32 tid = (u32)pid_tgid;
|
|
1592
|
+
const char *name = (const char *)PT_REGS_PARM1(ctx);
|
|
1593
|
+
|
|
1594
|
+
if (!target_enabled(pid, tid) || !name) {
|
|
1595
|
+
return 0;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
submit_env_event(pid, "setenv", 6, name);
|
|
1599
|
+
return 0;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
int on_unsetenv(struct pt_regs *ctx)
|
|
1603
|
+
{
|
|
1604
|
+
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
1605
|
+
u32 pid = pid_tgid >> 32;
|
|
1606
|
+
u32 tid = (u32)pid_tgid;
|
|
1607
|
+
const char *name = (const char *)PT_REGS_PARM1(ctx);
|
|
1608
|
+
|
|
1609
|
+
if (!target_enabled(pid, tid) || !name) {
|
|
1610
|
+
return 0;
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
submit_env_event(pid, "unsetenv", 8, name);
|
|
1614
|
+
return 0;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
int on_putenv(struct pt_regs *ctx)
|
|
1618
|
+
{
|
|
1619
|
+
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
1620
|
+
u32 pid = pid_tgid >> 32;
|
|
1621
|
+
u32 tid = (u32)pid_tgid;
|
|
1622
|
+
const char *string = (const char *)PT_REGS_PARM1(ctx);
|
|
1623
|
+
|
|
1624
|
+
if (!target_enabled(pid, tid) || !string) {
|
|
1625
|
+
return 0;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
submit_env_event(pid, "putenv", 6, string);
|
|
1629
|
+
return 0;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
int on_clearenv(struct pt_regs *ctx)
|
|
1633
|
+
{
|
|
1634
|
+
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
1635
|
+
u32 pid = pid_tgid >> 32;
|
|
1636
|
+
u32 tid = (u32)pid_tgid;
|
|
1637
|
+
|
|
1638
|
+
if (!target_enabled(pid, tid)) {
|
|
1639
|
+
return 0;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
submit_env_event(pid, "clearenv", 8, 0);
|
|
1643
|
+
return 0;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1522
1646
|
int on_span_raise(struct pt_regs *ctx)
|
|
1523
1647
|
{
|
|
1524
1648
|
u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
@@ -1551,11 +1675,12 @@ module Vivarium
|
|
|
1551
1675
|
CLANG
|
|
1552
1676
|
|
|
1553
1677
|
def initialize(pin_dir: Vivarium.bpf_pin_dir, ssl_trace: true, libssl_path: nil,
|
|
1554
|
-
dlopen_trace: true, libc_path: nil)
|
|
1678
|
+
dlopen_trace: true, env_trace: true, libc_path: nil)
|
|
1555
1679
|
@pin_dir = pin_dir
|
|
1556
1680
|
@ssl_trace = ssl_trace
|
|
1557
1681
|
@libssl_path = libssl_path
|
|
1558
1682
|
@dlopen_trace = dlopen_trace
|
|
1683
|
+
@env_trace = env_trace
|
|
1559
1684
|
@libc_path = libc_path
|
|
1560
1685
|
end
|
|
1561
1686
|
|
|
@@ -1580,6 +1705,7 @@ module Vivarium
|
|
|
1580
1705
|
|
|
1581
1706
|
attach_ssl_write_uprobe(bpf) if @ssl_trace
|
|
1582
1707
|
attach_dlopen_uprobe(bpf) if @dlopen_trace
|
|
1708
|
+
attach_env_uprobes(bpf) if @env_trace
|
|
1583
1709
|
|
|
1584
1710
|
config_root_targets = bpf["config_root_targets"]
|
|
1585
1711
|
config_spawned_targets = bpf["config_spawned_targets"]
|
|
@@ -1652,6 +1778,30 @@ module Vivarium
|
|
|
1652
1778
|
warn "[vivariumd] dlopen uprobe attach failed: #{e.class}: #{e.message}"
|
|
1653
1779
|
end
|
|
1654
1780
|
|
|
1781
|
+
def attach_env_uprobes(bpf)
|
|
1782
|
+
path = resolve_libc_path
|
|
1783
|
+
unless path
|
|
1784
|
+
warn "[vivariumd] libc not found; ENV uprobes disabled " \
|
|
1785
|
+
"(set --libc PATH or VIVARIUM_LIBC_PATH to override)"
|
|
1786
|
+
return
|
|
1787
|
+
end
|
|
1788
|
+
|
|
1789
|
+
{
|
|
1790
|
+
"getenv" => "on_getenv",
|
|
1791
|
+
"setenv" => "on_setenv",
|
|
1792
|
+
"unsetenv" => "on_unsetenv",
|
|
1793
|
+
"putenv" => "on_putenv",
|
|
1794
|
+
"clearenv" => "on_clearenv"
|
|
1795
|
+
}.each do |sym, fn_name|
|
|
1796
|
+
begin
|
|
1797
|
+
bpf.attach_uprobe(name: path, sym: sym, fn_name: fn_name)
|
|
1798
|
+
puts "[vivariumd] #{sym} uprobe attached via #{path}"
|
|
1799
|
+
rescue StandardError => e
|
|
1800
|
+
warn "[vivariumd] #{sym} uprobe attach failed: #{e.class}: #{e.message}"
|
|
1801
|
+
end
|
|
1802
|
+
end
|
|
1803
|
+
end
|
|
1804
|
+
|
|
1655
1805
|
def resolve_libc_path
|
|
1656
1806
|
if @libc_path
|
|
1657
1807
|
return @libc_path if File.exist?(@libc_path)
|
|
@@ -1892,18 +2042,23 @@ module Vivarium
|
|
|
1892
2042
|
next
|
|
1893
2043
|
end
|
|
1894
2044
|
|
|
1895
|
-
signature =
|
|
2045
|
+
signature = if tp.self.equal?(ENV)
|
|
2046
|
+
"ENV##{tp.method_id}"
|
|
2047
|
+
else
|
|
2048
|
+
"#{tp.defined_class}##{tp.method_id}"
|
|
2049
|
+
end
|
|
1896
2050
|
is_target = allowlist.include?(signature) || \
|
|
1897
2051
|
allow_classes.any? { |klass| tp.defined_class == klass } || \
|
|
1898
2052
|
allow_classes.any? { |klass| tp.defined_class == klass.singleton_class }
|
|
1899
2053
|
next unless is_target
|
|
1900
2054
|
|
|
1901
2055
|
file_arg = tail_fit_string(tp.path, SPAN_FILE_ARG_MAX)
|
|
2056
|
+
span_class_name = tp.self.equal?(ENV) ? "ENV" : tp.defined_class.to_s
|
|
1902
2057
|
case tp.event
|
|
1903
2058
|
when :call, :c_call
|
|
1904
|
-
Vivarium::Usdt.start(
|
|
2059
|
+
Vivarium::Usdt.start(span_class_name, tp.method_id.to_s, file: file_arg, lineno: tp.lineno)
|
|
1905
2060
|
when :return, :c_return
|
|
1906
|
-
Vivarium::Usdt.stop(
|
|
2061
|
+
Vivarium::Usdt.stop(span_class_name, tp.method_id.to_s, file: file_arg, lineno: tp.lineno)
|
|
1907
2062
|
end
|
|
1908
2063
|
end
|
|
1909
2064
|
end
|
|
@@ -1935,10 +2090,11 @@ module Vivarium
|
|
|
1935
2090
|
|
|
1936
2091
|
def self.run_daemon!(argv = ARGV)
|
|
1937
2092
|
options = { pin_dir: bpf_pin_dir, ssl_trace: true, libssl_path: nil,
|
|
2093
|
+
env_trace: true,
|
|
1938
2094
|
dlopen_trace: true, libc_path: nil }
|
|
1939
2095
|
OptionParser.new do |opts|
|
|
1940
2096
|
opts.banner = "Usage: vivariumd [--pin-dir PATH] [--no-ssl-trace] [--libssl PATH] " \
|
|
1941
|
-
"[--no-dlopen-trace] [--libc PATH]"
|
|
2097
|
+
"[--no-dlopen-trace] [--no-env-trace] [--libc PATH]"
|
|
1942
2098
|
opts.on("--pin-dir PATH", "Pinned map directory") { |v| options[:pin_dir] = v }
|
|
1943
2099
|
opts.on("--[no-]ssl-trace", "Attach OpenSSL SSL_write uprobe (default: enabled)") do |v|
|
|
1944
2100
|
options[:ssl_trace] = v
|
|
@@ -1949,6 +2105,9 @@ module Vivarium
|
|
|
1949
2105
|
opts.on("--[no-]dlopen-trace", "Attach libc dlopen uprobe (default: enabled)") do |v|
|
|
1950
2106
|
options[:dlopen_trace] = v
|
|
1951
2107
|
end
|
|
2108
|
+
opts.on("--[no-]env-trace", "Attach libc getenv/setenv uprobes (default: enabled)") do |v|
|
|
2109
|
+
options[:env_trace] = v
|
|
2110
|
+
end
|
|
1952
2111
|
opts.on("--libc PATH", "Path to libc.so for dlopen uprobe") do |v|
|
|
1953
2112
|
options[:libc_path] = v
|
|
1954
2113
|
end
|
|
@@ -1959,6 +2118,7 @@ module Vivarium
|
|
|
1959
2118
|
ssl_trace: options[:ssl_trace],
|
|
1960
2119
|
libssl_path: options[:libssl_path],
|
|
1961
2120
|
dlopen_trace: options[:dlopen_trace],
|
|
2121
|
+
env_trace: options[:env_trace],
|
|
1962
2122
|
libc_path: options[:libc_path]
|
|
1963
2123
|
).run
|
|
1964
2124
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vivarium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Uchio Kondo
|
|
@@ -66,6 +66,8 @@ files:
|
|
|
66
66
|
- Rakefile
|
|
67
67
|
- examples/dlopen_demo.rb
|
|
68
68
|
- examples/drop_demo.rb
|
|
69
|
+
- examples/env_access_external_demo.rb
|
|
70
|
+
- examples/env_access_ruby_demo.rb
|
|
69
71
|
- examples/execve_demo.rb
|
|
70
72
|
- examples/file_operation_demo.rb
|
|
71
73
|
- examples/network_client_demo.rb
|