Skip to content

Instantly share code, notes, and snippets.

@lloeki
Created October 23, 2024 12:06
Show Gist options
  • Save lloeki/27329483d4e83bc5c0c1072c8b9369e5 to your computer and use it in GitHub Desktop.
Save lloeki/27329483d4e83bc5c0c1072c8b9369e5 to your computer and use it in GitHub Desktop.
Ruby and syscalls: `Fiddle` vs `Kernel.syscall`
# docker run --rm -it -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.3 ruby -w -I. memfd.rb kernel
# docker run --rm -it -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.3 ruby -w -I. memfd.rb fiddle
raise unless RUBY_PLATFORM =~ /linux/
SYS_MEMFD_CREATE = case RUBY_PLATFORM
when /x86_64/
319
when /i386/
356
when /armv7l/
385
when /(arm|aarch)64/
279
end
MFD_CLOEXEC = 0x0001
require 'json'
flags = MFD_CLOEXEC
filename = 'datadog.tracing_library.json'
data = { 'foo' => 'bar' }
payload = JSON.dump(data)
if ARGV[0] == 'fiddle'
# https://www.man7.org/linux/man-pages/man2/syscall.2.html
# needs libffi
require 'fiddle'
# https://docs.ruby-lang.org/en/master/Fiddle.html
libc = Fiddle.dlopen(nil)
c_syscall = Fiddle::Function.new(libc['syscall'], [Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP, Fiddle::TYPE_UINT], Fiddle::TYPE_LONG)
# https://docs.ruby-lang.org/en/master/Fiddle/Pointer.html
filename_ptr = Fiddle::Pointer.malloc(filename.bytesize + 1)
Fiddle::Pointer.write(filename_ptr, filename)
fd = c_syscall.call(SYS_MEMFD_CREATE, filename_ptr, flags)
Fiddle.free filename_ptr
if fd == -1
raise "error: #{Fiddle.last_error}"
end
elsif ARGV[0] == 'kernel'
# https://docs.ruby-lang.org/en/master/Kernel.html#method-i-syscall
# emits warning: deprecated
begin
fd = Kernel.syscall(SYS_MEMFD_CREATE, filename, flags)
rescue SystemCallError => e
raise "error: #{e.errno}"
end
else
raise 'error: missing arg'
end
if fd < 2
raise "unexpected fd value for : #{fd}"
else
puts "success #{fd}"
# https://docs.ruby-lang.org/en/master/IO.html#method-c-new
io = IO.new(fd, 'w')
# underlying has no encoding, ensure write UTF-8 bytes
count = io.write(payload.encode('UTF-8'))
p count
io.flush
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment