Call: +44 (0)1904 557620 Call
Blog

Pete Finnigan's Oracle Security Weblog

This is the weblog for Pete Finnigan. Pete works in the area of Oracle security and he specialises in auditing Oracle databases for security issues. This weblog is aimed squarely at those interested in the security of their Oracle databases.

Can we Add C Style Pointers to PL/SQL?

In my last blog on Extreme PL/SQL I mentioned pointers in PL/SQL.

PL/SQL does not support pointers or dynamic memory management in the same way that we can write in C code.

In C code we can define a variable as a pointer, allocate some memory and then store a value at the location allocated and pointed to by the pointer. We can then do memory arithmetic or store a different value or free the memory after use so that it can be used elsewhere. Parts of a C program illustrating this are here:

...
int *p; /* define a pointer */
p=(int*)malloc(sizeof(int)*1); /* allocate one integer and assign to the pointer */
*p=7; /* assign a value of 7 stored in the memory located allocated */
...

C has syntax to define a variable as a pointer and access the "contents" of that variable or access the address stored in the variable.

I want to do a similar thing with PL/SQL in my CPU virtual machine implementation so that I can store the programs and use the memory in a similar way to a CPU; to do that in PL/SQL I wanted to access that memory using pointers. I want to show you an earlier version of this idea here to show that we can add and use pointers in PL/SQL.

If we consider what C is doing we can see that the same is easily possible in PL/SQL. In C we allocated blocks of memory from the HEAP or the STACK and we use pointers to perform address arithmetic and then use these pointers to store data at the locations "pointed to" by the pointer.

So here is a sample program that uses a HEAP and pointers to access and manage that memory:

declare
-- -------------------------------------------------------------
-- types
-- -------------------------------------------------------------
type heap_t is table of integer index by binary_integer;
subtype "* number" is integer;
-- -------------------------------------------------------------
-- variables
-- -------------------------------------------------------------
ptr "* number";
val integer;
"*" heap_t;
-- -------------------------------------------------------------
-- functions
-- -------------------------------------------------------------
function malloc(s in number) return "* number"
is
n binary_integer:=1;
begin
if("*".exists(n)) then
n:="*"(n);
while("*".exists(n)) loop
n:="*"(n);
end loop;
return(n+1);
else
"*"(n):=3;
return(n);
end if;
end;
--
function "^"(p in binary_integer) return integer
is
begin
return("*"(p));
end;
--
begin
-- ---------------------------------------------------------------
-- Malloc 1 integer on the heap, assign 7 to it, retrieve its
-- value from the heap
-- ---------------------------------------------------------------
ptr:=malloc(1);
"*"(ptr):=7;
val:="^"(ptr);
dbms_output.put_line('val=['||val||']');
-- ---------------------------------------------------------------
-- Malloc another 1 integer on the heap, assign 9 to it, retrieve
-- its value from the heap
-- ---------------------------------------------------------------
ptr:=malloc(1);
"*"(ptr):=9;
val:="^"(ptr);
dbms_output.put_line('val=['||val||']');
end;
/

We can see that I use syntax similar to C. First we create a HEAP (an area of memory) . We declare a new subtype to be "* integer" - a pointer to an integer. We create an instance of our HEAP and call it "*" so that we can access it in a similar syntax to C. Our Malloc function manages the HEAP. It keeps a simple linked list to point to the next free location of memory and allocate a pointer to that memory for the caller and pass it back. The "^" function allows us to use similar syntax to C to access the contents of the pointer. We can then use the pointers, HEAP and functions to write pointer based code as we would in C.

The simple demo in the begin/end block shows that we use our pointer "ptr" declared above as type "* integer", i.e. a pointer to an integer. We call malloc() to get one byte of storage and assign that one byte of storage address to "ptr". We can then store the digit "7" at the location pointed to by "ptr" in a similar way as we would in C. Finally we can retrieve the contents of the location pointed at by "ptr" and print it out. Then we repeat for a second location and store 9 at that location.

Of course we "deliberately" made a C programmers error and overwrote the "ptr" with a new location and lost the pointer to the first location.

We also need to implement free() to give back the memory to the HEAP after we finished using it.

The storage is not efficient for single integers as we need two integers for each integer used so that the memory management linked list works.

Is there a security issue if we introduce pointers and memory management to PL/SQL, Not in the same sense as a C program as any heap based overflow would not overflow beyond the PL/SQL implementation of the HEAP. If we implement a virtual CPU and store programs in the PL/SQL HEAP then yes those programs could overflow their own system but not escape back to overflow PL/SQL

The simple demo I have shown here has been improved already a lot by me for use in my compiler/CPU and I will take about it again in a later blog.

The C like syntax is of course not necessary; I used it here to illustrate that we can do C like programming and hence system level programming in PL/SQL. We can just use normal PL/SQL variables BUT it would be harder to see the beauty of pointers

