Errata

jm December 3rd, 2006

Below is all currently identified errata. Some issues will be explained in more detail in the blog under the Errata Category. Were planning on leaving this page open for comments so people can post additional errata.

First Edition, First and Second Printing

Ch# Pages Type Credit Description
2 27 typo Meder Kydyraliev First paragraph, Line 4: monkey market accounts should read money market accounts
2 41 typo Rhys Last paragraph, last sentence reads "Further, asymmetric encryption" but it should read "Further, symmetric encryption"
3 87 typo mjf Second paragraph, Line 3: "However, you should aware" should read "However, you should be aware"
5 177 typo mjf First paragraph, Line 4: "Remember that authenticated()" should read "Remember that authenticated". The parenthesis indicate that authenticated is a function, where its actually a local variable.
5 188 typo Willem De Groef First inline code block, Line 5: movb $0�0b should read movb $0�0b, %al
5 189 typo mark Missing label in the second inline code block
6 252 tech Dominique Brezinski Line 6 says (MAX_LEN - 1) is 256, but it is actually 255
6 285 typo sp Listing 6-32, Line 10: if ((ntohl(n->sequence_number) <= g_last_sequence number) should read if (ntohl(n->sequence_number) <= g_last_sequence_number)
6 286 tech Dominique Brezinski Listing 6-33, Line 10: if (!memcmp(a, b, sizeof(a))) should read if (!memcmp(a, b, sizeof(*a))) . See Doms analysis below.
7 318 tech jm First inline code, Line 5: bloblen = ntohl(blob); should read bloblen = read_int(blob);
7 352 typo tgo Listing 7-30, Page 2, Line 21: if(nl){ should read if(nl)
7 352 tech ilja Listing 7-30, Function read_line(): ilja noticed a vulnerability in this function that wasnt intended as part of the example. strchr() is called on a potentially unterminated stack buffer, so if the byte 0�0a is found before the null-termination byte 0�00 on the stack, memory will be unintentionally modified. This could lead to an exploitable condition or information disclosure. The string should be null terminated after the call to read(), with code like the following: data[sizeof(data)-1]=\0;
7 363 typo jm Listing 7-33, Page 2, Line 24: sizeof(struct cipher) < 0) should read sizeof(struct cipher)) < 0)
8 428 typo ilja Listing 8-19, Line 8: poen() should read popen()
8 434 tech mark Listing 8-21, Line 12: perform_query(buffer) should read perform_query(buf)
8 435 typo ilja Second inline code segment reads $input_data =~ s/[^A-Za-z0-9]/g; should read $input_data =~ s/[^A-Za-z0-9]//g;
9 482 typo ilja Last paragraph (pg 482), Line 4: The privileged sendmail group is smmsp, not smssp
9 525 typo jm First inline code segment, Line 5: fchmod(fd, 644); should read fchmod(fd, 0644);
10 600 typo tgo First inline code segment, Line 12; return env->value); should read return (env->value);
10 600 typo tgo Second inline code segment, Line 5; intlength = should read int length =
11 625 - 684 typo ilja Left-side page header should read "Chapter 11Windows 1: Objects and the File System" instead of "Chapter 11Objects and the File System"
11 642 typo jm

Restricted TokensF should read Restricted Tokens

12 730 typo Ryan Smith First sentence: properinitialization should be proper initialization
13 805 typo tgo Inline code segment, Line 6; if(read_packet_header(sock, &header)) < 0) should read if(read_packet_header(sock, &header) < 0)
13 809 typo Ryan Smith (Last paragraph, first sentence): you should use your scoreboard, not user it
16 932 typo ilja Line 8 in the inline code: The automatic variable string_length should be domain_length
16 986 typo jm Second paragraph, Line 2: "It takes a request from a user, tough function" should read "It takes a request from a user, through a function"
17 1009 typo Rhys First paragraph, last sentence: "and HTTP request" should read "an HTTP request"

First Edition, First Printing

