Sunday, October 28, 2018

How to fix "CONSTANT EXPRESSION RESULT" type coverity warnings in c code

Constant Expression Result - Coverity Warning:
    In this post we can discuss about a common logical error in the "if" condition evaluation statement which may lead to the "Constant Expression Result" type coverity warning in C code. Because of this logical error, the expression in the "if" condition evaluates to be either true or false always.
   Coverity tool will report "constant expression result" error when an expression is evaluated to be either true or false always irrespective of the value of the operands in that expression. That is, the expression's value does not depend on its operands. Consider the below C program.

Example 1: Expression always evaluates to be "false"

    In this program, we wanted to print the statement "Condition Met" only for the inputs red and green.

 #include <stdio.h>
typedef enum
{
    violet = 1,
    indigo,
    blue,
    green,
    yellow,
    orange,
    red
}tVIBGYOR;

void VerifyColour (tVIBGYOR input)
{
    if ((input == red) && (input == green))
    {
        if (input == red)
            printf ("Condition Met for RED\n");
        if (input == green)
            printf ("Condition Met for GREEN\n");
    }
}
int main ()
{
    VerifyColour (violet);
    VerifyColour (green);
    VerifyColour (red);
    VerifyColour (orange);
  
    return 0;
}

Output:

root@ubuntu:~/Programs# ./a.out
root@ubuntu:~/Programs#

    When we execute the program, the "Condition Met" statement is not at all being printed for any input value passed. The  reason is that, the below condition check in the "if" statement in the function "VerifyColour" always evaluated to be false.

     if ((input == red) && (input == green))

    In this statement we expect the variable "input" to have two different values at the same time whic is not possible. Even though when we pass the input as "red", the other condition of "input == green" will not be met. Similarly for the input "violet", none of the condition would be met. Eventually, the statement evaluated to be false irrespective of input arguments. So coverity reports this as "CONSTANT_EXPRESSION_RESULT" warning for this condition check.

How to Solve:

    If we change the "if" statement as below, the issue will get resolved.

    if ((input == red) || (input == green))

   With this change, the program will print the "Condition Met" statement when the input is either "red" or "green".

root@ubuntu:~/Programs# ./a.out
Condition Met for GREEN
Condition Met for RED
root@ubuntu:~/Programs#


Example 2: Expression always evaluates to be "true"

    In this example, we want to print the input value along with "Condition Met" statement except for the input values "red" and "green".

 #include <stdio.h>
typedef enum
{
    violet = 1,
    indigo,
    blue,
    green,
    yellow,
    orange,
    red
}tVIBGYOR;

void VerifyColour (tVIBGYOR input)
{
    if ((input != red) || (input != green))
    {
        printf ("Condition Met. Value=%d\n",(int)input);
    }
}
int main ()
{
    VerifyColour (violet);
    VerifyColour (green);
    VerifyColour (red);
    VerifyColour (orange);
  
    return 0;
}

Output:
root@ubuntu:~/Programs# ./a.out
Condition Met. Value=1
Condition Met. Value=4
Condition Met. Value=7
Condition Met. Value=6
root@ubuntu:~/Programs#

    In this program, the below "if" statement in the function "VerifyColour" is evaluated to be "true"  always.

    if ((input != red) || (input != green))

   When we pass the input as "red",  the second condition "input != green" gets satisfied and the condition passes. Similarly for input "violet", the expression is again is evaluated to be "true".

How to Solve:
    If we modify the expression as below, the program works as expected.

    if ((input != red) && (input != green))

    With this change, the program will print the input value except for the inputs "red" and "green".

root@ubuntu:~/Programs# ./a.out
Condition Met. Value=1
Condition Met. Value=6
root@ubuntu:~/Programs#




 

   

Saturday, October 27, 2018

A Relationship between Function Pointer and Function Calling Convention in "C"

