Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Seg fault while running C script as non root (http://www.velocityreviews.com/forums/t313816-seg-fault-while-running-c-script-as-non-root.html)

forrest stanley 06-25-2003 05:14 PM

Seg fault while running C script as non root
 
Hello all,
I am attempting to run this C script as a non root user. (its actually
run from a webpage). The code runs as expected as root. This is a
password changing script. I have removed some of the mail message sent
out, and a few other items. I have tried to set the bit file to make
this script have rrot powers as its run (chmod u+x), but this did not
help. Included is a slightly stripped version of the password changer.
I was hoping someone might be able to review the code, and point out
what could be causing a segmentation fault.


#include <iostream>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
char npword[9];
char * username;
char * useremail;

username = argv[1];
useremail = argv[2];

//open a shell and generate password, read output
FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
head -1","r");
for (int i=0; i<8; i++) {
npword[i] = fgetc(fnp);
}
pclose(fnp);
npword[8] = '\0';


//system call to set password file
FILE* fep = fopen("/tmp/newpw","w+");
fprintf(fep,"%s",npword);
fclose(fep);

//create email template
FILE* fne = fopen("/tmp/resetpassword","w+");
fprintf(fne,"
Login
%s
Password
%s
",username, npword);
fclose(fne);


//system call to send email
char mailpword[100];
char mailSubject[50] = "Your new password";
sprintf(mailpword,"mutt %s -s \"%s\" <
/tmp/resetpassword",useremail,mailSubject);
system(mailpword);

return 0;
}

Jack Klein 06-25-2003 05:34 PM

Re: Seg fault while running C script as non root
 
On 25 Jun 2003 10:14:53 -0700, sdallstar@myway.com (forrest stanley)
wrote in comp.lang.c:

> Hello all,
> I am attempting to run this C script as a non root user. (its actually
> run from a webpage). The code runs as expected as root. This is a
> password changing script. I have removed some of the mail message sent
> out, and a few other items. I have tried to set the bit file to make
> this script have rrot powers as its run (chmod u+x), but this did not
> help. Included is a slightly stripped version of the password changer.
> I was hoping someone might be able to review the code, and point out
> what could be causing a segmentation fault.


This is not a C language issue, C knows nothing at all about root,
chmod, or passwords. All of these things are features of your
operating system, not defined or supported by the C language.

> #include <iostream>
> #include <stdlib.h>
> #include <stdio.h>
>
> int main(int argc, char *argv[])
> {
> char npword[9];
> char * username;
> char * useremail;
>
> username = argv[1];
> useremail = argv[2];


Regardless of system-specific extensions, this code can invoke
undefined behavior and probably crash if it is called with fewer than
two command line arguments.

> //open a shell and generate password, read output
> FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
> head -1","r");


No such function as popen() in the standard C library.

> for (int i=0; i<8; i++) {
> npword[i] = fgetc(fnp);
> }
> pclose(fnp);


Ditto for pclose().

> npword[8] = '\0';
>
>
> //system call to set password file
> FILE* fep = fopen("/tmp/newpw","w+");
> fprintf(fep,"%s",npword);


Another potential crash if the fopen() failed for any reason. Always
check the a NULL return from fopen().

> fclose(fep);
>
> //create email template
> FILE* fne = fopen("/tmp/resetpassword","w+");
> fprintf(fne,"
> Login
> %s
> Password
> %s
> ",username, npword);


Again, crash if fopen() fails.

> fclose(fne);
>
>
> //system call to send email
> char mailpword[100];
> char mailSubject[50] = "Your new password";
> sprintf(mailpword,"mutt %s -s \"%s\" <
> /tmp/resetpassword",useremail,mailSubject);
> system(mailpword);
>
> return 0;
> }


Your problems with functions like popen() and root levels are not
language issues, and you need to discuss them in
news:comp.unix.programmer or perhaps a group for your specific *NIX
flavor, line those in news:comp.os.linux.development.*

But it is quite possible that your crash is the result of calling
fprintf() and fclose() on NULL file pointers. Perhaps your program
does not have access writes to create or write to those files, so the
fopen() is failing.

ALWAYS test the return of fopen() for NULL before using the FILE
pointer.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Martin Ambuhl 06-25-2003 05:42 PM

Re: Seg fault while running C script as non root
 
sdallstar@myway.com (forrest stanley) wrote (25 Jun 2003) in
news:215e7818.0306250914.3641e65b@posting.google.c om / comp.lang.c:

> Hello all,
> I am attempting to run this C script as a non root user.


Some red flags are raised immediately by this, and they are borne out by
the rest of your message. A question about your OS belongs in an
OS-specific newsgroup. And C is not a scripting language. But it gets
*much* worse:

> #include <iostream>


<iostream> is not a C header. C++ questions belong in a newsgroup for
that language. comp.lang.c++ comes to mind. Of course, you will mend
your ways and check the FAQ and the back-traffic before posting there/

> #include <stdlib. (its actually

h>

This garbage is, of course, not part of any computer language.
In C, this would be #include <stdlib.h>
In C++, it would be #include <cstdlib>
In neither language do you just stick comments without delimiters into
code.

> #include <stdio.h>


Before posting your question to comp.lang.c++, learn that the C++ header
is <cstdio>, and is rarely used in programs using <iostream>

> FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
> head -1","r");


popen() is not part of either C or C++. This again means that you need
to go to a platform- or implementation-specific newsgroup where these
additional functions are supported.

> pclose(fnp);


which is of course true for pclose() as well.

> fprintf(fne,"
> Login
> %s
> Password
> %s
> ",username, npword);


This breaking of a literal string across lines should have triggered
some diagnostics. If it didn't, you probably need to crank up your
diagnostics. I suppose you mean
fprintf(fne,"\n"
"Login\n"
"%s\n"
"Password\n"
"%s\n", username, npword);




--
Martin Ambuhl
Returning soon to the
Fourth Largest City in America

Gordon Burditt 06-25-2003 08:14 PM

Re: Seg fault while running C script as non root
 
>I am attempting to run this C script as a non root user. (its actually

What on Earth is a "C script"?

>run from a webpage). The code runs as expected as root. This is a


If something is expected to run as root, then it would be a REALLY
good idea to check whether your calls to fopen() fail before
attempting to use the result. Don't be too surprised if fopen()
fails when running with insufficient privileges.

>password changing script. I have removed some of the mail message sent
>out, and a few other items. I have tried to set the bit file to make
>this script have rrot powers as its run (chmod u+x), but this did not
>help. Included is a slightly stripped version of the password changer.
>I was hoping someone might be able to review the code, and point out
>what could be causing a segmentation fault.


Passing a NULL FILE * parameter to functions like fprintf() because
you didn't check whether fopen() failed is one way you might get a
smegmentation fault.


>
>
>#include <iostream>

^^^^^^^^^^
This sure doesn't look like C to me.

>#include <stdlib.h>
>#include <stdio.h>
>
>int main(int argc, char *argv[])
>{
> char npword[9];
> char * username;
> char * useremail;
>
> username = argv[1];
> useremail = argv[2];
>
> //open a shell and generate password, read output
> FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
>head -1","r");
> for (int i=0; i<8; i++) {
> npword[i] = fgetc(fnp);
> }
> pclose(fnp);
> npword[8] = '\0';
>
>
> //system call to set password file
> FILE* fep = fopen("/tmp/newpw","w+");
> fprintf(fep,"%s",npword);
> fclose(fep);
>
> //create email template
> FILE* fne = fopen("/tmp/resetpassword","w+");
> fprintf(fne,"
> Login
> %s
> Password
> %s
> ",username, npword);
> fclose(fne);
>
>
> //system call to send email
> char mailpword[100];
> char mailSubject[50] = "Your new password";
> sprintf(mailpword,"mutt %s -s \"%s\" <
>/tmp/resetpassword",useremail,mailSubject);
> system(mailpword);


What does the above do when someone tries to change the password
for the username:
x"`rm -rf /`"x
(The quotes are part of the username). Hint: the results will
not be pretty. Maybe you shouldn't be running programs that
are setuid-root invoked from web servers without CAREFULLY
checking your input?

>
> return 0;
>}


Gordon L. Burditt

Micah Cowan 06-26-2003 03:13 AM

Re: Seg fault while running C script as non root
 
sdallstar@myway.com (forrest stanley) writes:

> Hello all,
> I am attempting to run this C script as a non root user. (its actually
> run from a webpage). The code runs as expected as root. This is a
> password changing script. I have removed some of the mail message sent
> out, and a few other items. I have tried to set the bit file to make
> this script have rrot powers as its run (chmod u+x), but this did not
> help. Included is a slightly stripped version of the password changer.
> I was hoping someone might be able to review the code, and point out
> what could be causing a segmentation fault.
>
>
> #include <iostream>


The above is not a standard C header, and therefore off-topic here.

It *is* a standard C++ header, but as you do not seem to be writing
standard C++ (no std namespace), you should probably just remove it.

> #include <stdlib.h>
> #include <stdio.h>
>
> int main(int argc, char *argv[])
> {
> char npword[9];
> char * username;
> char * useremail;
>
> username = argv[1];
> useremail = argv[2];
>
> //open a shell and generate password, read output
> FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
> head -1","r");


The above function is not defined by either you or the C standard. If
you want the POSIX version (off-topic here), you should stick

#define _POSIX_C_SOURCE 199506L

or similar before #including any headers--for maximum
standards-compliance and portability.

And then you should take this thread to news:comp.unix.programmer .

Also, since you never check the return value of popen(), or any of
your fopen() calls, you don't know if you're getting NULL, in which
case a segfault is likely.

Also, you don't check to see if argv[1] and argv[2] exist, so you'd
better damn well hope they do :)

> for (int i=0; i<8; i++) {


OK: since you are declaring i here, you are either writing
non-standard C++, or you are writing in C99. If the former, you are
off-topic here.

> npword[i] = fgetc(fnp);
> }
> pclose(fnp);
> npword[8] = '\0';
>
>
> //system call to set password file
> FILE* fep = fopen("/tmp/newpw","w+");
> fprintf(fep,"%s",npword);
> fclose(fep);
>
> //create email template
> FILE* fne = fopen("/tmp/resetpassword","w+");
> fprintf(fne,"
> Login
> %s
> Password
> %s
> ",username, npword);
> fclose(fne);
>
>
> //system call to send email
> char mailpword[100];
> char mailSubject[50] = "Your new password";
> sprintf(mailpword,"mutt %s -s \"%s\" <
> /tmp/resetpassword",useremail,mailSubject);


It would be quite easy to overflow mailpword[] here, also causing a
segfault (if you're *lucky*...)

> system(mailpword);
>
> return 0;
> }


-Micah

Vijay B 06-26-2003 08:54 PM

Re: Seg fault while running C script as non root
 
Well Micah,

From my experience in C segfaults occur when you
1) Do not malloc for a pointer(In this case space has already been
allocated by the declaration of an array)
2) The file you are opening does not exist.
Generally good coding standards will be to check if fp is
null...So if we have a file names foo.data then the code would look
like this

File *fp = fopen("foo.data","r");
if(fp==NULL) {
printf("Error message");
return;
}
/* Code to do the manipulation of the file starts here */
3) Another place where your code could be buggy is when you try to
access the command line args. Once again u should ensure that the 2
arguments are present (keep in mind the args vector starts from 0) .
No assumptions should ever be made abt the number of inputs a user can
give. This will coz the code to crash at times.

Check and see if my above suggestions work. I have a lot of
experience with segfaults :). The best way to tackle this problem if
the above solutions dont work is to either use GDB or to use a lot of
printf statements to trap the exact line of code which causes the code
to segfault.

Hope this helps

Vijay


Micah Cowan <micah@cowan.name> wrote in message news:<m3llvpmsy8.fsf@localhost.localdomain>...
> sdallstar@myway.com (forrest stanley) writes:
>
> > Hello all,
> > I am attempting to run this C script as a non root user. (its actually
> > run from a webpage). The code runs as expected as root. This is a
> > password changing script. I have removed some of the mail message sent
> > out, and a few other items. I have tried to set the bit file to make
> > this script have rrot powers as its run (chmod u+x), but this did not
> > help. Included is a slightly stripped version of the password changer.
> > I was hoping someone might be able to review the code, and point out
> > what could be causing a segmentation fault.
> >
> >
> > #include <iostream>

>
> The above is not a standard C header, and therefore off-topic here.
>
> It *is* a standard C++ header, but as you do not seem to be writing
> standard C++ (no std namespace), you should probably just remove it.
>
> > #include <stdlib.h>
> > #include <stdio.h>
> >
> > int main(int argc, char *argv[])
> > {
> > char npword[9];
> > char * username;
> > char * useremail;
> >
> > username = argv[1];
> > useremail = argv[2];
> >
> > //open a shell and generate password, read output
> > FILE* fnp = popen("/usr/bin/tr -dc 'A-z' < /dev/urandom | fold -7 |
> > head -1","r");

>
> The above function is not defined by either you or the C standard. If
> you want the POSIX version (off-topic here), you should stick
>
> #define _POSIX_C_SOURCE 199506L
>
> or similar before #including any headers--for maximum
> standards-compliance and portability.
>
> And then you should take this thread to news:comp.unix.programmer .
>
> Also, since you never check the return value of popen(), or any of
> your fopen() calls, you don't know if you're getting NULL, in which
> case a segfault is likely.
>
> Also, you don't check to see if argv[1] and argv[2] exist, so you'd
> better damn well hope they do :)
>
> > for (int i=0; i<8; i++) {

>
> OK: since you are declaring i here, you are either writing
> non-standard C++, or you are writing in C99. If the former, you are
> off-topic here.
>
> > npword[i] = fgetc(fnp);
> > }
> > pclose(fnp);
> > npword[8] = '\0';
> >
> >
> > //system call to set password file
> > FILE* fep = fopen("/tmp/newpw","w+");
> > fprintf(fep,"%s",npword);
> > fclose(fep);
> >
> > //create email template
> > FILE* fne = fopen("/tmp/resetpassword","w+");
> > fprintf(fne,"
> > Login
> > %s
> > Password
> > %s
> > ",username, npword);
> > fclose(fne);
> >
> >
> > //system call to send email
> > char mailpword[100];
> > char mailSubject[50] = "Your new password";
> > sprintf(mailpword,"mutt %s -s \"%s\" <
> > /tmp/resetpassword",useremail,mailSubject);

>
> It would be quite easy to overflow mailpword[] here, also causing a
> segfault (if you're *lucky*...)
>
> > system(mailpword);
> >
> > return 0;
> > }

>
> -Micah


Mark McIntyre 06-26-2003 09:51 PM

Re: Seg fault while running C script as non root
 
On Thu, 26 Jun 2003 14:09:27 -0400, in comp.lang.c , Eric Sosman
<Eric.Sosman@sun.com> wrote:

>Pay heed to the Sixth
>Commandment, unbeliever!
>
> "If a function be advertised to return an error code
> in the event of difficulties, thou shalt check for
> that code, yea, even though the checks triple the size
> of thy code and produce aches in thy typing fingers,
> for if thou thinkest ``it cannot happen to me'', the
> gods shall surely punish thee for thy arrogance."


I seem to remember that quote ending " in the presence of thy most
valued Client"...

> -- http://www.lysator.liu.se/c/ten-commandments.html


ah, not quite, but nearly...
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---

Micah Cowan 06-27-2003 07:41 AM

Re: Seg fault while running C script as non root
 
vijbala@hotmail.com (Vijay B) writes:

> Well Micah,
>
> From my experience in C segfaults occur when you
> 1) Do not malloc for a pointer(In this case space has already been
> allocated by the declaration of an array)
> 2) The file you are opening does not exist.
> Generally good coding standards will be to check if fp is
> null...So if we have a file names foo.data then the code would look
> like this
>
> File *fp = fopen("foo.data","r");
> if(fp==NULL) {
> printf("Error message");
> return;
> }
> /* Code to do the manipulation of the file starts here */
> 3) Another place where your code could be buggy is when you try to
> access the command line args. Once again u should ensure that the 2
> arguments are present (keep in mind the args vector starts from 0) .
> No assumptions should ever be made abt the number of inputs a user can
> give. This will coz the code to crash at times.
>
> Check and see if my above suggestions work. I have a lot of
> experience with segfaults :). The best way to tackle this problem if
> the above solutions dont work is to either use GDB or to use a lot of
> printf statements to trap the exact line of code which causes the code
> to segfault.


Er, thanks Vijay, but I didn't write the problematic code you are
referring to; and in the message you responded to, I made exactly the
same recommendations you are making here.

Except that I didn't top-post :-)

-Micah

Micah Cowan 06-27-2003 07:51 AM

Re: Seg fault while running C script as non root
 
sdallstar@myway.com (forrest stanley) writes:

> Ahh, how I love the newsgroup. Always expect a few flames from
> friendly people with nothing to do at work (or at home, sorry, get
> layed off?).


<grin> -- you really think those were *flames*? They seemed pretty
cordial to me, especially considering you obviously had failed to have
the common decency to read the FAQ, and you had posted code which
didn't look too terribly much like ISO C, the only legal topic for
this newsgroup (besides meta-topics such as topicality).

> This code had no intentions of running as root, I was
> just stating that it would fail on non-root access. Anyways, luckily
> some of the people offered some constructive critisism, and I found my
> error. This new code works as intended. Also, this code can only be
> called by another script, and the other script performs any error
> checking required before it goes through.


Well, as other people have pointed out, this assertion is completely
unbelievable, considering that you still don't check the return of
fopen().

But, even if you could 100% guarantee that fopen() will succeed every
time, this style of coding is desipicable to me. If at least for the
sake of pride in your own work, isn't it worth building it with the
least little bit of *quality*?

> #include <stdlib.h>
> #include <stdio.h>
>
> int main(int argc, char *argv[])
> {
> char npword[8];
> char * username;
> char * useremail;
> char * userpass;
>
> username = argv[1];
> useremail = argv[2];
> userpass = argv[3];
>
> FILE* fnp = fopen("/foo/pw","w+");
> for (int i1 = 0; i1 < 6; i1++)
> fprintf(fnp,"%c",userpass[i1]);
> fclose(fnp);
>
> FILE* fgp = fopen("/foo/pw","r");
> fgets(npword,8,fgp);
> fclose(fgp);
>
> FILE* fne = fopenfoo/rp","w+");
> fprintf(fne,"\n"
> "Login\n"
> "%s\n"
> "Password\n"
> "%s\n"
> ,username, npword);
> fclose(fne);
>
> //system call to send email
> char mailpword[100];
> char mailSubject[50] = "Your new password";
> sprintf(mailpword,"mutt %s -s \"%s\" <
> /foo/rp",useremail,mailSubject);
> system(mailpword);
>
> return 0;
> }



Joona I Palaste 06-27-2003 07:51 AM

Re: Seg fault while running C script as non root
 
Micah Cowan <micah@cowan.name> scribbled the following:
> sdallstar@myway.com (forrest stanley) writes:
>> Ahh, how I love the newsgroup. Always expect a few flames from
>> friendly people with nothing to do at work (or at home, sorry, get
>> layed off?).


> <grin> -- you really think those were *flames*? They seemed pretty
> cordial to me, especially considering you obviously had failed to have
> the common decency to read the FAQ, and you had posted code which
> didn't look too terribly much like ISO C, the only legal topic for
> this newsgroup (besides meta-topics such as topicality).


No, *this* is a flame (albeit milder than what some people could come
up with):

http://groups.google.com/groups?q=Ja...inki.fi&rnum=1

--
/-- Joona Palaste (palaste@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"How come even in my fantasies everyone is a jerk?"
- Daria Morgendorfer


All times are GMT. The time now is 09:18 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.