Further on Taint - exact code that has the problem

B

Ben

This is a followup to my earlier post, sorry it's not in the same
thread, but it's been several hours and google still hasn't coughed up
the first post, so I can't get it into the same thread.

$cmd = "pogmaker";
$command = "$cmd $part $befo $fute $cols $redd >output.txt &";
$command =~ /(.*)/;
$command = $1;
$ENV{"PATH"}="/bin:/usr/bin";
delete @ENV{'IFS','CDPATH','ENV','BASH_ENV'};
# print "Taint checks seem to be on<br>"
# unless eval { local $^W; unlink "$^X$^T"; 1 };
$rez = system($command);

FYI, the print "Taint.... does not indicate that taint is on by
printing.

pogmaker is in /usr/bin, has execute permission for anyone, owned by
root.

pogmaker absolutely will not run.

Ben
 
L

Louis Erickson

: $cmd = "pogmaker";
: $command = "$cmd $part $befo $fute $cols $redd >output.txt &";
: $command =~ /(.*)/;
: $command = $1;
: $ENV{"PATH"}="/bin:/usr/bin";
: delete @ENV{'IFS','CDPATH','ENV','BASH_ENV'};
: # print "Taint checks seem to be on<br>"
: # unless eval { local $^W; unlink "$^X$^T"; 1 };
: $rez = system($command);

: FYI, the print "Taint.... does not indicate that taint is on by
: printing.

Then I suspect taint is not on. Why do you think taint is on?

: pogmaker is in /usr/bin, has execute permission for anyone, owned by
: root.

: pogmaker absolutely will not run.

Why not? Have you checked the return values from system? See
perldoc -f system to get how to decode the error values from
system to make sure it's working, and check your server logs for
any messages to stderr indicating possible problems from
your program itself.
 
G

Glenn Jackman

Ben said:
$rez = system($command); [...]
pogmaker absolutely will not run.

Find out why:

if ($rez != 0) {
print "<p>'$command' exits status: ", $rez/256, "</p><pre>$!</pre>";
}
 
D

Darren Dunham

Ben said:
This is a followup to my earlier post, sorry it's not in the same
thread, but it's been several hours and google still hasn't coughed up
the first post, so I can't get it into the same thread.
$cmd = "pogmaker";
$command = "$cmd $part $befo $fute $cols $redd >output.txt &";
$command =~ /(.*)/;
$command = $1;
$ENV{"PATH"}="/bin:/usr/bin";
delete @ENV{'IFS','CDPATH','ENV','BASH_ENV'};
# print "Taint checks seem to be on<br>"
# unless eval { local $^W; unlink "$^X$^T"; 1 };
$rez = system($command);
FYI, the print "Taint.... does not indicate that taint is on by
printing.

Does the script output anything else to tell you that it's actually
running?
pogmaker is in /usr/bin, has execute permission for anyone, owned by
root.
pogmaker absolutely will not run.

What is the exit code from the system command? (see $?).
 
B

Ben

Glenn Jackman said:
Ben said:
$rez = system($command); [...]
pogmaker absolutely will not run.

Find out why:

if ($rez != 0) {
print "<p>'$command' exits status: ", $rez/256, "</p><pre>$!</pre>";
}

$rez = 0

$! = ""

Next idea? :)

--Ben
 
B

Ben

Louis Erickson said:
: $cmd = "pogmaker";
: $command = "$cmd $part $befo $fute $cols $redd >output.txt &";
: $command =~ /(.*)/;
: $command = $1;
: $ENV{"PATH"}="/bin:/usr/bin";
: delete @ENV{'IFS','CDPATH','ENV','BASH_ENV'};
: # print "Taint checks seem to be on<br>"
: # unless eval { local $^W; unlink "$^X$^T"; 1 };
: $rez = system($command);

: FYI, the print "Taint.... does not indicate that taint is on by
: printing.

Then I suspect taint is not on. Why do you think taint is on?

The behaviour - runs if used in ('cmd',$parm,$parm,etc) form, but not
if in ("$cmd $parm $parm etc.") form. This behavior is described
fairly closely in perlsec as a consequence of taint being in effect.
No such behavior is described in, or referenced from,
functions/system(), however, which I consider a rather severe
oversight. Taint is not mentioned or referenced either, which it
probably should be.

<ASIDE> I find the perl documentation to be pretty poor in general...
WAY too many assumptions made about what the reader knows, not enough
example code and often, what example code you find there is pretty
darned opaque. I'd offer to contribute, I actually write pretty good
documentation, but the fact that I'm still looking IN the perl
documentation more often than not probably makes me a poor
candidate... sure wish someone would give that stuff a professional
going over. I love perl, but the docs... ugh.</ASIDE>

Also, in perlsec, the following remark is found near the top:

"Perl automatically enables a set of special security checks, called
taint mode, when it detects its program running with differing real
and effective user or group IDs."

....the implication seems to be that taint mode could get turned on
very late, right at the point where the command is invoked, even if it
wasn't on previously. That also leads me to think that taint might be
screwing with things, even if the latest check prior to launch I can
make clearly indicates it isn't.
: pogmaker is in /usr/bin, has execute permission for anyone, owned by
: root.

: pogmaker absolutely will not run.

Why not?

Dunno. That's what this is all about. :)
Have you checked the return values from system?