C - Function pointer & Calling Convention - Relationship:
    There is a unique relationship between function pointer and function calling convention in C. The function calling convention is one of the parameters that define the signature of a function. Each function pointer can be used to manipulate the functions with a particular signature. So, a function with different calling convention cannot be manipulated by the same function pointer. 

What is Function Calling Convention in "C":
     
    When ever a function is called in C, a stack frame is created in the stack area for that function. Stack frame stores several information relevant to that function. The arguments passed to the function, local variables, return address, etc will be stored in that stack frame. When the execution of the function completes, the stack frame will be destroyed.
    The C function calling convention tells the compiler things such as
  • The order in which the function arguments are pushed onto the stack.
  • Stack Cleanup Responsibility: When the function execution completed, whether the caller or called function will take care of destroying the stack
    The calling convention belongs to a  function's signature. To know about what function's signature implies, click here. Some of the calling conventions used in C compilers are __stdcall, __pascal, __cdecl and __fastcall. Every compilers follow their own way to specify the calling convention during the function definitions/declarations. Because of this, it may be possible to get linking errors such as "unresolved external" if we try to link object files compiled with different compilers.

    For example, the Borland and Microsoft compilers mandates the specification of calling convention type between function return type and function name.

    //Borland and Mircrosoft calling convention specification
   <FnReturnType> <calling_convention_type> FnName(argument)

   Example: void __cdecl TestFunction(char *str);

    For the GNU GCC, the __attribute__ keyword is used to specify the function calling convention.
    <FnReturnType> __attribute__((cdecl)) FnName (arguments)

    Example: void __attribute__((cdecl)) TestFunction (char *str) ;

Function Pointer & Calling Convention Relationship:

    A function pointer always points to a function with specific signature. So, we cannot use the same function pointer to point functions with two different signature. As the calling convention of a function is one of the signature parameters, we cannot use the same function pointer to manipulate a function with two different calling convention.

Illustrative Example:
     Consider the below C program to understand the concepts introduced above.

#include <stdio.h>
int add (int,int); /* Function with default calling convention */
int sub (int,int); /* Function with default calling convention */
int __attribute__((fastcall)) sub_new (int,int) ; /* Function with __fastcall type calling convention */
int main()
{
    int var1 = 10, var2 = 20, rslt = 0;

   
    int (*FunPtr) (int,int) = NULL; /* A function pointer which accepts a function whose return
                                       type is integer and accepts two integer arguments and the
                                       function with default calling convention*/

    int __attribute__((fastcall)) (*NewFunPtr) (int,int) = NULL;  /* A function pointer with non-
                                                                                                          default calling convention */

    FunPtr = &add;

    rslt = FunPtr (var1,var2); /* Calling the function add */
    printf ("Addition Result:%d\r\n",rslt);

    FunPtr = sub;

    rslt = FunPtr (var1,var2); /* Calling the function sub */
    printf ("Subtraction Result:%d\r\n",rslt);

    FunPtr = sub_new; /* We are assigning a function with different calling convention */

    rslt = FunPtr (var1,var2); /* Calling the function sub_new */
    printf ("Subtraction with __fastcall calling type -->Result:%d\r\n",rslt);

    NewFunPtr = sub_new; /* We are assigning a function with proper calling convention */

    rslt = NewFunPtr (var1,var2); /* Calling the function sub_new */
    printf ("Subtraction with __fastcall calling type and __fastcall Fn.Ptr --> Result:%d\r\n",rslt);

    return 0;
}

int add (int val1, int val2)
{
    return (val1+val2);
}

int sub (int val1, int val2)
{
    return (val1-val2);
}

int __attribute__((fastcall)) sub_new (int val1, int val2)
{
    return (val1-val2);
}

Compilation Warning:
    When we compile this using gcc, it throws warning for possible incompatible pointer type assignment at the line "FunPtr = sub_new;"