#oracleace #sym_42 #oracle #security #database #plsql #c #securecode #bufferoverflow #interpreter #compiler #heap #virtualmachine #vm #cpu

Extreme PL/SQL

It has been a while since my last blog post here. I have not abandoned blogging. Over the last year and more I have blogged regularly and this is reflected in my Oracle ACE Pro contributions this last year. I have just been accepted as an ACE Pro for another year.

I have not released many blogs recently BUT I have been writing blogs in the background at the same rate as normal to release in the coming weeks as a series of articles around PL/SQL. I wrote back in 2022 about adding a scripting language to PL/SQL and now I have done this. I have created a simple language based on BASIC initially but it will change to be not BASIC as we go along. I have implemented an interpreter in PL/SQL for this simple version of BASIC and tested simple BASIC programs that work and are parsed and executed in PL/SQL. The next step is to complete the implementation of a VM in PL/SQL to simulate a simple CPU that will execute binaries for an assembly language I have designed. The interpreter will change into a compiler for the simple BASIC, it will output assembler for the machine I have created in the VM and assemble that to binary. Finally the binary is executed in the VM/CPU implemented in PL/SQL.

What do I mean with the title of this blog of Extreme PL/SQL?. Well, doing things with PL/SQL that you would not normally do and trying to write systems level code in PL/SQL. I have more things coming up but we will keep that quiet for now!!, ok, one for you now; PL/SQL does not have pointers in the same way that C does. You cannot create a pointer to a type such as char and then malloc memory for that char and access it using its location (pointer) and then retrieve the value. I have been looking at how we might do this in PL/SQL or simulate it more later.

Why? I have always been interested in PL/SQL and also from a security standpoint; there is always a security angle for me. I have some security ideas and things I want to talk about with PL/SQL and maybe with Apex. These ideas will become clearer soon. I might put forward some papers for conferences around this area of extreme PL/SQL and coding things that you would never do.

Watch out soon for the article series on "Extreme PL/SQL" and also compilers, interpreters, VMs, assemblers all in PL/SQL. I have 26 parts already, almost half of them complete and the others in a state of development with code to demonstrate.

Could we write an OS (Operating System) in PL/SQL? not Linux/Windows level of course but maybe at the level of a Monitor that were used to load and run programs in the old 8 bit days. I am focusing on the language layer as compilers, system programming, interpreters and more have interested me since the beginning of the 90s.

Here is a simple example of the interpreter loading and running a simple program with some trace output

-- -----------------------------------------------------------------------------
-- PFCL_int Interpreter - run examples code in a simple harness
-- -----------------------------------------------------------------------------

declare
lv_prog varchar2(32767):='PRINT var + 3+(7*66) END';
begin
-- initialise the interpreter
pfcl_int.init(true,1);
-- run the code
pfcl_int.run(lv_prog);
--
end;
/
sho err

And the output including trace:

TRACE: Trace Start [25-JUN-2024 08:55:25]
TRACE: [1] gv_source=[PRINT var + 3+(7*66) END]
TRACE: [1] gv_len=[24]
TRACE: [1] gv_posn=[0]
TRACE: [1] Token Type = [KEYWORD ] : Token is = [PRINT]
TRACE: [1] Token Type = [VARIABLE ] : Token is = [var]
TRACE: [1] Token Type = [DELIMETER] : Token is = [+]
TRACE: [1] Token Type = [NUMBER ] : Token is = [3]
TRACE: [1] Token Type = [DELIMETER] : Token is = [+]
TRACE: [1] Token Type = [DELIMETER] : Token is = [(]
TRACE: [1] Token Type = [NUMBER ] : Token is = [7]
TRACE: [1] Token Type = [DELIMETER] : Token is = [*]
TRACE: [1] Token Type = [NUMBER ] : Token is = [66]
TRACE: [1] Token Type = [DELIMETER] : Token is = [)]
TRACE: [1] Token Type = [KEYWORD ] : Token is = [END]
TRACE: [1] Symbol Table ==>
TRACE: [1] symbol name=[var],type=[NUMBER],value=[0]
TRACE: [1] Keyword table ==>
TRACE: [1] Keyword name=[REM],action=[]
TRACE: [1] Keyword name=[LET],action=[]
TRACE: [1] Keyword name=[PRINT],action=[]
TRACE: [1] Keyword name=[IF],action=[]
TRACE: [1] Keyword name=[THEN],action=[]
TRACE: [1] Keyword name=[GOTO],action=[]
TRACE: [1] Keyword name=[END],action=[]
465
TRACE: Trace End [25-JUN-2024 08:55:25]
===============================================================
No errors.
SQL>


Watch for the series detailing all of this work with PL/SQL

#oracleace #sym_42 #oracle #database #23c #23ai ##securecode #plsql #extreme #interpreter #compiler