Yes, indeed. system() returns 0, and $! is empty.
See perldoc -f system to get how to decode the error values from
system to make sure it's working,

Not much decoding required. 0 is 0 even when you divide it by 256. :)
and check your server logs for
any messages to stderr indicating possible problems from
your program itself.

None. Also no indication that the program is running when diagnostics
like create a flag file, sleep for a while so I can look in the
process list are added... it's simply not running. When it does run,
it can run even with no parameters and come up with sensible (but
pointless) output. If I call it as system('cmd',$parm,$parm) it runs
perfectly (but runs too long, I need to fork it either from the
shell's interpretation of & or directly.) If I hack the command to
immediately exit(1), I get 256 as expected in the perl script, as a
return from system(). Change the perl to system("$cmd $parm $parm etc)
and I get nothing.

Additional info that might bear on people thinking on why something
might not run: My program is compiled from c, is relatively small
(about 29k) and is running in a 2 GHz, 1 Gb RH9 system with tons of
available resources. Once it is running, it talks to the PostgreSQL
postmaster in the usual ways, but that's way, way after I put the
diagnostics in - no dependance upon PostgreSQL servers involved, for
absolute certain. I can't get the first line of code to run even when
it's exit(1) if the system call is used with one parameter for shell
evaluation.

Thanks for your previous and potential future response(s.)

--Ben
 
G

Glenn Jackman

Ben said:
Glenn Jackman said:
Ben said:
$cmd = "pogmaker";
$command = "$cmd $part $befo $fute $cols $redd >output.txt &";
$command =~ /(.*)/;
$command = $1;
$rez = system($command); [...]
pogmaker absolutely will not run.

Find out why:

if ($rez != 0) {
print "<p>'$command' exits status: ", $rez/256, "</p><pre>$!</pre>";
}

$rez = 0
$! = ""

Someone else pointed this out in the parallel thread: because you run
$command in the backgrounded, you cannot know its exit status. system()
will return successfully immediately because the forked /bin/sh process
does. Note that the system() docs say:
If there is only one scalar argument, the argument is checked for
shell metacharacters, and if there are any, the entire argument is
passed to the system's command shell for parsing (this is "/bin/sh
-c" on Unix platforms, but varies on other platforms).

Similarly, if you open the command as a pipe, open(X,"$command |"), you
cannot know the exit status until you close() it.

As to why your command is not running, does the web server's user have
permission to write to output.txt? Have a look at what's happening on
stderr:
$command = "$cmd $part $befo $fute $cols $redd >output.txt 2>output.err &";
 
A

Alan J. Flavell

<ASIDE> I find the perl documentation to be pretty poor in general...
WAY too many assumptions made about what the reader knows, not enough
example code and often, what example code you find there is pretty
darned opaque.
[...]

My diagnosis here would be that you're keen to get your job done,
which is understandable, but not keen enough to take a moment to
familiarise yourself with what documentation is available and how best
to use it in your situation.

On the other hand if you really *can* do it better, then feel free to
step right up to the plate ;-)

(I've just needed to undertake a task in MS Excel, using its available
user documentation, after which the Perl documentation seems to be a
gift from Heaven. And as for that demented paperclip... but I
digress...)
Also, in perlsec, the following remark is found near the top:

"Perl automatically enables a set of special security checks, called
taint mode, when it detects its program running with differing real
and effective user or group IDs."

Then bestir yourself to perldoc perlvar, where you will find the Perl
variables described which contain real and effective user and group
IDs; splice into your development copy of the script some code to
print these out at appropriate points, inspect them, and duly consider
the next move (if necessary, post here to tell us what you found).
...the implication seems to be that taint mode could get turned on
very late, right at the point where the command is invoked, even if it
wasn't on previously.

Fair comment
That also leads me to think that taint might be
screwing with things, even if the latest check prior to launch I can
make clearly indicates it isn't.

"Might" be, but I'd be happier to see the results of a few simple
checks (such as noted above, plus my question - which you
side-stepped, but which I think may still be germane - to understand
better some important aspects of the environment - CGI? mod_perl?
setuid? - in which this server-side script is running) to help resolve
the situation.

I can't emphasise too strongly the benefits of stripping-down the
actual problem into a minimal testcase which exhibits the behaviour
of which you're complaining. When you said:

| I apologize for any "woffling." I was attempting to provide all of
| the information I had.

I think the key point here was that a good problem description
contains *enough* *relevant* information: the point is well taken that
you may not yet know just exactly what is "enough" and what is
"relevant", but I was trying to hint that you had on the one hand
included too much extraneous detail (we needed to know that you wanted
to launch a long-running process and not wait for the result: all else
on that side was extraneous detail) while in the other hand missing
the detailed observations of what was happening. OK, fair enough,
it's been clarified in the subsequent discussion as to why some of
that detail wasn't accessible to the invoking script, and I apologise
for initially missing that point.

And actually your report on the observed behaviour got muddled up with
your hunch as to why it was going wrong, which may well prove to be
right - but would be better kept apart until the hunch can be
confirmed or refuted.

I'm sorry that this isn't just a potted recipe to solve your problem,
but I think the above points were worth making, even though I don't
have that recipe on hand. Good luck, and it would be useful to future
readers if you put on record how the issue got resolved.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top