[MDEV-13285] Error 1210 description needs expanded Created: 2017-07-10  Updated: 2017-08-03  Resolved: 2017-08-03

Status: Closed
Project: MariaDB Server
Component/s: Documentation
Affects Version/s: 10.1.22
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: M MacDonald Assignee: Ian Gilfillan
Resolution: Fixed Votes: 0
Labels: data_directory, docs
Environment:

FreeBSD 10.3.R 2017Q2



 Description   

The current documentation implies by omission that

CREATE TABLE tname ( cols descr ) DATA DIRECTORY='absolute path'

is sufficiently specific. My tables on my dev machine are in /Local/tables. I want to add an ssd so that table creation and population takes less than geologic time (they're of multi-GB size, and my discs are mechanical). So naturally I created the mount point /Local/tables/SSD, and fixed up permits (0700) and ownership (mysql:mysql).

But attempting to

CREATE TABLE foo2 (bar INT) DATA DIRECTORY='/Local/tables/SSD' ENGINE=ARIA

failed with a 1210 (HY000) Incorrect arguments to DATA DIRECTORY.

It made no sense. After some search and experiment I discovered that one cannot have the alternative subtree as a child of the datadir subtree. Putting it at root level (/SSD) works, and even /Local/SSD is okay. But /Local/tables/SSD does not work and the error message is not helpful.

This is not documented very well at all, but should be, both in CREATE TABLE and in ERROR 1210. because it's a counter-intuitive limitation and is very productive of baffling errors.

I'd make the edits myself, but can't discover how to get at the docs in edit mode.



 Comments   
Comment by Sergei Golubchik [ 2017-07-10 ]

This is mainly for security reasons. If one has no privileges on the table t1, he shouldn't be able to access it. That's why the server also prohibits DATA DIRECTORY into a datadir, as it might allow one to create a table (say t2, with full privileges on it) symlinked to t1.

Comment by M MacDonald [ 2017-07-10 ]

You've lost me, Sergei. Perhaps I'm just too exhausted to understand what you're saying, but your comment seems like a non-sequitur. Surely the software looks at the individual's privs before it executes the CREATE and in my case sees that I'm root and have all the privs in the world.

Comment by Sergei Golubchik [ 2017-07-11 ]

Sorry. I agree that it needs to be documented. I just wanted to clarify why it's done this way so that it could be documented better.

Say, there is a database secret_db and you have no privileges on secret_db, so you cannot select from tables in it, for example. Note that DATA DIRECTORY works by creating symlinks from where the table would've normally been (in the datadir) to where you actually want it to reside (this DATA DIRECTORY). Now, you can create the table public_db.some_table — in a database you have all privileges on — and specify DATA DIRECTORY equal to datadir/secret_db. You have full rights on the table in public_db, but it's just a symlink into secret_db. So when you select from it, the server will use privileges for public_db, but show you the data from secret_db.some_table. You've bypassed privilege system!

To prevent this the server does not allow symlinks into datadir. You cannot even create a table with DATA DIRECTORY in /tmp and later replace table files in /tmp with symlinks into datadir, this won't work either. The server resolves symlinks every time it opens a table and refuses to follow them into a datadir.

Comment by M MacDonald [ 2017-07-11 ]

arrgh...I'm still not following. Let's say I create the new secret_db in /Local/tables/ and priv the db to root only. Then I create some tables in it.

And finally I create an account "scoundrel" to which I give create-table privs. My scoundrel persona knows about the tables in secret_db, the one of interest being 'foo'.

Okay, so, logged in as "scoundrel", I mkdir /home/scoundrel/backdoor/, and then open the mariadb command line and issue CREATE TABLE foo (...) DATA DIRECTORY= '/Local/tables/secret_db'. That obviously should fail instantly because I (as scoundrel) don't have privs in secret_db.

So I issue CREATE TABLE foo (...) DATA DIRECTORY='/home/scoundrel/backdoor'. The DD clause tries to create a symlink...but (a) why would it think it should create it in /Local/tables/secret_db rather than, say, /Local/tables/test, and (b) even if secret_db were the only db defined why wouldn't the create still fail since foo already still exists in secret_db?

Comment by Sergei Golubchik [ 2017-07-11 ]

If you do CREATE TABLE foo (...) DATA DIRECTORY='/home/scoundrel/backdoor', it will succeed (assuming the table foo is not in secret_db, of course). And you can use this table normally, it'll work just fine. Later you can manually delete files that were created in /home/scoundrel/backdoor/ and replace them with symlinks into /Local/tables/secret_db/. After that, the server will refuse to open your foo table, because it resolves all symlinks on open and rejects symlinks that point into datadir.

Comment by Ian Gilfillan [ 2017-08-03 ]

This has been documented:
https://mariadb.com/kb/en/mariadb/create-table/

Generated at Thu Feb 08 08:04:23 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.