root@ubuntu:~/Programs# gcc -Wall FnPtr2.c
FnPtr2.c: In function ‘main’:
FnPtr2.c:25:12: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
     FunPtr = sub_new; /* We are assigning a function with different calling convention */
            ^
root@ubuntu:~/Programs#

Output:

root@ubuntu:~/Programs# ./a.out
Addition Result:30
Subtraction Result:-10
Subtraction with __fastcall calling type -->Result:-938653831     <<< junk value is returned when we used function pointer with different calling convention.
Subtraction with __fastcall calling type and __fastcall Fn.Ptr --> Result:-10   <<< Result is proper when the calling convention matches.
root@ubuntu:~/Programs#


References:

 https://www.tenouk.com/Bufferoverflowc/bufferoverflowvulexploitdemo31.html

Wednesday, October 24, 2018

A Network Traffic Generator tool using Linux Utilities


    Most of the time in the development and testing of Networking products, we may need to test the product by injecting the traffic to it. We can use any traffic generator tools like Spirent or IXIA to construct and inject the traffic to our DUT (Device Under Test). These traffic generators are separate hardware devices that we need to purchase and for each type of feature on the device we need to get license too which is costlier.
   For simple testing, we can use the Linux utilities to construct and send the packet out of ethernet ports. We can connect our DUT to this ethernet port and test it.

   In this post we can see how to construct and send the packets on ethernet ports using Linux utilities. A prerequisite to use this script is that we need to have the ASCII hexdump of packet that we need to inject.

   The Linux utility "text2pcap" and open source tool "packEth" is used to generate and send out the traffic via particular ethernet port. The utility "text2pcap" is available by default in most Linux distributions. The "packEth" tool can be downloaded from here . Download the packEth tool for linux version.

    The "packEth" tool sends the packet given as input via an Ethernet interface that we specify. But the input file needs to be in "pcap" format. So, when we know the ASCII hexdump of packet that we need to send, we can use the utility "text2pcap" which will convert the text file which contains the packet content in ASCII hexdump format, into a "pcap" file. Then we can send that "pcap" file using the "packEth" tool.

text2pcap:
    This utility reads in an ASCII hex dump and writes the data described into pcap file.
 
    text2pcap -d <infile> <outfile>

    This command will read packet content from "infile" and  will generate the "outfile" in .pcap format. If there is any parse error while processing input file, it will be displayed on the screen. To know about the way of formatting the input file of "text2pcap" tool, click here.

How to install "packEth":
  • Download the "packEth" tool for Linux version here.
  • Extract the package using the command "tar xvjf packETH-1.9.tar.bz2"
  • Go to "packETH-1.9/cli" and give "make". This will generate the "packETHCli" utility inside that path. This utility will send the packet out of the specified eth port.
How to use "packETHCli":
      packETHcli -i <Interface> -m 1 -f  <pcap_file> 

      This command will send out one instance of the given packet "pcap_file" out of the given "Interface".

     Use the command "packETHcli -h" to know more about the usage of utility.

Illustration:

    Consider the scenario where we have a file "garp_ascii_hex" which contains a GARP packet in ASCII HEX format.

[root@centos-5-vm cli]# cat garp_ascii_hex
0000  ff ff ff ff ff ff 02 02 02 02 02 02 08 06 00 01   ................
0010  08 00 06 04 00 01 02 02 02 02 02 02 c0 a8 01 01   ................
0020  ff ff ff ff ff ff c0 a8 01 01 00 00 00 00 00 00   ................
0030  00 00 00 00 00 00 00 00 00 00 00 00               ............
[root@centos-5-vm cli]#

   Now, we want to send this packet out of ethernet port using "packETHcli" utility. As "packETHcli" accepts only the files in .pcap format, we use the "text2pcap" utility to convert the above packet from ASCII HEX format into .pcap format.

    ./text2pcap  -d garp_ascii_hex  garp_pkt.pcap

