MariaDB Server Plugins: disabled functions

During the last MariaDB Foundation Board Meeting (24 June 2026), Barry shared how it can be difficult to deploy an upgrade immediately and that they sometimes have to wait for one that fixes security bugs. Wait for the validation, wait for the fix, and the release. Even if the MariaDB engineers are doing incredible work, it might still not be fast enough for the security team.

That’s where Barry requested MariaDB implement a query-rewriter plugin, like the one in MySQL, to address the fact that, in a multi-tenant environment, certain queries that would trigger known vulnerabilities are never legitimately used by applications.

So I wrote something similar, but unfortunately, this didn’t solve the problem. Queries are way too different. For example, these two queries will provide two different digests or normalized forms:

select now() as nu;

select now() as maintenant;

So this solution was discarded, and we discussed maybe using a regular expression, but that might become too heavy; it would be better to use a proxy like MaxScale with the rewrite or regexp filter.

And then the real problem arose: most of their issues stemmed from built-in functions they never use in their application, but that could become dangerous. So they asked if it was possible to “just” disable some built-in functions

The Solution

Of course, there is nothing currently implemented in MariaDB Server that allows the DBA to disable built-in functions.

But our Chief Architect, Sergei Golubchik, had an idea: a dynamic plugin loaded at startup could disable a function and return an error. We could monkey-patch a C++ virtual method at runtime by directly modifying a class’s vtable.

Monkey-patching means changing the behavior of existing code at runtime, rather than by editing and recompiling the original source. It’s primarily used in dynamic languages like Python and JavaScript to add, replace, or suppress functionality in memory.

That rang a bell and opened a new perspective to reach the desired objective.

The key idea

MariaDB has internal registries of built-in SQL functions, represented as arrays:

extern Native_func_registry_array native_func_registry_array;
extern Native_func_registry_array native_func_registry_array_geom;
extern Native_func_registry_array oracle_func_registry_array;

Each entry looks like this:

struct Native_func_registry
{
  LEX_CSTRING name;
  Create_func *builder;
};

Meaning that each function has a name and a builder (an object used to create the function expression).

Finally, MariaDB also has hash tables used to look up functions quickly:

extern Native_functions_hash native_functions_hash;
extern Native_functions_hash native_functions_hash_oracle;

So when a SQL statement contains something like:

SELECT SLEEP(10);

MariaDB parses SLEEP, searches the function registry/hash, finds its Create_func *builder, and uses that to construct the function call.

This plugin simply removes selected entries from those hashes.

After removal, the function still exists in the compiled MariaDB code, but the SQL layer can no longer resolve its name via the normal native-function lookup path.

mariadb-plugin-disabled-functions

Creating a plugin for MariaDB Server isn’t complicated (see this page), so I tried to write a plugin that, when loaded at startup, would disable functions referenced by a global read-only variable using the key idea above.

The plugin is available on my GitHub repository.

When compiled and installed, you can load the module directly from the my.cnf:

[mariadb]
plugin_load_add=disabled_functions
disabled_functions=SLEEP,COLUMN_LIST

This will load the plugin and disable the commands SLEEP() and COLUMN_LIST():

MariaDB [test]> SELECT * FROM information_schema.PLUGINS  
                WHERE plugin_name = 'disabled_functions'\G
*************************** 1. row ***************************
           PLUGIN_NAME: disabled_functions
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: DAEMON
   PLUGIN_TYPE_VERSION: 130100.0
        PLUGIN_LIBRARY: disabled_functions.so
PLUGIN_LIBRARY_VERSION: 1.15
         PLUGIN_AUTHOR: lefred
    PLUGIN_DESCRIPTION: Disables selected native built-in SQL functions
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: ON
       PLUGIN_MATURITY: Experimental
   PLUGIN_AUTH_VERSION: 1.0
1 row in set (0.002 sec)

MariaDB [test]> SHOW GLOBAL VARIABLES LIKE 'disabled_functions_list';
+-------------------------+-------------------+
| Variable_name           | Value             |
+-------------------------+-------------------+
| disabled_functions_list | SLEEP,COLUMN_LIST |
+-------------------------+-------------------+
1 row in set (0.000 sec)

Now let’s try to use one of these functions:

MariaDB [test]> select sleep();
ERROR 1305 (42000): FUNCTION test.sleep does not exist
MariaDB [test]> select sleep(10);
ERROR 1305 (42000): FUNCTION test.sleep does not exist
MariaDB [test]> select sleep('fred');
ERROR 1305 (42000): FUNCTION test.sleep does not exist
MariaDB [test]> 

The plugin works exactly as expected.

Conclusion

This is not a wow-feature plugin, but it illustrates how flexible MariaDB is and how quickly it’s possible to extend it with a feature that could be used in production.

Please give it a try, and if you code some plugins, please share them with me. I will be happy to test them.

As usual, enjoy MariaDB Server and enjoy hacking!

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Leave a Reply

Your email address will not be published. Required fields are marked *