Unable to PHP exec() compiled binary

software development

#1

I’m having some problems using PHP’s exec() function to execute a binary I compiled under my home directory. The binary executes fine via the command line, but it doesn’t seem to be running correctly when used via exec(). No output is seen when using the options $output variable.

I haven’t had any problems when executing an ls command similar to
exec(‘ls /home/username’);
or a custom PHP build like so
exec(’/home/username/apps/bin/php5/bin/php -i’);

The binary does appear to be attempting to execute (some zero-byte files are created) … it’s just not quite working out.

Anyone have any suggestions?


#2

I had some binaries that worked for ages then one day just quit. AndrewF here at this board did some digging at system level and discovered the problem was with grsecurity and the binaries having been compiled traceable.

Here’s his PM after Sherlocking the logs:

[quote]grsec: From x.x.x.x: denied ptrace of /home/.mount/user/script/test(test:2553) by /home/.mount/user/script/test[test:2554] uid/euid:2657432/2657432 gid/egid:415661/415661, parent /home/.mount/user/script/test[test:2553] uid/euid:2657432/2657432 gid/egid:415661/415661

grsecurity doesn’t like it when users other than root try to ptrace processes that aren’t a child of the tracing process. Your bet bet is probably either to turn off the !TRACEABLE code, or to try swapping the roles of the parent and child processes.[/quote]
The ‘test’ binary in the logs above worked when run directly in shell, but not when called via other run methods (call .sh, exec, etc). Recompiling without the traceable flag cleared it straight up :slight_smile:

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#3

Thanks for the info. I’m not sure if that’s the problem or not. As far as I can tell there is no traceable flag set (at least, not in the makefile). But this isn’t my area of expertise so maybe I’m missing something.

Also, I just tested the same exec() when executing the PHP from the shell and it works as expected. So maybe there is a permission error when run via apache?


#4

[quote]Thanks for the info. I’m not sure if that’s the problem or not. As far as I can tell there is no traceable flag set (at least, not in the makefile). But this isn’t my area of expertise so maybe I’m missing something.

[/quote]

If it works from the shell, the problem is elsewhere. So, moving on…

[quote]So maybe there is a permission error when run via apache?

[/quote]

I doubt it’s a permissions issue - Apache runs PHP and CGIs as you. However, it is possible that the environment of your PHP script ends up lacking some variables that your shell gets. In particular, I’d wonder if your $PATH needs to be set to include the directory you installed the binary into…


#5

A path issue seems like a good possibility. There appear to be a few external programs that are compiled at the same time as the main program. I’ve added path info for all the external programs to my .bash_profile. It doesn’t seem to be helping. Do I need to do anything else to get the new path information working for apache?


#6

Try setting up your paths in .bashrc and call it within .bash_profile so they’re also loaded when you’re “physically” in shell.

# ~/.bash_profile: executed by bash(1) for login shells. source .bashrc
Some example paths that might help:

# ~/.bashrc: executed by bash(1) for non-login shells. export env=$HOME/your/build/location export PATH=$env/bin:$PATH export LD_LIBRARY_PATH=$env/lib:/usr/local/lib:$LD_LIBRARY_PATH export LIBRARY_PATH=$env/lib:/usr/local/lib:$LIBRARY_PATH export CPATH=$env/include:/usr/local/include:$CPATH

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#7

Thanks for the info … that does make sense. I must still be missing something, though. When I check the path info from within PHP (using phpinfo) the additional directories aren’t showing.


#8

exec runs things in the shell environment, so you wouldn’t see those paths in phpinfo unless you added them to your php.ini.
Can you elaborate on what you’re trying to do?

Is this a web-accessible php script calling a custom-compiled binary?

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#9

[quote]exec runs things in the shell environment, so you wouldn’t see those paths in phpinfo unless you added them to your php.ini.

[/quote]

Well … that makes sense! :wink:

So I created a shell script that echos out the path, used exec() to call it from a web-accessible PHP. The value returned is the default … the additional path information I’ve defined isn’t showing up.

[quote]Is this a web-accessible php script calling a custom-compiled binary?

[/quote]

That’s exactly what I’m doing. I’m trying to set up a page that will process fonts using ttf2ufm (the modified version of ttf2pt1 that supports unicode). So the user supplies a font, I use PHP exec() to call the ttf2ufm binary and process the font.

Considering the possibility of a path problem and the results outlined above, I created a shell script that defines the paths then executes the binary. I even did a cursory look through the code for anything that appeared to be an environment variable reference and added that to the shell script. Even with all this I’m still not having any luck.

The output should be an AFM file. I know it’s at least running because the AFM is created, it just has no content.


#10

> The output should be an AFM file. I know it’s at least running because the AFM is created, it just has no content.

I was getting 0 byte creations when having grsecurity woes. Thinking out aloud, does the binary create an empty destination file if it can’t locate the target file? If so it might be a preliminary path problem rather than an environmental one.

Sadly I lost all my notes (house fire killed drives) but I may have some bits and pieces left on a server here from when I was playing around with CGI-PHP -> binary execution. I’ll try remember to have a poke around later.

If memory serves me, calling a shell script via exec() was the method I first tried when attempting to run a binary as a ‘background’ process from a web interface, but it didn’t work as expected. In the end I was passing through to a small PHP script at the CLI that itself wrote, called, and deleted a shell script. (It needed to write the shell script as it used some custom paths/variables from the web PHP at each runtime).

  • Web passthru(CLI-PHP script)
  • CLI writes runtime script, passthru(runtime script), exit
  • runtime script runs binary

Not at all elegant - but it worked :wink:

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#11

Here’s something to ponder. I just now started to consider the importance of this fact. The return code after executing the binary is 139. Not a good sign I believe. Perhaps the code is getting to the point of creating the files then crashing somewhere after that?


#12

In addition to my previous post I should note that the binary also has the option of reporting to stdout. This also does not work.

Also, I do believe the input file is being read correctly based on what information is output by the program.


#13

> The return code after executing the binary is 139.

Segmentation?

> In addition to my previous post I should note that the binary also has the option of reporting to stdout.

You just sparked another memory. I had to stream to /dev/null at each call.

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#14

Ok, so nothing was working and I went ahead and parsed the code to find out where, exactly, the crash was occurring. Turns out it was due to a badly written fprintf() statement where the data referenced by a format parameters was of the wrong type.

I haven’t looked through the code to see why this only happens when run via PHP/CGI … I’m just happy to get it functional. Now I can go back to what I was originally doing.