Module: Straycall::Handlers::Filesystem

Included in:
Supervisor
Defined in:
lib/straycall/handlers/filesystem.rb

Instance Method Summary collapse

Instance Method Details

#handle_fd_mutation(request, fd) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/straycall/handlers/filesystem.rb', line 41

def handle_fd_mutation(request, fd)
  path = File.readlink("/proc/#{request.tid}/fd/#{fd}").delete_suffix(" (deleted)")
  return request.continue! unless path.start_with?(File::SEPARATOR)

  target = {type: "file", path:, operation: request.syscall.to_s}
  if !@config.filesystem.allowed_write?(path) || @config.on_violation == :record
    record_violation(request, target, %(allow_write_under #{File.dirname(path).inspect}))
  else
    request.continue!(unsafe: true)
  end
rescue SystemCallError
  record_violation(request, {type: "file", path: "?", operation: request.syscall.to_s}, nil)
end

#handle_mmap(request) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/straycall/handlers/filesystem.rb', line 55

def handle_mmap(request)
  prot = request.args[2]
  shared = (request.args[3] & 1).positive?
  return request.continue! unless shared && (prot & 2).positive?

  handle_fd_mutation(request, request.args[4])
end

#handle_openat(request) ⇒ Object



6
7
8
# File 'lib/straycall/handlers/filesystem.rb', line 6

def handle_openat(request)
  handle_open(request, request.args[0], request.args[1], request.args[2])
end

#handle_openat2(request) ⇒ Object



10
11
12
13
# File 'lib/straycall/handlers/filesystem.rb', line 10

def handle_openat2(request)
  flags = request.read(request.args[2], 8).unpack1("Q<")
  handle_open(request, request.args[0], request.args[1], flags)
end

#handle_path_mutation(request, dirfd, path_address) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/straycall/handlers/filesystem.rb', line 15

def handle_path_mutation(request, dirfd, path_address)
  path = resolve_path(request, dirfd, path_address)
  target = {type: "file", path:, operation: request.syscall.to_s}
  if !@config.filesystem.allowed_write?(path) || @config.on_violation == :record
    record_violation(request, target, %(allow_write_under #{File.dirname(path).inspect}))
  else
    request.continue!(unsafe: true)
  end
rescue PathResolutionError, Seccomp::Notify::MemoryReadError
  record_violation(request, {type: "file", path: "?"}, nil)
end

#handle_rename(request, source_dirfd, source_address, destination_dirfd, destination_address) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/straycall/handlers/filesystem.rb', line 27

def handle_rename(request, source_dirfd, source_address, destination_dirfd, destination_address)
  source = resolve_path(request, source_dirfd, source_address)
  destination = resolve_path(request, destination_dirfd, destination_address)
  target = {type: "file", path: destination, source:, operation: request.syscall.to_s}
  allowed = @config.filesystem.allowed_write?(source) && @config.filesystem.allowed_write?(destination)
  if !allowed || @config.on_violation == :record
    record_violation(request, target, %(allow_write_under #{File.dirname(destination).inspect}))
  else
    request.continue!(unsafe: true)
  end
rescue PathResolutionError, Seccomp::Notify::MemoryReadError
  record_violation(request, {type: "file", path: "?"}, nil)
end