Seg fault while running C script as non root

Discussion in 'C Programming' started by forrest stanley, Jun 25, 2003.

  1. 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 = 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;
    }
    forrest stanley, Jun 25, 2003
    #1
    1. Advertising

  2. forrest stanley

    Jack Klein Guest

    On 25 Jun 2003 10:14:53 -0700, (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 = 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
    Jack Klein, Jun 25, 2003
    #2
    1. Advertising

  3. (forrest stanley) wrote (25 Jun 2003) in
    news: / 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
    Martin Ambuhl, Jun 25, 2003
    #3
  4. >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 = 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
    Gordon Burditt, Jun 25, 2003
    #4
  5. forrest stanley

    Micah Cowan Guest

    (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 = 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
    Micah Cowan, Jun 26, 2003
    #5
  6. forrest stanley

    Vijay B Guest

    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 <> wrote in message news:<>...
    > (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 = 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, Jun 26, 2003
    #6
  7. On Thu, 26 Jun 2003 14:09:27 -0400, in comp.lang.c , Eric Sosman
    <> 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 =---
    Mark McIntyre, Jun 26, 2003
    #7
  8. forrest stanley

    Micah Cowan Guest

    (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, Jun 27, 2003
    #8
  9. forrest stanley

    Micah Cowan Guest

    (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;
    > }
    Micah Cowan, Jun 27, 2003
    #9
  10. Micah Cowan <> scribbled the following:
    > (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=J...m=9gl89n$7po$&rnum=1

    --
    /-- Joona Palaste () ---------------------------\
    | 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
    Joona I Palaste, Jun 27, 2003
    #10
  11. forrest stanley

    Micah Cowan Guest

    Joona I Palaste <> writes:

    > Micah Cowan <> scribbled the following:
    > > (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=J...m=9gl89n$7po$&rnum=1


    Yowza. I remember that guy. I still think it's terrific that his
    asshole-ness is forever archived in the annals of USENET.

    OTOH, that reminds me of how many times *my* idiocy got recorded...

    -Micah
    Micah Cowan, Jun 27, 2003
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vinod

    Suprising seg fault!!!

    Vinod, Sep 27, 2003, in forum: C++
    Replies:
    3
    Views:
    465
    Ron Natalie
    Sep 27, 2003
  2. Corrine
    Replies:
    1
    Views:
    420
    Gianni Mariani
    Nov 27, 2003
  3. Manuel Maria Diaz Gomez

    fstream::open & seg fault

    Manuel Maria Diaz Gomez, Jul 20, 2004, in forum: C++
    Replies:
    3
    Views:
    1,193
    John Harrison
    Jul 20, 2004
  4. goktan
    Replies:
    4
    Views:
    2,022
    Howard
    Aug 2, 2004
  5. hector
    Replies:
    5
    Views:
    412
    CBFalconer
    Dec 5, 2006
Loading...

Share This Page