Execve syscall in ruby

Hi
I’ve tried to call execve using Kernel#syscall. Execve is 11 in my case
[i386] so i’m trying to call:

syscall(11, ‘/bin/true’, [‘true’].pack(‘p*’) , [‘X=1’].pack(‘p*’))

but it raises Bad address (Errno::EFAULT) exception, called it with
strace:

% strace -eexecve ruby -e “syscall(11, ‘/bin/true’, [‘true’].pack(‘p*’)
, [‘X=1’].pack(‘p*’))”
execve("/usr/bin/ruby", [“ruby”, “-e”, “syscall(11, ‘/bin/true’,
[‘true’”…], [/* 75 vars /]) = 0
execve("/bin/true", [“true”…, 0x4800, 0x6000000, 0x11, “\7!”…,
“”…, 0x7000000, 0x49, “\7!”…,
“\310\261\371A\310\261\371A\320\261\371A\320\261\371A\330\261\371A\330\261\371A\340\261\371A\340\261\371A”…],
[/
4 vars */]) = -1 EFAULT (Bad address)
-e:1:in `syscall’: Bad address (Errno::EFAULT)
from -e:1

execve(2) man says:
EFAULT filename points outside your accessible address space.

Both execve traces differs, second argument [an arguments array] in
second execve doesn’t look the same like in first execve invocation,
it’s longer, has addidional values and … [three dots] after strings
suggesting they’re in fact probably longer [i don’t know strace formatting rules well]. Is it something wrong with p* packing? Anybody
tried calling execve in ruby this way?:slight_smile:

That’s me again, now i know that i have to terminate an array with null
pointer, is this possible in ruby?

On 19-07-2008, at 15:36, Daniel Kaminski wrote:

That’s me again, now i know that i have to terminate an array with
null
pointer, is this possible in ruby?

NULL is just a 0 (zero):

$ ruby -e “syscall(11, ‘/home/rolando/test.rb’, [‘true’, ‘lala’,
0].pack(‘ppi’), [‘X=1’, 0].pack(‘pi’))”
[“lala”]
{“X”=>“1”}

$ cat test.rb
#!/usr/local/bin/ruby

p ARGV
p ENV


Posted via http://www.ruby-forum.com/.

regards,

Rolando A. wrote:

On 19-07-2008, at 15:36, Daniel Kaminski wrote:

That’s me again, now i know that i have to terminate an array with
null
pointer, is this possible in ruby?

NULL is just a 0 (zero):

$ ruby -e “syscall(11, ‘/home/rolando/test.rb’, [‘true’, ‘lala’,
0].pack(‘ppi’), [‘X=1’, 0].pack(‘pi’))”
[“lala”]
{“X”=>“1”}

$ cat test.rb
#!/usr/local/bin/ruby

p ARGV
p ENV

-e:1:in `syscall’: string contains null byte (ArgumentError)
from -e:1

It’s the same error when tried [‘true’, nil].pack(‘p*’), result is the
same too, it adds ‘000\000\000\000’.
Do you have patched ruby build or something? i managed to make it work
by commenting few lines from string.c responsible for above exception.

regards:-)

On 19-07-2008, at 17:01, Daniel Kaminski wrote:

0].pack(‘ppi’), [‘X=1’, 0].pack(‘pi’))"
-e:1:in `syscall’: string contains null byte (ArgumentError)
from -e:1

It’s the same error when tried [‘true’, nil].pack(‘p*’), result is the
same too, it adds ‘000\000\000\000’.
Do you have patched ruby build or something? i managed to make it work
by commenting few lines from string.c responsible for above exception.

regards:-)

I think you’re missing the fact that I used ‘ppi’ as the argument to
pack (NULL is an integer) and not ‘p*’.
regards,

Ah, stupid me, haven’t noticed a bug:
http://rubyforge.org/tracker/index.php?func=detail&aid=20895&group_id=426&atid=1698

Rolando A. wrote:

I think you’re missing the fact that I used ‘ppi’ as the argument to
pack (NULL is an integer) and not ‘p*’.
regards,

Except that the problem is already solved [see above, pasted a link] you
seems to be missing the fact that I was saing that [‘true’,0
].pack(‘pi’) and [‘true’,nil ].pack(‘p*’) gives the same result and the
p* method is better because you don’t have to control ‘p’ count in
pack() argument.