Why is it dangerous?

Discussion in 'C Programming' started by Julian, Aug 10, 2008.

  1. Julian

    Julian Guest

    'evening.

    I'm not new to C and have been programming in it since I was 8 but
    here's a strange problem I've never seen before.

    When I compile a program from our C course with a windows compiler
    there is no problem but when I try to compile it with a linux compiler
    it complains that

    a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    and should not be used.

    Is linux more dangerous than windows? Where can I download a
    non dangerous gets function? I have never used gets before is
    there undefined behavior somewhere?


    Here is a trimmed down example program from my assignment that
    demonstrates the problem

    #include <stdio.h>
    #include <malloc.h>

    void main()
    {
    char *string;
    printf("enter string (max 2000 chars): ");
    fflush(stdin);
    fflush(stdout);
    string = (char *)malloc(2001);
    if(!string) exit(1);
    gets(string);
    printf("you entered: %s\n", string);
    free(string);
    exit(0);
    }

    On windows with TurboC and Lcc no error is printed. On linux with
    gcc it says gets is dangerous.

    Please advise my instructor says gcc is overly pedantic.
     
    Julian, Aug 10, 2008
    #1
    1. Advertising

  2. Julian

    Ian Collins Guest

    Julian wrote:
    >
    > Please advise my instructor says gcc is overly pedantic.
    >

    As Richard said, the opposite is true unless you invoke gcc with the
    correct options. That's why it has a -pedantic option!

    As a learner using gcc, you should use

    gcc -ansi -Wall -pedantic

    as a minimum set of options. Substitute '-std=c99' for '-ansi' if you
    are learning C99.

    --
    Ian Collins.
     
    Ian Collins, Aug 10, 2008
    #2
    1. Advertising

  3. Julian

    Guest

    On Aug 9, 7:42 pm, Julian <> wrote:
    > 'evening.
    >
    > I'm not new to C and have been programming in it since I was 8 but
    > here's a strange problem I've never seen before.
    >
    > When I compile a program from our C course with a windows compiler
    > there is no problem but when I try to compile it with a linux compiler
    > it complains that
    >
    > a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    > and should not be used.
    >
    > Is linux more dangerous than windows? Where can I download a
    > non dangerous gets function? I have never used gets before is
    > there undefined behavior somewhere?
    >
    > Here is a trimmed down example program from my assignment that
    > demonstrates the problem
    >
    > #include <stdio.h>
    > #include <malloc.h>
    >
    > void main()
    > {
    >     char *string;
    >     printf("enter string (max 2000 chars): ");
    >     fflush(stdin);
    >     fflush(stdout);
    >     string = (char *)malloc(2001);
    >     if(!string) exit(1);
    >     gets(string);
    >     printf("you entered: %s\n", string);
    >     free(string);
    >     exit(0);
    >
    > }
    >
    > On windows with TurboC and Lcc no error is printed. On linux with
    > gcc it says gets is dangerous.
    >
    > Please advise my instructor says gcc is overly pedantic.


    (Leaving aside all the errors in the code that other people have
    already pointed out and will continue to point out...)

    It has nothing to do with the operating system, it has nothing to do
    with the compiler, it has nothing to do with your instructor; it has
    to do with gets(), and gets() alone (and you can't get a "safer"
    gets(), BTW). The problem is that gets() has no way to know the size
    of the buffer you pass to it, and it will continue to read until a
    newline. You allocated 2001 bytes, which is reasonably large enough
    for a line of text. But... suppose a cracker gets to your program and
    gives you this line on the terminal:

    enter string (max 2000 chars):
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

    Those are 2001 characters. There you go, the cracker overflowed your
    buffer.

    Sebastian
     
    , Aug 10, 2008
    #3
  4. Julian <> writes:
    [...]
    > #include <stdio.h>
    > #include <malloc.h>
    >
    > void main()
    > {
    > char *string;
    > printf("enter string (max 2000 chars): ");
    > fflush(stdin);
    > fflush(stdout);
    > string = (char *)malloc(2001);
    > if(!string) exit(1);
    > gets(string);
    > printf("you entered: %s\n", string);
    > free(string);
    > exit(0);
    > }

    [...]

    This program, in 16 lines, exhibits at least 6 blatant errors or
    gratuitous non-portabilities that have been discussed repeatedly in
    this newsgroup: <malloc.h>, "void main()", "fflush(stdin), casting the
    result of malloc(), exit(1), and of course the use of gets().

    Either this is deliberate, and Julian is a troll, or it's not, and
    he's been very poorly taught. In the latter case, Julian, please read
    read the comp.lang.c FAQ <http://www.c-faq.com/>, and feel free to
    post again if you still have any questions.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 10, 2008
    #4
  5. Julian

    santosh Guest

    CBFalconer wrote:

    > Ian Collins wrote:
    >> Julian wrote:
    >>
    >>> Please advise my instructor says gcc is overly pedantic.

    >>
    >> As Richard said, the opposite is true unless you invoke gcc with
    >> the correct options. That's why it has a -pedantic option!
    >>
    >> As a learner using gcc, you should use
    >>
    >> gcc -ansi -Wall -pedantic
    >>
    >> as a minimum set of options. Substitute '-std=c99' for '-ansi'
    >> if you are learning C99.

    >
    > Correction: That omits many useful tests. I suggest:
    >
    > gcc -W -Wall -ansi -pedantic
    >
    > for better error detection.


    I would also recommend:

    -Wfloat-equal
    -Wshadow
    -Wpointer-arith
    -Wbad-function-cast
    -Wcast-qual
    -Wcast-align
    -Wwrite-strings
    -Wstrict-prototypes
    -Wold-style-definition
    -Wmissing-prototypes
    -Wredundant-decls
    -Wunreachable-code
     
    santosh, Aug 10, 2008
    #5
  6. On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
    > CBFalconer wrote:
    >> Correction: That omits many useful tests. I suggest:
    >>
    >> gcc -W -Wall -ansi -pedantic
    >>
    >> for better error detection.

    >
    > I would also recommend:
    > [...]
    > -Wwrite-strings


    I would not, since it deliberately makes the compiler nonconforming. For
    those that understand in what ways, it can be useful, but they can find
    the option themselves. CBFalconer included that option in his
    recommendations recently, and I'm glad he dropped it.
     
    Harald van Dijk, Aug 10, 2008
    #6
  7. Julian

    santosh Guest

    Harald van D?k wrote:

    > On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
    >> CBFalconer wrote:
    >>> Correction: That omits many useful tests. I suggest:
    >>>
    >>> gcc -W -Wall -ansi -pedantic
    >>>
    >>> for better error detection.

    >>
    >> I would also recommend:
    >> [...]
    >> -Wwrite-strings

    >
    > I would not, since it deliberately makes the compiler nonconforming.
    > For those that understand in what ways, it can be useful, but they can
    > find the option themselves. CBFalconer included that option in his
    > recommendations recently, and I'm glad he dropped it.


    Thanks for that. I do remember that subthread now, but I passed over it,
    being pressed for time. Now, to the Google Groups archive...
     
    santosh, Aug 10, 2008
    #7
  8. Julian

    Ian Collins Guest

    Harald van Dijk wrote:
    > On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
    >> CBFalconer wrote:
    >>> Correction: That omits many useful tests. I suggest:
    >>>
    >>> gcc -W -Wall -ansi -pedantic
    >>>
    >>> for better error detection.

    >> I would also recommend:
    >> [...]
    >> -Wwrite-strings

    >
    > I would not, since it deliberately makes the compiler nonconforming. For
    > those that understand in what ways, it can be useful, but they can find
    > the option themselves. CBFalconer included that option in his
    > recommendations recently, and I'm glad he dropped it.


    Even so, it would save a lot of noise here if it where the default in gcc!

    --
    Ian Collins.
     
    Ian Collins, Aug 10, 2008
    #8
  9. "Malcolm McLean" <> writes:

    > "Gordon Burditt" <> wrote in message
    >> There is no non-dangerous gets() function with the same interface.
    >> The non-dangerous function is called fgets().
    >>

    > This is a hardy annual.
    > Of course fgets() can be used safely, but won't be. For instance
    > Richard Heathfield posted a dangerous use of fgets() in this very
    > thread. It will give the wrong answer if the user enters a string of
    > over 2000 characters.


    You have allowed yourself to slip into polemic. It is not clear, at
    least to me, what the right answer is so you are stretching the point
    -- be careful with fgets and long lines -- by saying that the answer
    is "wrong" and the use "dangerous".

    --
    Ben.
     
    Ben Bacarisse, Aug 10, 2008
    #9
  10. On 10 Aug 2008 at 0:59, Richard Heathfield wrote:
    > Julian said:
    >> a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    >> and should not be used.

    >
    > The functionality of gets() is defined by ISO; it takes a pointer to
    > the first character in a buffer, and stores an entire line from stdin
    > into that buffer, *regardless of the buffer's size*!! There is no safe
    > way to use such a function.


    Of course, this is nonsense. There is a perfectly safe way to use
    gets(), namely by being in control of what appears on stdin. Here in the
    real world, people write all sorts of scraps of in-house code to run
    once and forget about. They use fscanf() without elaborate error
    checking, because they are 100% sure of the format of the input files.
    gets() is no different.

    Of course, in any production code, or any code at all where someone
    other than the programmers will be able to decide what appears on stdin,
    then gets() should not be used, the return value of p=malloc(10) should
    be checked, etc. etc.

    Instead of gets(), use whatever safe function is available on your
    platform. For example, on GNU systems there is a getline() function
    provided by stdio.h, which will dynamically allocated a big enough
    buffer using malloc(). Or, roll your own getline function if portability
    is a big issue for you.
     
    Antoninus Twink, Aug 10, 2008
    #10
  11. Julian

    CBFalconer Guest

    santosh wrote:
    > CBFalconer wrote:
    >> Ian Collins wrote:
    >>> Julian wrote:
    >>>
    >>>> Please advise my instructor says gcc is overly pedantic.
    >>>
    >>> As Richard said, the opposite is true unless you invoke gcc with
    >>> the correct options. That's why it has a -pedantic option!
    >>>
    >>> As a learner using gcc, you should use
    >>>
    >>> gcc -ansi -Wall -pedantic
    >>>
    >>> as a minimum set of options. Substitute '-std=c99' for '-ansi'
    >>> if you are learning C99.

    >>
    >> Correction: That omits many useful tests. I suggest:
    >>
    >> gcc -W -Wall -ansi -pedantic
    >>
    >> for better error detection.

    >
    > I would also recommend:
    >
    > -Wfloat-equal
    > -Wshadow
    > -Wpointer-arith
    > -Wbad-function-cast
    > -Wcast-qual
    > -Wcast-align
    > -Wwrite-strings
    > -Wstrict-prototypes
    > -Wold-style-definition
    > -Wmissing-prototypes
    > -Wredundant-decls
    > -Wunreachable-code


    I wouldn't, although those may be useful. The OP is obviously a
    newbie, and is not going to remember all that. It is only useful
    when implemented via an alias, a script, or a makefile, etc. What
    I recommended is a minimum to ensure reasonably correct standard C
    code.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Aug 10, 2008
    #11
  12. Julian

    CBFalconer Guest

    santosh wrote:
    > Harald van D?k wrote:
    >> santosh wrote:
    >>> CBFalconer wrote:
    >>>
    >>>> Correction: That omits many useful tests. I suggest:
    >>>>
    >>>> gcc -W -Wall -ansi -pedantic
    >>>>
    >>>> for better error detection.
    >>>
    >>> I would also recommend:
    >>> [...]
    >>> -Wwrite-strings

    >>
    >> I would not, since it deliberately makes the compiler nonconforming.
    >> For those that understand in what ways, it can be useful, but they
    >> can find the option themselves. CBFalconer included that option in
    >> his recommendations recently, and I'm glad he dropped it.

    >
    > Thanks for that. I do remember that subthread now, but I passed over
    > it, being pressed for time. Now, to the Google Groups archive...


    I didn't drop it. I conceded your 'non-standard' point. I
    maintain that, for new code, including it will result in better
    code, and maintain conformity. It may object to some actually
    conforming code.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Aug 10, 2008
    #12
  13. Julian

    Richard Guest

    Richard Heathfield <> writes:

    > Julian said:
    >
    >> 'evening.
    >>
    >> I'm not new to C and have been programming in it since I was 8 but
    >> here's a strange problem I've never seen before.
    >>
    >> When I compile a program from our C course with a windows compiler
    >> there is no problem but when I try to compile it with a linux compiler
    >> it complains that
    >>
    >> a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    >> and should not be used.
    >>
    >> Is linux more dangerous than windows?

    >
    > No. Your Linux compiler warned you about a dangerous function that should
    > never be used.


    Total and utter nonsense. C is used all over the place for creating
    elements which are under strict control and the program/process/function
    has a totally controlled and defined input stream. In those scenarios
    gets is used flawlessly in millions of programs around the world.

    if you can NOT define the input then I would agree. But in the real
    world the input is indeed guarenteed in a properly functioning
    system. if the system isn't well defined then all "bets are off" since
    you can pretty much be sure that undefined behaviour/input has already
    compromised the process pipeline.
     
    Richard, Aug 10, 2008
    #13
  14. Julian

    CBFalconer Guest

    Malcolm McLean wrote:
    > "Gordon Burditt" <> wrote:
    >
    >> There is no non-dangerous gets() function with the same interface.
    >> The non-dangerous function is called fgets().

    >
    > This is a hardy annual. Of course fgets() can be used safely, but
    > won't be. For instance Richard Heathfield posted a dangerous use of
    > fgets() in this very thread. It will give the wrong answer if the
    > user enters a string of over 2000 characters. Of course it is not
    > dangerous in a little exercise program that doesn't do anything,
    > but then neither is gets().
    >
    > To use fgets() safely you must check for the newline. If it is not
    > present a buffer overflow occurred. So you must then take action
    > against the buffer to ensure that the next read doesn't get the
    > remainder of the previous line.


    Or just get the remainder of the line. No overflow has occurred.

    And you can avoid all those problems by using the (released to
    public domain) ggets() function, available in standard C source
    form at:

    <http://cbfalconer.home.att.net/downlod/ggets.zip>

    ggets gets complete lines, is safe, and has the simplicity of
    gets. Malicious users can run the system out of assignable heap
    memory, but will normally have to work hard to do so.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Aug 10, 2008
    #14
  15. Julian

    santosh Guest

    Richard wrote:

    > Richard Heathfield <> writes:
    >
    >> Julian said:
    >>
    >>> 'evening.
    >>>
    >>> I'm not new to C and have been programming in it since I was 8 but
    >>> here's a strange problem I've never seen before.
    >>>
    >>> When I compile a program from our C course with a windows compiler
    >>> there is no problem but when I try to compile it with a linux
    >>> compiler it complains that
    >>>
    >>> a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    >>> and should not be used.
    >>>
    >>> Is linux more dangerous than windows?

    >>
    >> No. Your Linux compiler warned you about a dangerous function that
    >> should never be used.

    >
    > Total and utter nonsense. C is used all over the place for creating
    > elements which are under strict control and the
    > program/process/function has a totally controlled and defined input
    > stream. In those scenarios gets is used flawlessly in millions of
    > programs around the world.
    >
    > if you can NOT define the input then I would agree. But in the real
    > world the input is indeed guarenteed in a properly functioning
    > system. if the system isn't well defined then all "bets are off" since
    > you can pretty much be sure that undefined behaviour/input has already
    > compromised the process pipeline.


    I wonder, can you give examples of sources of perfectly controlled and
    defined input? Certainly disk files can be tampered, as can pipes,
    sockets and almost every other device. Why risk it with gets when fgets
    is just as easy and safer?
     
    santosh, Aug 10, 2008
    #15
  16. On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
    > CBFalconer wrote:
    >> Correction: That omits many useful tests. I suggest:
    >> gcc -W -Wall -ansi -pedantic
    >> for better error detection.

    >
    > I would also recommend:
    > [...]
    > -Wpointer-arith


    This is redundant, since it's already enabled by -pedantic.
     
    Antoninus Twink, Aug 10, 2008
    #16
  17. On 10 Aug 2008 at 13:17, santosh wrote:
    > Richard wrote:
    >> Total and utter nonsense. C is used all over the place for creating
    >> elements which are under strict control and the
    >> program/process/function has a totally controlled and defined input
    >> stream. In those scenarios gets is used flawlessly in millions of
    >> programs around the world.

    >
    > I wonder, can you give examples of sources of perfectly controlled and
    > defined input? Certainly disk files can be tampered, as can pipes,
    > sockets and almost every other device.


    True. The world might also be destroyed in a nuclear holocaust while
    your throwaway program is reading its non-life-critical data, so why
    take the risk of programming at all? Drink a beer, get laid, and wait
    for the mushroom cloud to take you.
     
    Antoninus Twink, Aug 10, 2008
    #17
  18. Julian

    Richard Guest

    santosh <> writes:

    > Richard wrote:
    >
    >> Richard Heathfield <> writes:
    >>
    >>> Julian said:
    >>>
    >>>> 'evening.
    >>>>
    >>>> I'm not new to C and have been programming in it since I was 8 but
    >>>> here's a strange problem I've never seen before.
    >>>>
    >>>> When I compile a program from our C course with a windows compiler
    >>>> there is no problem but when I try to compile it with a linux
    >>>> compiler it complains that
    >>>>
    >>>> a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    >>>> and should not be used.
    >>>>
    >>>> Is linux more dangerous than windows?
    >>>
    >>> No. Your Linux compiler warned you about a dangerous function that
    >>> should never be used.

    >>
    >> Total and utter nonsense. C is used all over the place for creating
    >> elements which are under strict control and the
    >> program/process/function has a totally controlled and defined input
    >> stream. In those scenarios gets is used flawlessly in millions of
    >> programs around the world.
    >>
    >> if you can NOT define the input then I would agree. But in the real
    >> world the input is indeed guarenteed in a properly functioning
    >> system. if the system isn't well defined then all "bets are off" since
    >> you can pretty much be sure that undefined behaviour/input has already
    >> compromised the process pipeline.

    >
    > I wonder, can you give examples of sources of perfectly controlled and
    > defined input? Certainly disk files can be tampered, as can pipes,
    > sockets and almost every other device. Why risk it with gets when fgets
    > is just as easy and safer?


    If I have a well defined pipeline then any deviance make the entire line
    corrupt.

    If I have a process whose DEFINED input is say, 16 characters at a time
    on its standard input then its not its job to ensure thats what
    comes. Dont believe me? Try calling strcpy with NULL pointer as the
    destination.

    Since it has NO way of reporting back errors to the program feeding it,
    what should me module do? Carry on processing this rogue data?

    The point is this - one can worry all day long. Once can also be
    practical and "real".

    Its like the malloc business. If malloc fails for a few bytes the chance
    of that program not exhibiting "Undefined Bahvaiour" because you checked
    the return code is practically nil.
     
    Richard, Aug 10, 2008
    #18
  19. On Aug 10, 12:42 pm, Richard<> wrote:
    > Richard Heathfield <> writes:
    > > Julian said:


    > >> I'm not new to C and have been programming in it since I was 8 but
    > >> here's a strange problem I've never seen before.

    >
    > >> When I compile a program from our C course with a windows compiler
    > >> there is no problem but when I try to compile it with a linux compiler
    > >> it complains that

    >
    > >> a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
    > >> and should not be used.

    >
    > >> Is linux more dangerous than windows?

    >
    > > No. Your Linux compiler warned you about a dangerous function that should
    > > never be used.

    >
    > Total and utter nonsense. C is used all over the place for creating
    > elements which are under strict control and the program/process/function
    > has a totally controlled and defined input stream. In those scenarios
    > gets is used flawlessly in millions of programs around the world.
    >
    > if you can NOT define the input then I would agree. But in the real
    > world the input is indeed guarenteed in a properly functioning
    > system.


    hardly. Much web based software does not have total control
    of its inputs. Compilers don't have TCOI. Even if the other end of
    your
    "link" is "trusted" there can be errors made. Yes, you test your
    software but
    why not on the length of input

    > if the system isn't well defined then all "bets are off" since
    > you can pretty much be sure that undefined behaviour/input has already
    > compromised the process pipeline


    how many bugs has gets() caused? Windows certainly. Wasn't the Unix
    worm gets() based?


    --
    Nick Keighley
     
    Nick Keighley, Aug 10, 2008
    #19
  20. Julian

    Serve Lau Guest

    "Antoninus Twink" <> schreef in bericht
    news:...
    > True. The world might also be destroyed in a nuclear holocaust while
    > your throwaway program is reading its non-life-critical data, so why
    > take the risk of programming at all? Drink a beer, get laid, and wait
    > for the mushroom cloud to take you.


    I agree except on one thing. I'd drink the beer last

    >
     
    Serve Lau, Aug 10, 2008
    #20
    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. Anil Kripalani
    Replies:
    2
    Views:
    503
    Eric Lawrence [MSFT]
    Feb 25, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    974
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,213
    Smokey Grindel
    Dec 2, 2006
  4. jayapal

    why the usage of gets() is dangerous.

    jayapal, Nov 16, 2007, in forum: C Programming
    Replies:
    123
    Views:
    2,005
    CBFalconer
    Nov 28, 2007
  5. Arturo
    Replies:
    2
    Views:
    260
    Arturo
    Apr 14, 2004
Loading...

Share This Page