How to discover what is available in lua environment? - lua

Many games these days make available some lua scripting, but this is universally undocumented.
So let's say I can get a game to run my lua script (it's lua 5.1) - and the script can write what it finds to text files on disk. How much can I discover about environment the script is executing in?
For example it seems I can list keys in tables, and find out what's a function and what's some other type of object, but there's no obvious way to guess how many arguments function takes (and a mistake usually results in crash to desktop).
Most languages provide some reflection functionality that could be used here - how much is possible in embedded lua environment?

"debug" standard library has some functions, which you may find useful:
debug.getfenv - Returns the environment of object.
debug.getinfo - Returns a table with information about a function.
... and more
Lua Reference Manual also states:
several of these functions violate some assumptions about Lua code (e.g., that variables local to a function cannot be accessed from outside or that userdata metatables cannot be changed by Lua code) and therefore can compromise otherwise secure code.
So with debug library, you may access more.

Unfortunately, there is not much you can learn about functions in Lua - they by design accept any number of parameters. Without the ability to look at the sources, your only resort is the documentation and/or other samples.
The most you can do in this case is traverse the entire _G table recursively and dump every table/function, printing the results to a file.
"A mistake usually results in crash to desktop" is a sign of a really bad design - good API should tell you, that it expects A, and you passed B. For example in Lqt, a Qt binding to Lua, we check every parameter against the original Qt API, so that the programmer is notified of mistakes:
> QApplication.setFont(1, 2)
QApplication::setFont(number, number): incorrect or extra arguments, expecting: QFont*,string,.

Related

Is there a sandboxable compiled programming language simililar to lua

I'm working on a crowd simulator. The idea is people walking around a city in 2D. Think gray rectangles for the buildings and colored dots for the people. Now I want these people to be programmable by other people, without giving them access to the core back end.
I also don't want them to be able to use anything other than the methods I provide for them. Meaning no file access, internet access, RNG, nothing.
They will receive get events like "You have just been instructed to go to X" or "You have arrived at P" and such.
The script should then allow them to do things like move_forward or how_many_people_are_in_front_of me and such.
Now I have found out that Lua and python are both thousands of times slower than compiled languages (I figured it would be in order of magnitude of 10s times slower), which is way to slow for my simulation.
So heres my question: Is there a programming language that is FOSS, allows me to restrict system access (sandboxing) the entire language to limit the amount of information the script has by only allowing it to use my provided functions, that is reasonably fast, something like <10x slower than Java, where I can send events to objects inside that language with which I can load in new Classes/Objects on the fly.
Don't you think that if there was a scripting language faster than lua and python, then it'd be talked about at least as much as they are?
The speed of a scripting language is rather vague term. Scripting languages essentially are converted to a series of calls to functions written in fast compiled languages. But the functions are usually written to be general with lots of checks and fail-safes, rather than to be fast. For some problems, not a lot of redundant actions stacks up and the script translation results in essentially same machine code as the compiled program would have. For other problems, a person, knowledgeable about the language, might coerce it to translate to essentially same machine code. For other problems the price of convenience stay forever with the script.
If you look at the timings of benchmark tasks, you'll find that there's no consistent winner across them. For one task the language is fastest, for the other it is way behind.
It would make sense to gauge language speed at your task by looking at similar tasks in benchmarks. So, which of those problem maps the closest to yours? My guess would be: none.
Now, onto the question of user programs inside your program.
That's how script languages came to existence in the first place. You can read up on why such a language may be slow for example in SICP.
If you evaluate what you expect people to write in their programs, you might decide, that you don't need to give them whole programming language. Then you may give them a simple set of instructions they can use to describe a few branching decisions and value lookups. Then your own very performant program will construct an object that encompasses the described logic. This tric is described here and there.
However if you keep adding more and more complex commands for users to invoke, you'll just end up inventing your own language. At that point you'll likely wish you'd went with Lua from the very beginning.
That being said, I don't think the snippet below will run significantly different in compiled code, your own interpreter object, or any embedded scripting language:
if event = "You have just been instructed to go to X":
set_front_of_me(X) # call your function
n = how_many_people_are_in_front_of_me() #call to your function
if n > 3:
move_to_side() #call to function provided by you
else:
move_forward() #call to function provided by you
Now, if the users would need to do complex computer-sciency stuff, solve np-problems, do machine learning or other matrix multiplications, then yes, that would be slow, provided someone would actually trouble themselves with implementing that.
If you get to that point, it seem that there are at least some possibilities to sandbox the compiled dlls (at least in some languages). Or you could do compilation of users' code yourself to control the functionality they invoke and then plug it in as a library.

Getting the Erlang shell to forget a BIF

Is there any way I can get Erlang to forget a built in function so I can use that name?
eg. forget retrieve
There's a bit of confusion here.
retrieve is not a built-in function, you may be thinking of receive
receive is not a built-in function, but a special token in the language, much like if, case, end, and so on. These cannot be modified.
BIFs are mostly implemented in the erlang module, and you cannot redefine this one
Many of the BIFs in erlang are auto-imported in modules and such. Any module-local definition will take over these, and otherwise they're syntactic shortcuts for erlang:MyBif(...).
The shell replicates these auto-imports, but also provides additional functions. They are technically not BIFs. See Shell Commands
You can override the auto-imports for the shell by configuring your own user_default module. These will only work in the shell.
To avoid auto-imports in modules, use the -compile({no_auto_import,[Name/N]}). module attribute, so that Name(...) always uses the local function.

how to make lua config file to be safe

