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