c++ada

Constraints not checked when calling ADA code from C++ Code


I am working through a light example of calling Ada code from C++ code. I was able to induce a buffer overflow and read data past a buffer using the following code:

main.cpp

extern "C" {
  void proc_buffer (int data[]);
  void adainit ();
  void adafinal ();
}

int main() {
  adainit();
  int data[] = {1, 7, 3, 4, 5};
  proc_buffer(data);
  adafinal();
  return 0;
}

proc_buffer.adb

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
package body Proc_Buffer is
  procedure ProcBuffer (Buff : in Custom_Buff) is
  begin
    Put_Line("Integer Requested is: "); Put(Buff(Buff(1)), 0);
  end ProcBuffer;
begin
  null;
end Proc_Buffer

proc_buffer.ads

package Proc_Buffer is
  type Custom_Buff is array (0..9) of Integer;
  procedure ProcBuffer (Buff : in Custom_Buff);
  pragma Export (C, ProcBuffer, "proc_buffer");
end Proc_Buffer;

To Build and Link I do the following:

gnatmake -c proc_buffer
g++ -c main.cpp
gnatbind -n proc_buffer
gnatlink proc_buffer -o main --LINK=g++ -lstdc++ main.o

I wanted to see how data was handled when passing C++ data to Ada, attempting to induce a buffer overflow by printing the value of the array at the index of integer stored at the first index. In the example in main.cpp we would attempt to print the value of the array at index 7 (which does not exist since the array has a length of 5).

This does not induce a CONSTRAINT_ERROR from Ada, rather it prints past the buffer, displaying whatever is there in memory.

Why does this not induce a CONSTRAINT_ERROR? If i do the same thing from Ada I get a compile time warning saying this will cause a constraint error since the array is not of the correct size. It is still legal as it fits in the bounds of the array but correctly throws a CONSTRAINT_ERROR when accessing an index the array does not have. However, when called from C++ it does not throw the error. My initial thought was Ada would check this and successfully send the error, but appears to simply pass along and read past the buffer.

When I change the 1st index to 14 instead of 7, I do get a CONSTRAINT_ERROR thrown successfully as we no longer meet the requirements of the array.

I tried running this from Ada code as well as C++ code, I expect a CONSTRAINT_ERROR to be thrown from Ada, even when called from/with data from C++.


Solution

  • The C++ compiler does not write run-time checks on array indexing. Once the array is passed to the C++ compiler it is accessed using C++ rules. You can expect buffer overflow checking if you pass an Ada subprogram handling the array to the C++ compiler. The Ada compiler will generate the subprogram with the expected run-time checks.