I am new to Lua and want to ask whether it is possible to restrict lua syntax in config file? I know that config loading have to be performed in jail, but how we can cope with while 1 do end in config file we want to load? Is there a way to allow only strings, assignments and tables in config and if not, then what is the best way to check that lua file doesn't contain undesirable constructs? Is manual pre-parsing the only solution?
You seem to already know about "sandboxing" in Lua. So what's left is as you say malicious constructs like infinite loops. And to solve that you need to solve the Halting Problem. Which is not practical.
Instead of "manually" parsing and hoping you find all the malicious content (you won't), how about just running your Lua interpreter with a timer set so that the script will be interrupted if it takes longer than N seconds?
If you want to explicitly forbid certain constructs in Lua, you have to actually scan the file yourself. Note that there are valid uses for those constructs, even in config files, so you are restricting what the user can do.
It wouldn't be too hard to write a simple Lua lexer that ignores the contents of strings and comments, but errors on any of the Lua keywords other than return. Given proper sandboxing (ie: no functions are available to be called), that should be sufficient to weed out anything malicious.
Also, note that Lua 5.1 doesn't make it easy to keep the parser from parsing non-text data (ie: compiled Lua bytecode). 5.2 offers specific API support for forcing the loader to only recognize text and therefore reject bytecode.

Is there a set of complete documentation for mysql-proxy lua scripting?

I am playing with scripting for mysql-proxy. What I am trying to accomplish is irrelevant. What I am finding, however, is that there appears to be elements of the lua interface that are undocumented. The big "smoking gun" I have is the disconnect_client() hook. I cannot find it documented anywhere in the official documentation, though it's used in an example on the explanation of the admin interface. It's also used extensively in the example docs. A quick grep shows its use in the following scripts included in the 5.5.8 distribution:
active-queries.lua
active-transactions.lua
load-multi.lua
ro-pooling.lua
rw-splitting.lua
tutorial-keepalive.lua
My other example that has caught my eye is the list of attributes for entries in the proxy.global.backends table. The documentation lists the following attributes:
dst.name
dst.address
dst.port
connected_clients
state
type
However, several of the example scripts reference a fairly complex element called pool. Take for instance tutorial-keepalive.lua:
local s = proxy.global.backends[i]
local pool = s.pool
local cur_idle = pool.users[proxy.connection.client.username].cur_idle_connections
At first I thought it was being added somewhere else in the lua, but I've looked and I can't find any code assigning into proxy.global.backends[i].pool.
So, two questions I suppose:
Am I nuts? Please feel free to demonstrate how I've overlooked the obvious and the documentation is really quite clear.
Assuming I am correct, is there anywhere to find the complete documentation? A nice link would be great (though I couldn't google one up), but even "take a look at this .c file from the mysql-proxy distro that defines the interface". At least that would give me something to poke at.
Thanks
Just opened Proxy/Lua myself. I'm afraid, as with all things Mysql, once you dip under the covers you are on your own. The same goes for LUA.
You will need other addons to LUA to do what you want to do, I would like to suggest:
http://peterodding.com/code/lua/apr/docs/#shared_memory
for the Apache Protable library binding... saved me a shedload of time.
As for the internals of MySql, you will probably need to look in teh C source files, sadly, as we are in unexplored territory here.
One thing I have found is that the LUA structures in Mysql are not Lua tables, but Lua 'user data'. This means that they are effectively shared memory, so are not changeable by Lua, as Mysql uses them too. I am going to try the luaposix library to see if I can get inbto them, as there are elements I would like to change, if possible.
Good luck
peter.colclough#toolstation.com

Cloning Lua state

Folks, is there a way to clone a Lua state?
In my game application the initialization procedure of the Lua virtual machine is pretty heavy(about 1 sec, since many scripts are loaded at once). I have a separate Lua VM for each autonomous agent and once the agent is created its Lua initialization affects FPS pretty badly.
I'm thinking about the following schema: what about keeping "preforked" Lua state which is then simply cloned for each agent? Is it possible?
You want to consider using Lua's coroutines for each autonomous agent, instead of a completely separate VM. Coroutines are a more lightweight solution, but may or may not be suitable for your application.
If you can't change the architecture, you might try LuaJIT. It might make the initialization fast enough for your purposes.
More options:
Rings: "Rings is a library which provides a way to create new Lua states from within Lua. It also offers a simple way to communicate between the creator (master) and the created (slave) states."
Pluto: "Pluto is a library which allows users to write arbitrarily large portions of the "Lua universe" into a flat file, and later read them back into the same or a different Lua universe."
There's also Lanes (download, docs) and within the comparison to all similar products I know.
About Rings the comparison sheet says:
Rings offers separate Lua states, but
no multithreading. This makes it
simple, but it won't use more than one
CPU core.
Note: The comparison sheet says Lanes would only marshal 'non-cyclic tables'. It does do cycles, and does marshall functions, upvalues etc. And it does the copies between Lua states as direct copies, not needing to stringify the contents in the middle. This makes it fast.
If you're on Linux, you may try lper, LPSM-based experimental library by one of Lua authors.
Notice, works with Lua 5.2 and above
You can just restrict access to this VM. Create one instance with all functions required, that will not depend on _G (global Lua state) and then create separate table for each client. That they will use as their global namespace. Setting a table as current _G is possible via _ENV. That's quite difficult topic to explain in one post. In short you prepare "virtual" _G for your new client and then just replace _G for the client's code. There is where I advice you to start.
Here's the point.
local _ENV = t -- change the environment. without the local, this would change the environment for the entire chunk
Just remove local and you'll change _ENV for all further code. Good luck with experiments!
P. S. don't forget that you may set metatable for _ENV and _G tables and forbid changing that metatable. Lua is really flexible here.

Resources