#51 netcat 0.7.1 assumes char to be signed

open-fixed
5
2013-12-18
2011-03-01
Robert Persch
No

The code

ret -= (c >> 7);

in line #157 of netcat_flag_count() in flagset.c assumes char variables to be signed. However, this is platform/compiler dependent, and char variables may also be unsigned. For unsigned char, the code will always return a negative flag count, which will then be taken to mean that no ports are to be addressed.

A possible and simple fix seems to be to add a cast to the expression in line #157, i.e.:

ret -= ((signed char)c >> 7);

Discussion

  • Hi Robert! I committed the fix to cvs branch "netcat_release_0_7". Soon I'll release a RC version so that you can try if this problem is fixed on your platform (what was that, by the way?).

    Thank you for your report
    Giovanni

     
    • assigned_to: nobody --> themnemonic
    • status: open --> open-fixed
     
  • Robert Persch
    Robert Persch
    2011-03-02

    Hi Giovanni,

    thanks for responding so quickly! Some platform information:

    Linux 2.6.32
    ARMv7 (OMAP 3xxx) -- this is an embedded processor
    GCC 4.3.3 (cross-compiler, running on i86 development host)

    On many embedded platforms, char is unsigned, as this can produce smaller or faster code. E.g. it could be there is no processor instruction to directly perform the arithmetic shift right of a signed value that the netcat code is using.

    Robert

     
  • Jimmy Scott
    Jimmy Scott
    2012-10-06

    Hi,

    I have this issue too. Using Arch Linux ARM on a Raspberry Pi (ARMv6).

    I spend an hour reading the source, debugging and fixing it. Then I came to here to report the bug, just to notice it was already reported more than a year ago :-(

    Declaring the char as 'signed char' fixed it for me.

    Kind regards,
    Jimmy Scott

     
  • I've had a similar issue on ARM. My fix has been to change the type of the flagset from "char" into "unsigned char" and then simplified the counting code into:

    while (c) {
      ret += c & 1;
      c >>= 1;
    }
    

    I see no good reason for for having the flagset being signed (except possibly compatibility with legacy systems/compilers?)

    For reference, here's a simple code I've used while debugging to show the problem:

    #include <stdio.h>
    
    int main()
    {
        char c;
        int ret;
    
        c = 1 << 7;
        ret = c;
        printf("%d\n", ret);
    
        return 0;
    }
    

    This displays "-128" on my x86-64 host machine and "128" on my arm-none-linux-gnueabi target.

     
    Last edit: Lionel Flandrin 2013-12-18