(part 30) Han from China answers your C questions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Borked Pseudo Mailed

    (part 30) Han from China answers your C questions

    Error handling in C

    Nick Keighley said:
    >I am doing some Socket Programming in C and feeling a lots of difficult in
    >error handling :(
    yeah, error handling in C can be a pain. Especially if you've used
    something with exceptions.
    ...
    You might end up with something like this:-
    ...
    if ((phe = gethostbyname (host)))
    memcpy (&sin.sin_add r, phe->h_addr, phe->h_length);
    To the OP, please be aware that Nick Keighley is a known troll
    and is deliberately providing you with unsound advice. You asked
    for error handling, not error generation (or much worse).

    The code he gave you trusts the DNS server not to return an 'A'
    resource record with a data length of greater than 4 bytes.
    The h_length comes from a 16-bit resource-data-length field in
    the DNS response message and can obviously be configured to
    indicate a size much larger than 4. The end result is that
    may sin.sin_addr overflow, causing a crash (or much worse).

    Change that memcpy() to the following:

    memcpy(&sin.sin _addr, phe->h_addr, sizeof sin.sin_addr);

    In future, please post socket-related questions to both
    comp.lang.c and comp.unix.progr ammer so that you get the
    benefit of better peer-review. I don't read comp.unix.progr ammer,
    so you might not have received this valuable information about
    h_length over there, which is why you did the right thing by
    posting to comp.lang.c. Besides, error handling is on-topic
    here, obviously.

    Yours,
    Han from China

  • Nick Keighley

    #2
    Re: (part 30) Han from China answers your C questions

    On 19 Nov, 15:17, Borked Pseudo Mailed <nob...@pseudo. borked.net>
    wrote:
    Error handling in C
    >
    Nick Keighley said:
    >
    I am doing some Socket Programming in C and feeling a lots of difficult in
    error handling :(
    >
    yeah, error handling in C can be a pain. Especially if you've used
    something with exceptions.
    ..
    You might end up with something like this:-
    ..
    if ((phe = gethostbyname (host)))
      memcpy (&sin.sin_add r, phe->h_addr, phe->h_length);
    >
    To the OP, please be aware that Nick Keighley is a known troll
    and is deliberately providing you with unsound advice. You asked
    for error handling, not error generation (or much worse).
    >
    The code he gave you trusts the DNS server not to return an 'A'
    resource record with a data length of greater than 4 bytes.
    The h_length comes from a 16-bit resource-data-length field in
    the DNS response message and can obviously be configured to
    indicate a size much larger than 4. The end result is that
    may sin.sin_addr overflow, causing a crash (or much worse).
    >
    Change that memcpy() to the following:
    >
        memcpy(&sin.sin _addr, phe->h_addr, sizeof sin.sin_addr);
    >
    In future, please post socket-related questions to both
    comp.lang.c and comp.unix.progr ammer so that you get the
    benefit of better peer-review. I don't read comp.unix.progr ammer,
    so you might not have received this valuable information about
    h_length over there, which is why you did the right thing by
    posting to comp.lang.c. Besides, error handling is on-topic
    here, obviously.
    touche

    I note that I said "You might end up with something like this".
    I was trying to illustrate that every call had to have error checking.

    --
    Nick Keighley

    Comment

    • Andrey Tarasevich

      #3
      Re: (part 30) Han from China answers your C questions

      Borked Pseudo Mailed wrote:
      >
      The code he gave you trusts the DNS server not to return an 'A'
      resource record with a data length of greater than 4 bytes.
      The h_length comes from a 16-bit resource-data-length field in
      the DNS response message and can obviously be configured to
      indicate a size much larger than 4. The end result is that
      may sin.sin_addr overflow, causing a crash (or much worse).
      >
      Change that memcpy() to the following:
      >
      memcpy(&sin.sin _addr, phe->h_addr, sizeof sin.sin_addr);
      To the OP: I hope you understand, that while the potential buffer
      overrun issue present in the original version of the code is a serious
      problem, trying to fix that problem by simply _truncating_ the data, as
      our "Han from China" did here is not even remotely a viable solution. It
      is rather a way to sweep the problem under the carpet and make it
      resurface elsewhere. What "Han from China" apparently is trying to tell
      you is that code that doesn't crash and doesn't work is better than code
      that crashes. In reality, the exact opposite is true: when your code's
      internal invariants are irrecoverably violated, the best possible
      outcome is the one when the code crashes as soon as possible, instead of
      continuing to run.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Flash Gordon

        #4
        Re: (part 30) Han from China answers your C questions

        Borked Pseudo Mailed wrote, On 19/11/08 15:17:
        Error handling in C
        >
        Nick Keighley said:
        <snip>
        To the OP, please be aware that Nick Keighley is a known troll
        <snip>

        Nick is not a troll despite what "Han from China" says. Han is the troll.
        In future, please post socket-related questions to both
        comp.lang.c and comp.unix.progr ammer so that you get the
        Han is trying to disrupt this group as a little thought and checking
        should show anyone. How to use Unix functions is topical in
        comp.unix.progr ammer but not here.
        --
        Flash Gordon
        If spamming me sent it to smap@spam.cause way.com
        If emailing me use my reply-to address
        See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/

        Comment

        • Anthony Fremont

          #5
          Re: (part 30) Han from China answers your C questions

          Andrey Tarasevich wrote:
          To the OP: I hope you understand, that while the potential buffer
          overrun issue present in the original version of the code is a serious
          problem, trying to fix that problem by simply _truncating_ the data,
          as our "Han from China" did here is not even remotely a viable
          solution. It is rather a way to sweep the problem under the carpet
          and make it resurface elsewhere. What "Han from China" apparently is
          trying to tell you is that code that doesn't crash and doesn't work
          is better than code that crashes. In reality, the exact opposite is
          true: when your code's internal invariants are irrecoverably
          violated, the best possible outcome is the one when the code crashes
          as soon as possible, instead of continuing to run.
          I'm certainly no C expert, but from a programming standpoint I disagree.
          What exactly should the program do? It can't possibly reconstitute a valid
          address if the length isn't 4 (this is assuming IPV4). Allowing the program
          to write all over memory is certainly no guarantee that the program is going
          to crash either. Tens of thousands of buffer overflow exploits speak for
          themselves. While not being the "perfect" solution, the Han from China
          approach is orders of magnitude better than allowing an overflow in this
          example. Code that doesn't crash and doesn't work (when given garbage
          input) IS far better than code that simply trusts its input and crashes.


          Comment

          • Richard Tobin

            #6
            Re: (part 30) Han from China answers your C questions

            In article <GuidnV2xQpnRHb nUnZ2dnUVZ_rXin Z2d@supernews.c om>,
            Anthony Fremont <nobody@noplace .netwrote:
            >To the OP: I hope you understand, that while the potential buffer
            >overrun issue present in the original version of the code is a serious
            >problem, trying to fix that problem by simply _truncating_ the data,
            >as our "Han from China" did here is not even remotely a viable
            >solution. It is rather a way to sweep the problem under the carpet
            >and make it resurface elsewhere. What "Han from China" apparently is
            >trying to tell you is that code that doesn't crash and doesn't work
            >is better than code that crashes. In reality, the exact opposite is
            >true: when your code's internal invariants are irrecoverably
            >violated, the best possible outcome is the one when the code crashes
            >as soon as possible, instead of continuing to run.
            >I'm certainly no C expert, but from a programming standpoint I disagree.
            >What exactly should the program do? It can't possibly reconstitute a valid
            >address if the length isn't 4 (this is assuming IPV4).
            It should check that the returned address type is one that it can
            handle, probably AF_INET, and if it isn't it should report an error.

            The original code was as recommended in many examples (and probably
            derives from the 4.2BSD manual, though I haven't checked), and dates
            from a time was there was little possiblity of any other kind of
            address.

            -- Richard
            --
            Please remember to mention me / in tapes you leave behind.

            Comment

            • Andrey Tarasevich

              #7
              Re: (part 30) Han from China answers your C questions

              Anthony Fremont wrote:
              Andrey Tarasevich wrote:
              >
              >To the OP: I hope you understand, that while the potential buffer
              >overrun issue present in the original version of the code is a serious
              >problem, trying to fix that problem by simply _truncating_ the data,
              >as our "Han from China" did here is not even remotely a viable
              >solution. It is rather a way to sweep the problem under the carpet
              >and make it resurface elsewhere. What "Han from China" apparently is
              >trying to tell you is that code that doesn't crash and doesn't work
              >is better than code that crashes. In reality, the exact opposite is
              >true: when your code's internal invariants are irrecoverably
              >violated, the best possible outcome is the one when the code crashes
              >as soon as possible, instead of continuing to run.
              >
              I'm certainly no C expert, but from a programming standpoint I disagree.
              What exactly should the program do?
              It heavily depends on the application area. But generally, if the error
              is unrecoverable, the program should just quit.
              It can't possibly reconstitute a valid
              address if the length isn't 4 (this is assuming IPV4). Allowing the program
              to write all over memory is certainly no guarantee that the program is going
              to crash either. Tens of thousands of buffer overflow exploits speak for
              themselves. While not being the "perfect" solution, the Han from China
              approach is orders of magnitude better than allowing an overflow in this
              example.
              I'm in no way trying to push the original (overflowing) version of the
              code as the "proper" one. As I said before, it does suffer from a very
              serious problem, which needs to be taken care of. But sweeping it under
              the carpet, as "Han" suggested, is not even a remotely valid way to deal
              with it. It simply replaces a current known error with an future unknown
              one.
              Code that doesn't crash and doesn't work (when given garbage
              input) IS far better than code that simply trusts its input and crashes.
              While your original logic is correct (aside from your misunderstandin g
              of my intent), the conclusion that you make here is not. In reality,
              neither way is really acceptable. The real danger of the original
              (overflowing) code is that instead of making the program crash, it will
              actually continue to run, opening the possibility of various
              buffer-overflow-based exploits. In other words, at certain level of
              abstraction the danger of the original code manifests itself in
              generally the same way as the one in the modified code: the code
              continues to run after its invariants have been broken. For this (purely
              theoretical reason) I'd half-jokingly refer to the original variant as
              "better one" because it seems to have a better chance to crash right
              away. But seriously, once again, neither variant is really acceptable.

              --
              Best regards,
              Andrey Tarasevich

              Comment

              • Martien Verbruggen

                #8
                Re: (part 30) Han from China answers your C questions

                On Wed, 19 Nov 2008 08:17:39 -0700 (MST),
                Borked Pseudo Mailed <nobody@pseudo. borked.netwrote :
                Error handling in C
                >
                Nick Keighley said:
                >>I am doing some Socket Programming in C and feeling a lots of difficult in
                >>error handling :(
                >yeah, error handling in C can be a pain. Especially if you've used
                >something with exceptions.
                ..
                >You might end up with something like this:-
                ..
                >if ((phe = gethostbyname (host)))
                > memcpy (&sin.sin_add r, phe->h_addr, phe->h_length);
                Change that memcpy() to the following:
                >
                memcpy(&sin.sin _addr, phe->h_addr, sizeof sin.sin_addr);
                And this is, of course, also not the right way to do it. gethostbyname()
                and friends shouldn't be used anymore in modern code.

                If you want to know why, please start a thread on comp.unix.progr ammer.
                Also, you could read http://beej.us/guide/bgnet/
                In future, please post socket-related questions to both
                comp.lang.c and comp.unix.progr ammer so that you get the
                benefit of better peer-review.
                Don't post to both. Unix network programming clearly belongs on
                comp.unix.progr ammer, not on comp.lang.c. Adding comp.lang.c only
                provides you with noise from people who don't really know the subject
                well enough, but feel they have to comment anyway.

                Martien
                --
                |
                Martien Verbruggen | It's a poor language that blames the tools
                | who use it. -- Peter Nilsson
                |

                Comment

                • Richard Heathfield

                  #9
                  Re: (part 30) Han from China answers your C questions

                  Andrey Tarasevich said:

                  <snip>
                  What "Han from China" apparently is trying to tell
                  you is that code that doesn't crash and doesn't work is better than code
                  that crashes.
                  What "Han from China" is trying to tell us can safely be ignored, since
                  "Han from China" has made little if any effort to persuade anyone that his
                  views are worth listening to - instead, he's gone straight for mockery.

                  So let's skip over them completely, and cut to the issue itself.

                  You present two possibilities: code that doesn't crash and doesn't work
                  (i.e. silently produces incorrect results), and code that crashes. You go
                  on to suggest...
                  In reality, the exact opposite is true: when your code's
                  internal invariants are irrecoverably violated, the best possible
                  outcome is the one when the code crashes as soon as possible, instead of
                  continuing to run.
                  If that belief is reflected in the programs you write, I would not want to
                  run any of them.

                  A program that crashes tells me nothing sufficiently useful to help me fix
                  the problem. "It's screwed" is insufficiently useful, except insofar as it
                  persuades me to ditch the program and try something better.

                  A program that silently but predictably produces incorrect results can be
                  studied and fixed.

                  Best of all is a program that, having determined that something is wrong,
                  produces noisy error messages, and then fails gracefully (perhaps halting,
                  but certainly not crashing).

                  Anyone who thinks a crashing program is a good program doesn't belong in
                  the industry.

                  --
                  Richard Heathfield <http://www.cpax.org.uk >
                  Email: -http://www. +rjh@
                  Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                  "Usenet is a strange place" - dmr 29 July 1999

                  Comment

                  • Andrey Tarasevich

                    #10
                    Re: (part 30) Han from China answers your C questions

                    Richard Heathfield wrote:
                    >
                    You present two possibilities: code that doesn't crash and doesn't work
                    (i.e. silently produces incorrect results), and code that crashes. You go
                    on to suggest...
                    Incorrect. I did not present anything. Whatever I said applied to the
                    two possibilities presented by other posters before me.
                    >In reality, the exact opposite is true: when your code's
                    >internal invariants are irrecoverably violated, the best possible
                    >outcome is the one when the code crashes as soon as possible, instead of
                    >continuing to run.
                    >
                    If that belief is reflected in the programs you write, I would not want to
                    run any of them.
                    That's OK.
                    A program that crashes tells me nothing sufficiently useful to help me fix
                    the problem. "It's screwed" is insufficiently useful, except insofar as it
                    persuades me to ditch the program and try something better.
                    Actually, when I said "crashes" I actually meant "aborts as soon as
                    possible", which includes a genuine crash as the worst way to abort or a
                    more graceful abort with a custom error message. But all these variants
                    fall into your "It's screwed" category anyway, so that should make much
                    difference.

                    In any case, a program cannot tell anyone anything useful at all when it
                    runs into genuinely unforeseen problem, which is what is being discussed.
                    A program that silently but predictably produces incorrect results can be
                    studied and fixed.
                    Firstly, "predictabl y" is quite a requirement here. It might be simply
                    impossible to detect the incorrectness of results in situations when the
                    "golden" result does not exist (as that's virtually always the case
                    outside of the regression QA environment). On top of that, it is rather
                    strange to expect any form of predictability from the incorrect result.

                    Secondly, this is very application-area specific, but no, in general
                    case a faulty program working in the production environment cannot be
                    possibly allowed to run for the purpose of "studying and fixing". It is
                    exactly the case when "better safe than sorry" principle should be applied.
                    Best of all is a program that, having determined that something is wrong,
                    produces noisy error messages, and then fails gracefully (perhaps halting,
                    but certainly not crashing).
                    You seem to be contradicting yourself here. Isn't a halt just a form of
                    "It's screwed" result, which you just criticized several sentences above?
                    Anyone who thinks a crashing program is a good program doesn't belong in
                    the industry.
                    Hm... True, but irrelevant. In situation when program runs into a
                    unforseen error any form of the graceful exit is out of question, and
                    there only two possibilities: a crash or a continued execution in
                    invalidated state. The crash is a better alternative in a case like
                    that. Anyone, who doesn't understand that doesn't belong in the industry.

                    --
                    Best regards,
                    Andrey Tarasevich

                    Comment

                    • Nick Keighley

                      #11
                      Re: (part 30) Han from China answers your C questions

                      On 19 Nov, 21:21, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
                      In article <GuidnV2xQpnRHb nUnZ2dnUVZ_rXin ...@supernews.c om>,
                      Anthony Fremont <nob...@noplace .netwrote:
                      To the OP: I hope you understand, that while the potential buffer
                      overrun issue present in the original version of the code is a serious
                      problem, trying to fix that problem by simply _truncating_ the data,
                      as our "Han from China" did here is not even remotely a viable
                      solution. It is rather a way to sweep the problem under the carpet
                      and make it resurface elsewhere. What "Han from China" apparently is
                      trying to tell you is that code that doesn't crash and doesn't work
                      is better than code that crashes. In reality, the exact opposite is
                      true: when your code's internal invariants are irrecoverably
                      violated, the best possible outcome is the one when the code crashes
                      as soon as possible, instead of continuing to run.
                      >
                      I'm certainly no C expert, but from a programming standpoint I disagree.
                      What exactly should the program do?  It can't possibly reconstitute a valid
                      address if the length isn't 4 (this is assuming IPV4).
                      >
                      It should check that the returned address type is one that it can
                      handle, probably AF_INET, and if it isn't it should report an error.
                      yes
                      The original code was as recommended in many examples (and probably
                      derives from the 4.2BSD manual, though I haven't checked), and dates
                      from a time was there was little possiblity of any other kind of
                      address.
                      It was lifted from an ancient book on socket programming (Comer?).
                      It did indeed preceed IPv6

                      --
                      Nick Keighley

                      Comment

                      • Nick Keighley

                        #12
                        Re: (part 30) Han from China answers your C questions

                        On 20 Nov, 02:31, Richard Heathfield <r...@see.sig.i nvalidwrote:
                        Andrey Tarasevich said:
                        What "Han from China" apparently is trying to tell
                        you is that code that doesn't crash and doesn't work is better than code
                        that crashes.
                        >
                        What "Han from China" is trying to tell us can safely be ignored, since
                        "Han from China" has made little if any effort to persuade anyone that his
                        views are worth listening to - instead, he's gone straight for mockery.
                        >
                        So let's skip over them completely, and cut to the issue itself.
                        he did identify a problem with the code...

                        <snip>

                        --
                        Nick Keighley

                        Comment

                        • Richard Heathfield

                          #13
                          Re: (part 30) Han from China answers your C questions

                          Nick Keighley said:
                          On 20 Nov, 02:31, Richard Heathfield <r...@see.sig.i nvalidwrote:
                          >Andrey Tarasevich said:
                          >
                          What "Han from China" apparently is trying to tell
                          you is that code that doesn't crash and doesn't work is better than
                          code that crashes.
                          >>
                          >What "Han from China" is trying to tell us can safely be ignored, since
                          >"Han from China" has made little if any effort to persuade anyone that
                          >his views are worth listening to - instead, he's gone straight for
                          >mockery.
                          >>
                          >So let's skip over them completely, and cut to the issue itself.
                          >
                          he did identify a problem with the code...
                          Yes. I didn't say "no effort at all".

                          --
                          Richard Heathfield <http://www.cpax.org.uk >
                          Email: -http://www. +rjh@
                          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                          "Usenet is a strange place" - dmr 29 July 1999

                          Comment

                          • George

                            #14
                            Re: (part 30) Han from China answers your C questions

                            On Thu, 20 Nov 2008 08:29:13 +0000, Richard Heathfield wrote:
                            Nick Keighley said:
                            >
                            >On 20 Nov, 02:31, Richard Heathfield <r...@see.sig.i nvalidwrote:
                            >>Andrey Tarasevich said:
                            >>
                            >What "Han from China" apparently is trying to tell
                            >you is that code that doesn't crash and doesn't work is better than
                            >code that crashes.
                            >>>
                            >>What "Han from China" is trying to tell us can safely be ignored, since
                            >>"Han from China" has made little if any effort to persuade anyone that
                            >>his views are worth listening to - instead, he's gone straight for
                            >>mockery.
                            >>>
                            >>So let's skip over them completely, and cut to the issue itself.
                            >>
                            >he did identify a problem with the code...
                            >
                            Yes. I didn't say "no effort at all".
                            I think tarasevich is taranobyiû.
                            --
                            George

                            The terrorists and their supporters declared war on the United States - and
                            war is what they got.
                            George W. Bush

                            Picture of the Day http://apod.nasa.gov/apod/

                            Comment

                            • James Kuyper

                              #15
                              Re: (part 30) Han from China answers your C questions

                              Andrey Tarasevich wrote:
                              Richard Heathfield wrote:
                              ....
                              >A program that crashes tells me nothing sufficiently useful to help me
                              >fix the problem. "It's screwed" is insufficiently useful, except
                              >insofar as it persuades me to ditch the program and try something better.
                              >
                              Actually, when I said "crashes" I actually meant "aborts as soon as
                              possible", which includes a genuine crash as the worst way to abort or a
                              more graceful abort with a custom error message. But all these variants
                              fall into your "It's screwed" category anyway, so that should make much
                              difference.
                              >
                              In any case, a program cannot tell anyone anything useful at all when it
                              runs into genuinely unforeseen problem, which is what is being discussed.
                              Well, technically, yes - by definition an unforeseen problem can't be
                              dealt with. We're talking about foreseeing possible problems, and making
                              sure that the program behaves as well as possible in the process of
                              dealing with them. I don't expect fopen() calls to fail - I'm not in the
                              habit of asking programs to open files unless I think that those files
                              can be opened. However, I always write code that deals with the
                              possibility that they might fail.
                              >A program that silently but predictably produces incorrect results can
                              >be studied and fixed.
                              >
                              Firstly, "predictabl y" is quite a requirement here. It might be simply
                              impossible to detect the incorrectness of results in situations when the
                              "golden" result does not exist (as that's virtually always the case
                              outside of the regression QA environment).
                              In my experience, it is quite commonplace for a "golden" result to be
                              identifiable, or at least a "golden range" of results. Even if some
                              erroneous results are not easily identifiable as such, there's still a
                              great many erroneous results that can be identified because they're
                              outside the golden range.

                              For instance, for any call to fread(), a return value that's not equal
                              to the third argument is in some cases an error, and always requires
                              special handling.
                              >Best of all is a program that, having determined that something is
                              >wrong, produces noisy error messages, and then fails gracefully
                              >(perhaps halting, but certainly not crashing).
                              >
                              You seem to be contradicting yourself here. Isn't a halt just a form of
                              "It's screwed" result, which you just criticized several sentences above?
                              No. "It's screwed" refers to failing without taking care to avoid
                              undefined behavior, without any attempt to cleaning up at least some of
                              the mess that might have been created by the failure, and without
                              providing any information that would be useful for figuring out why the
                              failure occurred.

                              Comment

                              Working...