Sometimes you just have to use a variable to terminate the string yourself.
Original:
fprintf(log_file, "By user %s \n", getenv("USER"));Change (off the top of my head, without testing):
char * username=getenv("USER");
fprintf(log_file, "By user %s \n" &username, );This may not fix the problem, but using variables give you a little more control, especially when there is NULL terminated or EOF input involved. You might have to loop through the string looking for EOF, but the main idea is that you control the contents of the array (char *) before you print it. Assigning the value terminates the string.
In your case, this does not appear to be a problem of using the environment variable from getenv(), which does not have a value when the user does not login normally. But, if there is a null string or invalid input for some reason, capturing the text input first should prevent a segfault, because the string would be terminated.
At 01:55 PM 2/10/2005, you wrote:
Ran into an interesting problem with an in-house program here, that I helped fix, but was wondering if anyone's seen this before and especially if anyone has a link to where this might be explained officially on the net. I did searches and didn't find anything.
Problem was a program that would run fine on a amd64 host if you logged in, but
if you ran on the same host via LSF (Load Sharing Facility.. batch job system)
it would fail. We finally tracked it down to a problem with the value from a
getenv call.. which ltrace showed:
9271 getlogin() = NULL 9271 getenv("USER") = "mmarion" 9271 getenv("USER") = "mmarion" 9271 fprintf(0x00585950, "By user %s \n", "EOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOF"... <unfinished ...> 9271 --- SIGSEGV (Segmentation fault) --- 9271 +++ killed by SIGSEGV +++
You can see that getenv("USER") returned a valid answer, but the pointer's value
was then immediately changed to tons of EOF.. which I _think_ is on-purpose to
get poeple to stop using getenv, since you could easily overload the values.
I was able to replace the getenv calls with getpwid(getuid()) and it works like
a charm. But.. like I said, I'd love to see a page on the web that spells out
this deliberate change.
Oh, and the difference between the lsf run and the logged-in one is that even if
you just start a remote shell using lsf, you're not in the utmp file, and the
getenv call seems (in strace output) to look in there to verify if you're
locally logged-in or not.. when when not, that's when the change to the EOF's
happens. To help stop remote root exploits I think.
You can see my fix works:
old: fprintf(log_file, "By user %s \n", getenv("USER")); mine: fprintf(log_file, "By user %s \n", getpwuid(getuid())->pw_name);
ltrace: 15441 getuid() = 32836 15441 getpwuid(32836, 0x7fbfffdd70, 0, 0x2a956f91d9, 0xfefeffffffffffff) = 0x2a958891c0 15441 fprintf(0x00502a00, "By user %s \n", "mmarion") = 17
BTW, my C fu is _really_ weak.. but I slog by like this from time to time. So no picking on me. :P
-- Mike Marion-Unix SysAdmin/Staff Engineer-http://www.miguelito.org Marge: "Homer, sitting that close to the TV can't be good for you." Homer: "Talking while the TV's on can't be good for you!" ==> Simpsons
-- [email protected] http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-list
-- [email protected] http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-list