[root@centos-5-vm cli]# text2pcap garp_ascii_hex garp_pkt.pcap
Input from: garp_ascii_hex
Output to: garp_pkt.pcap
Wrote packet of 60 bytes at 0
Read 1 potential packet, wrote 1 packet
[root@centos-5-vm cli]#


Note: The "text2pcap" utility will process the input file only when its content are in particular format. The man page says,
      "Text2pcap understands a hexdump of the form where each byte is individually displayed and surrounded with a space. Each line begins with an offset describing the position in the file. The offset is a hex number of more than two hex digits."

     Now, we want to send the packet "garp_pkt.pcap" out of "eth0" interface. We use the packETHcli utility to achieve the same.

    packETHcli -i eth0 -m 1 -f  garp_pkt.pcap

   This will send out the packet "garp_pkt.pcap" from eth0 interface.

    


Sunday, October 14, 2018

How to fix "BAD SIZEOF" type coverity warnings in C code

Bad sizeof - Coverity Warning:
   The "sizeof" is an unary operator in C which is used to compute the size of its operand. The "BAD_SIZEOF" is a type of coverity warning which will be reported when there is a possibility of logical error in the usage of the "sizeof" operator. Consider the program given below.

#include <stdio.h>
#include <string.h>
int main()
{
    char src_string[10]="C_Program", out_string1[10] = {0}, out_string2[10] = {0};
    char *ptr = NULL;

    ptr = src_string;

    printf ("src_string=%s ;; *ptr=%s\n", src_string, ptr);

    memcpy(out_string1, src_string, sizeof(src_string));
    memcpy(out_string2, src_string, sizeof(ptr));     /* <<<<< bad_sizeof warning will be reported by coverity at this line >>>>>*/

    printf ("Out_String1=%s ;; Out_String2=%s\n",out_string1, out_string2);

    printf ("sizeof(src_string)=%u ;; sizeof(ptr)=%u\n",sizeof(src_string), sizeof(ptr));
    return 0;
}

    In this program, we try to copy the string "C_Program" into two different output variables using the "memcpy" function. We assign the base address of the character array "src_string" to a character pointer "ptr". We can print the string "C_Program" by using either "src_string" or "ptr". But when we try to calculate the size of these variables, this will result in different values.  Because of this reason, when we try to copy this string to output variables using "memcpy", the results are different.
    When we execute the program we get the below output.

Output:

src_string=C_Program ;; *ptr=C_Program    <<<< Both src_string && ptr prints the string properly
Out_String1=C_Program ;; Out_String2=C_Pr     <<< The values copied into out_string1 and out_string2 are different.
sizeof(src_string)=10 ;; sizeof(ptr)=4

     From the above output, we can understand that the string "C_Program" is being printed properly using "src_string" and "ptr". While copying to output variables, the value is properly copied into the variable "out_string1". Whereas for the variable "out_string2", only partial string was copied.
    In the first "memcpy" statement, we used the "sizeof(src_string)". This will calculate the size of the argument "src_string" which is an array. In this case it happens to be 10. So, all the characters are properly copied into the variable "out_string1".
    In the second "memcpy" statement, we used "sizeof(ptr)". The argument "ptr" is a pointer variable whose size is 4 bytes. So, only 4 bytes are being copied into "out_string2". The coverity tool will report this second sizeof statement as "bad_sizeof". We wanted to copy the entire string pointed by "ptr" into the variable "out_string2". But due to incorrect use of sizeof operator, the result went wrong.

How to Solve:
    We can re-write the second "memcpy" statement as given below which will resolve the error.

    memcpy (out_string2, src_string, strlen(ptr));

    Otherwise, we can use the first memcpy statement alone to copy the string.


    This is one example which illustrated the incorrect usage of "sizeof" operator.Whenever coverity reports "bad_sizeof" warning, verify that the argument passed to the "sizeof" operator is proper and correct the statement in appropriate way.