Ch# Pages Type Credit Description
2 57 layout justin Mislabeled diagram
6 224 tech jm "Type coercion" is synonymous with "implicit type conversion," not both explicit and implicit type conversion. Additional info here.
6 273 tech rCs The behavior of right shift of a signed variable is implementation-defined, however the explanation on page 273 implies that arithmetic right shift is part of the standard. More information is available here.
7 319 tech jm First inline code, Line 9: length = ntohl(&pkt[1]); should read length = read_int(&pkt[1]);
7 337 tech tgo Listing 7-23, Line 7: calloc(strlen(string+1,sizeof(string)))) should read calloc(strlen(string)+1, 1)))
Line 11: switch(*cp){ should read switch(*string){
Line 14: *dest++ = \; should read *dest++ = \\;
Line 20 and 23: case \n: and default: should both be followed by the line escape = 0;
Line 24: *string = *dest++; should read *dest++ = *string;
7 351 typo tgo Listing 7-30, Line 11: memcpy(buffer->data + buffer->used, n); should read memcpy(buffer->data + buffer->used, data, n);
9 482, 484 typo ilja Last paragraph (pg 482), Line 4; and first paragraph (pg 484), Line 2: The privileged sendmail group is smmsp, not smssp
9 517 tech rCs Figure 9-5: The diagram implies that the link count attribute of a file inode is updated when that file is the target of a symbolic link. This is incorrect, as the link count only reflects the number of hard links that exist for the file. More information here.
10 609 typo Ryan Smith Second paragraph, second sentence: a file that ws parsed should read a file that was parsed
10 613 typo Ryan Smith Second paragraph, second sentence: you the get should read you get the
11 632 tech justin Handle enumeration explanation fails to address PROCESS_DUP_HANDLE permission. Additional info here.
12 736 typo Ryan Smith Fourth paragraph, last sentence: C_IMP_LEVEL_IDENTIFY should read RPC_IMP_LEVEL_IDENTIFY
13 805 typo tgo Inline code segment, Line 23: case QUIT should read case QUIT:
17 1023 typo Rhys Fourth paragraph, third sentence: arg=h1 should read arg=hi
17 1046 typo Rhys Third paragraph, second sentence: "logic and structure are probably be easy to piece together" should read "logic and structure are probably easy to piece together"
17 1048 typo Rhys Auditing tip, third sentence: "Determine if any of these unanticipated situations cause a page use" should read "Determine if any of these unanticipated situations cause a page to use"

49 Responses to “Errata”

  1. jmon 24 Dec 2006 at 2:48 pm

    Added three errata entries from tgo, but accidentally deleted his comments. Sorry bout that, but thanks for the submissions!

  2. tgoon 31 Dec 2006 at 4:47 am

    two small typos on page 600. in the first block of code it has “return env->value);” the second block doesnt have a space between int and length.

  3. tgoon 03 Jan 2007 at 5:37 am

    two small typos on page 805. “if (read_packet_header(sock,&header))

  4. jmon 03 Jan 2007 at 7:12 am

    Got them, thanks! Not sure what’s going on with the comments, but I’ll check it out when I get a chance.

  5. Meder Kydyralievon 10 Jan 2007 at 10:27 am

    Chapter 2, page 27 says ‘monkey market accounts’, which should be ‘money market accounts’. Fun typo.

  6. Rhyson 18 Jan 2007 at 5:17 am

    What appears to be a typo on pg 41 … “Further, asymmetric encryption has no means for verifying the sender of a message among any group of shared key users”.

    Shouldn’t that be “symmetric encryption has no means of verifying the sender”, as all users in a group share the same keys? I can see how it could apply to asymmetric encryption and public keys as well, but it would make for an oddly constructed paragraph and not 100% correct.

  7. Rhyson 28 Jan 2007 at 4:34 pm

    Typo on pg 1009, end of first paragraph “… which can be retrieved via and HTTP request.”

    Obviously ‘and’ is incorrect, but there then is the issue of the oft incorrectly employed indefinite article (a vs. an) before a h-word. Usually ‘an’ is used when the h is silent, or when the acronym is pronounced like a word rather than as individual letters; neither of which apply to ‘HTTP’.

    However, Merriam-Webster’s English Usage now recommends that ‘a’ vs. ‘an’ be selected based on which ever pronunciation is easier. Maybe it’s just my Australian accent, but ‘an HTTP request’ sounds better by my reckoning :P

  8. Rhyson 29 Jan 2007 at 6:56 am

    Typo on pg 1023, in relation to GET query strings: The URI is entered into the browser as containing “arg1=h1″, whereas the HTTP request on the network is described as containing “arg1=hi”.

    Typo on pg 1046, first dot point of ‘Client Visibility’: “.. the site’s logic and structure are probably be easy to piece together…” extraneous ‘be’ there.

    Typo on pg 1048, in the Auditing Tip box: “Determine if any of these unanticipated situations cause a page to use the input without first validating it.” the addition of ‘to’ corrects the sentence.

  9. jmon 31 Jan 2007 at 11:28 am

    Much thanks, Rhys. :> I agree with you on the ‘an HTTP request’ thing, so we’ll see what AW says. Again, thanks for all the errata.

  10. Jeremiah Blatzon 13 Feb 2007 at 7:06 pm

    I’m hoping to win the award for “most frivolous error,” here’s my first submission:
    On page 287, it says “When you read code written by experienced developers, you often see complex expressions that seem to be precariously void of parenthesis.” This should be “overconfident developers.” Experienced developers put in the parenthesis.

  11. jmon 13 Feb 2007 at 11:24 pm

    lol! That’s a good point. :> I think I wrote that sentence after being frustrated when this one developer kept getting lucky playing fast and loose with precedence, and I eventually decided he was probably just smarter than me.

  12. Willem De Groefon 03 Mar 2007 at 10:42 am

    On page 188:

    movl $address_of_argv, %ecx

    movb $0xob but no register!

    According to the example on page 189, this should be movb $0×0b, %al

  13. jmon 13 Mar 2007 at 5:12 am

    Note to self: page 986 - gethostbyname() is not a tough function :>

  14. iljaon 20 Mar 2007 at 6:56 am

    on page 352 (listing 7-30, page 2)

    in read_line():

    .

    n = read(sockfd, data, sizeof(data)-1);

    if (n <= 0)

    return -1;

    if ((ptr = strchr(data, \n))){

    n = ptr - data;

    nl = 1;

    }

    data[n] = ;

    .

    looks like read_line() can actually corrupt memory on the stack. since the data is read from the wire it doesnt have to be 0-terminated, and using the strchr() function on it is not safe. There could be a chance that it scans beyond the buffer where you read from and for example the saved ebp has a \n in it (or saved eip, whatever, just something thats interesting), n will get adjusted to point to that place, and itll get overwritten with the 0-byte. yea, I know, the stars have to align and all that. anyways, Im assuming this is an unforseen bug in the sample code, since the explanation after listing 7-30 doesnt mention it at all. I guess 0-terminating the string before the use of strchr() would solve it .

  15. mjfon 26 Mar 2007 at 12:13 am

    Page 87, first paragraph

    However, you should aware, Im guessing that should be However, you should be aware.

  16. mjfon 03 Apr 2007 at 10:46 am

    On page 177 in the first paragraph,

    (Remember that authenticated() is at the top of the stack frame.) I think the parenthesis should be removed from around the variable named authenticated, as it makes it look like a function (but its a local variable).

  17. Dominique Brezinskion 20 Apr 2007 at 7:26 pm

    Maybe I am stupid, but I think Listing 6-33 on page 286 is incorrect or totally confusing. The point is structure padding and logic errors leading to a double free. I think the example has an improper use of sizeof() that makes the code broken for a whole different reason. Here goes my analysis:

    In free_sechdrs(struct sh *a, struct sh *b) the conditional check is if (!memcmp(a, b, sizeof(a))). a is a pointer to a struct sh object, so sizeof(a) is 4 (or whatever the size of a pointer is on the architecture). As struct sh is defined, this conditional is actually checking whether (a->base == b->base), but the example is really meant to show that memcmp(a, b, sizeof(struct sh)) does not necessarily return the correct logical result even if the structure elements of a and b are equal, given that the padding bits could differ.

    Fix: change conditional in free_sechdrs() to if (!memcmp(a, b, sizeof(struct sh)))

  18. iljaon 07 Jun 2007 at 12:34 am

    page 399

    If the username parameter to this function is longer than 1024 bytes, the strlcat() size parameter underflows

    but the sample code uses strncat() not strlcat().

  19. iljaon 07 Jun 2007 at 12:41 am

    chapter 11, missing part of the title.

    chapter 9, 10 and 12 start of with: Chapter 9 UNIX I: , Chapter 10 UNIX II: , Chapter 12 WINDOWS II: but for chapter 11 it says Chapter 11 Objects and the File System instead of Chapter 11: WINDOWS I: Object and the File System. this bit me in the ass when I needed to look something up and was looking for WINDOWS I: (all pages in chapter 11 have this)

  20. spon 22 Jul 2007 at 4:30 pm

    Hi,

    there are two typos in Listing 6-32 on pages 284/285.

    The line with the if-statement starts with two opening parentheses even though one parenthesis is enough (the second parenthesis is never closed).

    In the same line theres the comparison with g_last_sequence number which should probably be g_last_sequence_number (additional underscore).

  21. jmon 24 Jul 2007 at 9:58 pm

    Thanks for all the errata everyone!

    ilja - good spot on the nul-termination bug. oops! :>

    dom - Nice spot and analysis on the structure padding example. It wasnt a particularly great synthetic example to begin with, and that mistake made it completely incorrect and misleading.

  22. Mathiason 01 Sep 2007 at 8:11 pm

    Just found a little bug, not security relevant, though. The read_line() function on page 137 may work fine for little endian systems except for the mentioned problem with the 0-byte write but on big endian systems buf is filled with 0s only. Thats because the variable behind the pointer in the read() function is actually an int, not a char. This changes the very first byte of the int in the memory. So for little endian systems thats ok, but for big endian systems this read() changes the most significant byte, not the least significant. So the char value of that int never changes and is 0 all the time.

    Futhermore, on page 138 there are some typos regarding the desk-check. The assignments for buf[2] and buf [3] are wrongshould be C and D instead of B.

  23. Bruce Dangon 04 Sep 2007 at 6:40 am

    p. 282: printf(%d\n, i++, i++); should be printf(%d %d\n, i++, i++);

  24. Jayon 23 Sep 2007 at 3:13 pm

    Listing 8-25, IMHO the example code is not correct, even it should show an error code. i think you need to add an dst +=3 after the memmove copy line, or (*dst++ = *src++) will overwrite the first 3 bytes later, results: example code does not work.

  25. Drew Yaoon 25 Dec 2007 at 11:31 pm

    Not exactly an errata, but:

    On page 489 there is a list of things to look for when permanently dropping privileges. One thing that the book doesnt mention, is that you should make sure that privileged resources are no longer available to the process after the priv drop. Specifically, any file descriptors to privileged files that are no longer needed should be closed.

    If there was a file descriptor leak, and the process is compromised via a buffer overflow, or the process execs an attacker-controlled program, then the attacker would have access to a privileged file.

    This is mentioned on page 587 in the section on file descriptor leaks. But IMO it should also be in the checklist on page 489.

  26. jmon 17 Jan 2008 at 8:15 pm

    (From Kurt on the Suggestions page)

    Page 208: Ones complement . has the amusing ambiguity of having two values of zero: positive zero and negative zero. This is not amusing, since at the hardware level there is no ambiguity. Since negative zero is less than zero. So, there is a potential security problem, since codes often compare to zero. Since we are talking about integers and not IEEE floats, negative zero and positive zero are the same. ((-x) - (-x)) < (x-x), for positive x, if done directly in hardware as printed, and the hardware does not have extra hardware to check for this special case.

  27. jmon 17 Jan 2008 at 8:54 pm

    Kurt,

    Ah, that sentence is poorly written. The complication for the machine I was referring to was having to implement end-around carry, but Id imagine thats probably not a particularly significant technical barrier. (Im a bit outside of my area of expertise here.) I agree that the ambiguity of negative and positive zero is a human problem of meaning, and not a machine-level issue, as that sentence implies.

    Ive never worked on a ones complement machine before, but I absolutely would imagine that it would lead to security exposures.

    Its interesting to note that twos complement trades the -0/+0 ambiguity for the one we detail on page 235/236, where for a 32-bit twos complement int, -0×80000000 == 0×80000000.

  28. Miguel Correiaon 12 Feb 2008 at 3:30 pm

    Congratulations for the excellent book.

    Typo: listing 9-4, pg 529: S_IFREG should be S_ISREG

  29. RSGBon 11 Mar 2008 at 1:19 am

    page 426: execve() example at the top should have a NULL terminated array entry for char *args[]

  30. Kurtison 02 Sep 2008 at 4:09 am

    page 380, first sentence following code sample: remove because.

  31. tpingon 18 Sep 2008 at 5:31 pm

    Typo, page 301.

    each answer in the DNS response packet (as tracked by anscount), making

    According to the provided code (page 300) there is no anscount. It should be ancount.

  32. tpingon 02 Oct 2008 at 4:34 pm

    Typo, page 330.

    to the size of the destination buffer buf.

    buf on the above sentence is highlighted as a variable but on the given code the destination buffer is named dst. Also, at which writes the NUL one byte past bufs buf should be dst too.

  33. tpingon 07 Oct 2008 at 6:11 am

    Listing 7-29 (pages 347-348).

    if(!(key = read_key(sock))) Should be if(!(k = read_key(sock)))

  34. tpingon 14 Oct 2008 at 9:33 pm

    Typo, page 366.

    packet into the ss->sec.ci.ClientChallenge buffer

    According to the code in Listing 7-34 it should be ss->sec.ci.clientChallenge

    Typo, page 384.

    Therefore, whenever new_size() and

    This is a variable in Listing 7-47, it should be new_size

    Listing 8-2 (page 396) in function is_username_valid() line 6. It

    should be strchr(username, :) instead of strchr(name, :)

  35. tpingon 23 Oct 2008 at 12:34 am

    Page 408.

    bob:test

    newuseruser:newpassword

    Have to be:

    bob:test

    newuser:newpassword

    Page 426.

    The command to be executed should be:

    /usr/bin/sendmail -s hi user@host.com

    However, the 0th element on the args[] is -s

    instead of the name of the application.

    Page 435, Listing 8-22

    if(strchr(bad_characters, *input)

    Misssing on more ) at the end.

    Page 437.

    its the newline ((\n) character.

    Should be:

    its the newline (\n) character.

    Page 452, Listing 8-29

    MultiByteToWideChar(CP_ACP, 0, name, strlen(filename), buf, sizeof(buf)/2);

    Should probably be:

    MultiByteToWideChar(CP_ACP, 0, name, strlen(name), buf, sizeof(buf)/2);

  36. morphicon 06 Nov 2008 at 1:52 pm

    Figure 14-12 on page 873.

    The SYN-ACK diagram have 2 Seq fields, the second one were supposed to be Ack: 0xabce.

  37. tpingon 09 Nov 2008 at 8:05 pm

    Page 478, Listing 9-1

    [plaguez@plaguez bin]$ ID

    On his advisory is:

    [plaguez@plaguez bin]$ id

    Page 487

    The service has an option thatallows

    There should be a space:

    The service has an option that allows

    Page 500

    Say a user creates a ~/login.conf file

    According to the advisory it should be:

    Say a user creates a ~/.login.conf file

    Page 518

    If homedir is greater than PATH_MAX - strlen(/.optconfig)

    there will be truncation.

    Page 519

    The environment variable SOMEVARcontains

    Should probably have a space:

    The environment variable SOMEVAR contains

    Page 530, Figure 9-8

    At the time of check the figure has access() but

    the program at Listing 9-4 uses lstat() instead.

    Page 556

    if(fprintf(fp, %s:%s:%lu:%lu:%s:%s%s\n,

    I think it should be:

    if(fprintf(fp, %s:%s:%lu:%lu:%s:%s:%s\n,

    In order to separate with colon the users

    home directory from the users default shell.

  38. tpingon 27 Nov 2008 at 12:11 am

    Page 616

    strncpy(sun.sun_path, path, sizeof(sun.sun_path)-1;

    Missing a close parenthesis.

    Pages 623-624

    At:

    switch(rqstp->rq_cred.oa_flavor){

    and:

    aup = (struct authunix_params *)rqstp->rq_cred;

    There is no rqstp svc_req structure, either rename the:

    int authenticate(struct svc_req *svc)

    on page 623 to rqstp or the above ones to svc.

  39. jmon 27 Nov 2008 at 1:20 am

    Thanks for all your hard work tping.. Ill get around to adding these to the list shortly. Very much appreciated.

  40. tpingon 30 Nov 2008 at 10:50 pm

    First of all, thank you too for writing this marvelous book

    and sharing this knowledge. Now, here is what Ive found

    on chapter 11:

    Page 634

    the bInheritable parameter 8h a CreateProcess() call

    According to MSDN this is named bInheritHandles. The same typo

    is also located at the same page, after a few lines:

    by setting a true value in the bInheritable member

    Here according to MSDN for SECURITY_ATTRIBUTES structure this

    should be: bInheritHandle. Lastly, at the end of the first

    paragraph:

    DuplicateHandle() and passing a true value for the bInheritable

    Which once more, according to MSDN should be bInheritHandle.

    Page 636

    look for the bInheritable parameter in calls to the CreateProcess()

    Same as above, bInheritable should be bInheritHandles.

    Page 643

    HANDLE NewTokenHandle) according to the prototype of

    the MSDN: PHANDLE NewTokenHandle.

    Page 664

    char *ProfileDirectory = c:\profiles;

    Should be:

    char *ProfileDirectory = c:\\profiles;

    Page 671

    _snprintf(buf, sizeof(buf), %s\\%s.txt, ProfileDirectory, Name);

    Should be:

    _snprintf(buf, sizeof(buf), %s\\%s.txt, ProfileDirectory, UserName);

    Page 678

    snprintf(path, sizeof(path)-1, c:\\temp\\%s_%s_%s.txt, user, filename, ext);

    Should be:

    snprintf(path, sizeof(path)-1, c:\\temp\\%s_%s_%s.txt, username, filename, ext);

  41. tpingon 07 Dec 2008 at 1:45 am

    Page 693

    ZeroMemory(&wc, sizeof(wnd));

    There is no wnd. The block size

    should be either sizeof(wc) or sizeof(WNDCLASSEX)

    Also the:

    return RegisterClassEx( &wnd );

    Should be replaced with &wc.

    Later, at the next function:

    WINDOW hwnd;

    Should be:

    HWND hwnd; since CreateWindow() returns

    this type of object and this variable is used to hold

    the return value of CreateWindow().

    Next, an MSG structure is used:

    GetMessage( &msg, 0, 0, 0 )

    But there is no declaration of this variable

    in the given functions.

    Page 695

    Missing a dash on the provided URL, it is:

    http://blackhat.com/presentations/bh-usa-04/bh-us-04-moore/bh-us-04-moore whitepaper.pdf

    Instead of:

    http://blackhat.com/presentations/bh-usa-04/bh-us-04-moore/bh-us-04-moore-whitepaper.pdf

    At the same page:

    SetProcessWindowStation(hwinsta);

    Should be:

    SetProcessWindowStation(hWinsta);

    Page 701

    Return FALSE; Should be: return FALSE;

    Page 702

    Return FALSE; Should be: return FALSE;

    Page 737

    if(FAILED(rc))

    Return FALSE;

    Again it should be: return FALSE;

  42. tpingon 15 Dec 2008 at 10:22 pm

    Page 757

    for(list = global_list; list->next; list = list->next);

    list->next = element;

    Should be:

    for(tmp = global_list; tmp->next; tmp = tmp->next);

    tmp->next = element;

    Page 761

    Int thread1(void)

    Should be:

    int thread1(void)

    Page 769

    HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpAttributes,

    According to MSDN it should be:

    HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

    At the same page:

    HANDLE OpenSemaphore(DWORD dwDesiredAccess, BOOL bInheritable,

    Should be:

    HANDLE OpenSemaphore(DWORD dwDesiredAccess, BOOL bInheritHandle,

    And finally:

    HANDLE CreateWaitableTimer(LPSECURITY_ATTRIBUTES lpAttributes,

    Should be:

    HANDLE CreateWaitableTimer(LPSECURITY_ATTRIBUTES lpTimerAttributes,

    Page 770

    HANDLE OpenWaitableTimer(DWORD dwDesiredAccess, BOOL bInheritable,

    Should be:

    HANDLE OpenWaitableTimer(DWORD dwDesiredAccess, BOOL bInheritHandle,

    Page 822

    Starzets demonstrated how to leverag this bug

    Should be:

    Starzets demonstrated how to leverage this bug

  43. tpingon 21 Dec 2008 at 6:02 pm

    Page 841

    header_length = ntohs(iph->hl);

    Should be:

    header_length = ntohs(iph->ihl);

    Page 855, Figure 14-2:

    The last fragment has incorrectly set its MF flag on.

    It should not be set.

    Page 856

    offset = ntohs(iph->frag_offset) * 8;

    end = offset + ntohs(iph->tot_len) - iph->hl << 2;

    Should be:

    offset = ntohs(iph->frag_off) * 8;

    end = offset + ntohs(iph->tot_len) - iph->ihl << 2;

    And the same element is used on netinet/ip.h iphdr struct.

    to retrieve the MF/DF flags, so:

    if(!(iph->flags & IP_MF))

    Should be:

    if(!(iph->frag_off & IP_MF))

  44. tpingon 24 Dec 2008 at 7:19 pm

    Page 901, Figure 15-4

    The second node should be renamed from DNS to FTP.

    Page 938

    int read_header(int soc, char **buffer)

    Should be:

    int read_header(int sock, char **buffer)

    Page 943

    tcp_read_data(s, data, clen);

    Should be:

    tcp_read_data(sock, data, clen);

    Page 968

    long doi;

    Should probably be: unsigned long doi;

  45. iljaon 05 Sep 2009 at 3:12 am

    how bout a layout bug ? coz those are really important, right ?
    on page 781, it says reader_task() in table 13-1 where the first r has a different font than the rest of the function name.

    jeebus, can’t believe I have nothing better to do than report a font issue on a friday night ….

  46. dwighton 05 Oct 2009 at 3:33 pm

    Chapter 6 - Section “Pointer Arithmetic” - “Vulnerabilities”


    int buf[1024];
    int *b=buf;

    while (havedata() && b < buf + sizeof(buf))
    {
    *b++=parseint(getdata());
    }

    The intent of b < buf + sizeof(buf) is to prevent b from advancing past buf[1023]. However, it actually prevents b from advancing past buf[4092]. " <– shouldn’t it be "buf[4095]" ??

  47. Jeffrey Waltonon 29 Nov 2009 at 10:54 am

    Hi All,

    I believe the discussion of ‘Handle Inheritance’ (pp. 633-34) has a small verbage issue.

    Page 634: “…Windows does provide an explicit mechanism for passing open object instances to its children, called *handle inheritance*.” I believe the correct term is “Object Handle Inheritance”. Confer, Windows via C/C++, p. 43.

    Jeff

  48. Jeffrey Waltonon 29 Nov 2009 at 11:03 am

    Hi All,

    believe the discussion of ‘Handle Inheritance’ (pp. 633-34) has a small usage issue.

    Page 634: “Alternately, the handle can be marked inheritable by calling DuplicateHandle() and passing a TRUE value for for the bInheritable argument.” I believe the most common way to enable inheritance is to use SetHandleInformation() with HANDLE_FLAG_INHERIT. Calling DuplicateHandle() is not necessary and may have the side effect of causing handle table bloat. It’s kind of like killing a fly with a cannon ball. Confer, Windows via C/C++, p. 46.

    Jeff

  49. Jeffrey Waltonon 29 Nov 2009 at 11:15 am

    Chapter 2, p.27 Errata: “…monkey market accounts should read money market accounts”

    Considering what the Wall Street MBA’s have done, monkey market accounts is probably more appropriate.

    Jeff

Permanent Link | Comments RSS

Leave a Reply