It seems today is not my day.

I was playing to put more security on system tables, but I ran on a series
of bugs. At this time I'm not really sure if it's just me, so I need others
to comment.

SQL> insert into rdb$database values(null,null,null,null,null);
Statement failed, SQLSTATE = 28000
no permission for (ACL unrecognized) access to security_class SQL$353

You won't get the message above because I put code in my private tree to
block insertions into rdb$database and keep it same as Oracle's dual: with a
single record. However, the "(ACL_unrecognized)" caught my attention. We
forbade in FB2.5 deletions from rdb$pages, because it's fatal. (BTW, I need
to forbid insertions by anyone other than "internal request", because it's
suicide, too.)

I found that using ^Z in isql after that error msg (to terminate the
session) hung it forever, but only if I was debugging. Running the same
DEBUG isql from the command line, I can quit immeditaly. Got an idea and
asked Vlad, but maybe nobody will be able to reproduce it.

SQL> delete from rdb$pages;
Statement failed, SQLSTATE = 28000
no permission for (ACL unrecognized) access to security_class SQL$355

Ok, as I said, this restriction already exists, but the message is not good.
Unlike Ann, I'm not a debugging wizard, but because I couldn't make sense of
it by reading the sources, I had to call VS and found that an ACL is corrupt
when walk_acl() thinks so and in turn this happens because that function
walks uninitialized memory beyond the end of the ACL. The code used in
INI_format() needs a second ACL_end and if you debug walk_acl() you will see
it reading trash and marking the ACL as corrupt. I'm going to put that extra
terminator.


Before fixing that error, apparently there was a memory corruption in the
engine, because if I tried
SHOW TABLE RDB$DATABASE;
just after getting (ACL unrecognized), isql crashed. Looking at the code in
ISQL_get_default_char_set_id(), I'm mystified:

{ <-----
if (!DB)
   DB = fbProvider->attachDatabase(fbStatus,
"F:/fb3dev/fbbuild/firebird30/gen/dbs/yachts.lnk", 0, NULL);
if (DB && !fbTrans)
   fbTrans = DB->startTransaction(fbStatus, 0, NULL);
} <------
        if (!fb_142)
           fb_142 = DB->compileRequest(fbStatus, sizeof(fb_143), fb_143);
        fb_142->start(fbStatus, fbTrans, 0);

- I don't understand the purpose of the braces shown by the arrows.
- Why is gpre generating code to attach to yachts, that's the DB used in the
build process? Shouldn't it use the dynamic DB, in this case, the db where
I'm testing the system relation protection?
- fbProvider->attachDatabase() can produce a NULL result. The status is not
checked. Worse, if DB is NULL, then
DB->compileRequest() will crash dereferencing a NULL pointer (and this is
what I'm seeing).
- If DB->compileRequest() fails due to a corrupt ACL, for example, fb_142
will be NULL. Again, the status is not checked and fb_142->start() will
crash dereferencing a NULL pointer.

I checked the sequence
DB->prepare()
YStatement* YAttachment::prepare()
jrd.cpp's JStatement* JAttachment::prepare()

and it can return NULL. The same with the sequence
DB->compileRequest()
YAttachment::compileRequest()
jrd.cpp's JAttachment::compileRequest()

hence GPRE should produce better code, check the status and NULL pointers.
All those experiments where done starting isql only and thus the engine was
loaded as embedded.

C.
---
Claudio Valderrama C.
Consultant, SW developer.


------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to