Fri 30 Jan 2009
Interesting issue with arguments for MDSYS.SDO_JOIN
Posted by Slavik under DBA, Fuzzor, Oracle
[2] Comments
I was playing a bit with FuzzOr and trying out different Oracle built-in schemas on 11g when I stumbled across something interesting in the parameters for MDSYS.SDO_JOIN. This caused FuzzOr to fail in fuzzing the function so I took a closer look.
SYS> select argument_name, type_owner, type_name, position, sequence from all_arguments where object_name = ‘SDO_JOIN’;
ARGUMENT_NAME TYPE_OWNER TYPE_NAME POSITION SEQUENCE --------------------- -------------- ----------------- -------- -------- TABLE2_PARTITION 8 10 TABLE1_PARTITION 7 9 PRESERVE_JOIN_ORDER 6 8 PARAMS 5 7 COLUMN_NAME2 4 6 TABLE_NAME2 3 5 COLUMN_NAME1 2 4 TABLE_NAME1 1 3 MDSYS SDO_ROWIDPAIR 1 2 MDSYS SDO_ROWIDSET 0 1 10 rows selected.
So, do you notice anything weird here? SDO_ROWIDPAIR is listed as a parameter in the same position as TABLE_NAME1 but has no parameter name. Interesting. Initially, I thought that there might be something wrong with the view all_arguments but querying directly the argument$ table produced the same results.
Describing the function did not mention SDO_ROWIDPAIR at all:
SYS> desc MDSYS.SDO_JOIN FUNCTION MDSYS.SDO_JOIN RETURNS SDO_ROWIDSET Argument Name Type In/Out Default? ------------------------------ -------------- ------- -------- TABLE_NAME1 VARCHAR2 IN COLUMN_NAME1 VARCHAR2 IN TABLE_NAME2 VARCHAR2 IN COLUMN_NAME2 VARCHAR2 IN PARAMS VARCHAR2 IN DEFAULT PRESERVE_JOIN_ORDER NUMBER IN DEFAULT TABLE1_PARTITION VARCHAR2 IN DEFAULT TABLE2_PARTITION VARCHAR2 IN DEFAULT
The source code is wrapped but the header is:
FUNCTION SDO_Join (TABLE_NAME1 VARCHAR2, COLUMN_NAME1 VARCHAR2,
TABLE_NAME2 VARCHAR2, COLUMN_NAME2 VARCHAR2,
PARAMS VARCHAR2 DEFAULT NULL,
PRESERVE_JOIN_ORDER NUMBER DEFAULT 0,
TABLE1_PARTITION VARCHAR2 DEFAULT NULL,
TABLE2_PARTITION VARCHAR2 DEFAULT NULL)
RETURN MDSYS.SDO_ROWIDSET
AUTHID CURRENT_USER
PIPELINED IS
As you see, no mention of SDO_ROWIDPAIR which is in-fact mentioned later in the function as a declared local variable TAB_REC.
Anyway, this function is declared as AUTHID CURRENT_USER so even if can be injected (which I suspect that it can) it will not benefit the attacker.
Still, it’s an interesting case where the arguments table does not reflect the actual code and I suspect that there is a bug in populating this table.
Have you encountered similar cases?
desc MDSYS.SDO_JOIN
gives
“FUNCTION MDSYS.SDO_JOIN RETURNS SDO_ROWIDSET”
desc SDO_ROWIDSET
gives
“SDO_ROWIDSET TABLE OF MDSYS.SDO_ROWIDPAIR
Name Null? Type
———— ——– —————————-
ROWID1 VARCHAR2(24)
ROWID2 VARCHAR2(24)
If you check the DATA_LEVEL column in all_arguments, there’s a ’1′ flag for SDO_ROWIDPAIR and zero for all the others. So I think the view works. You may just want to excluded non zero data_level entries.
@Gary
I think you’re right. The view is indeed correct and I completely forgot about the data_level column. Still, it’s weird that the position is shared with table_name1 instead of the return value.
Well, it’s time for another FuzzOr fix…