Lua os.time does not do not work - lua

I have programed Lua script to a game with function os.clock() and os.time(). Its worked correctly, but after upgrade of this game I have observed fail message : attempt to call global 'os' (a nil value)... ? I thought that os.clock() and os.time() are native function of Lua.

From the Lua reference manual:
Except for the basic and the package libraries, each library provides
all its functions as fields of a global table or as methods of its
objects.
To have access to these libraries, the C host program should call the
luaL_openlibs function, which opens all standard libraries.
Alternatively, the host program can open them individually by using ... luaopen_os (for the operating system library)...
As you see adding the standard libraries in a host program is optional. Many applications restrict access to standard libraries. Especially os and io.
As the os librarie has not been added to the scripting environment of your game the global table os is nil.
So obviously the developers of your game decided that their users should survive without the os functions. Sometimes they just don't want you to do things, sometimes it just doesn't make sense. It is the simplest way to prevent you from interacting with the operatinig system from inside a game.
Usually they also prevent you from loading external code by removing the necessary functions.

Related

Running untrusted code in Lua via loadstring

I'm working with a modding api for a game, for those curious it's factorio but it's not really relevant, and the Lua environment is HEAVILY limited, blocking functions like setfenv, it's a 5.1 environment and I do have access to loadstring, pcall, etc. My question is how would you recommend running 'unsafe' code that is provided by a user and limiting what functions they can access without access to environment modification functions? (Preferably whitelist functions/values instead of blacklist, but I'll take whatever I can get)
In Lua 5.1 you need setfenv to create a secure sandbox (see this answer for a typical procedure). So if you don't have access to setfenv, then I don't think it can't be done.
Then again, if the environment you're working in has disabled setfenv and has put a wrapper around loadstring to avoid malicious bytecode loading (again, see the answer I linked) then you might be able to run the script without setting up a special environment for it. It really depends on the details of your current environment as to whether it's safe or not.
I apologize for a late answer (you've probably moved on by now) but it is possible to do this using the built in load function. You can supply a fourth argument to the function which is a custom environment and it returns a function. You can pass a function, a string, or possibly even a thread (I think) to load and get the result you want. I was also having this problem and I thought I'd answer it for future users.
Here is a link to the documentation on the lua site for load: https://www.lua.org/manual/5.2/manual.html#pdf-load
I have tested this to ensure it works properly in Factorio and it appears to work as intended.

Creating a secure Lua sandbox..?

Right now I am doing a lot of.
local env = {
print = print,
}
setfenv(func, env)
and then using metamethods to lock propertys on Instances, but it is really inefficient and has lots of bypasses. I googled it and everything I find is the same as this: unworking.
In Lua 5.1, sandboxing is pretty simple. If you have a Lua script in a file somewhere, and you want to prevent it from accessing any functions or anything other than the parameters you provide, you do this:
local script = --Load the script via whatever means. DO NOT RUN IT YET!
setfenv(script, {})
script is now sandboxed. It cannot access anything other than the values you directly provide. Functions it creates cannot access anything outside of this sandbox environment. Your original global environment is completely cut off from them, except for what you permit it to access.
Obviously you can put whatever you like in that table; that table will contain whatever globally accessible stuff you like. You should probably give Lua scripts access to basic Lua standard library functions; most of those are pure functions that can't do anything unpleasant.
Here's a list of Lua standard library stuff that you must not give the user access to, if you want to maintain the integrity your sandbox:
getfenv. There are valid reasons for a user to be able to setfenv, so that it can create mini-sandboxes of its own within your sandbox. But you cannot allow access to the environment of any functions you put in the sandbox if you want to maintain the integrity of the sandbox.
getmetatable: Same reasoning as above; setting metatables is OK. Though malicious code can break an object if they change its metatable, but malicious code can break your entire system just by doing an infinite loop.
The entire debug library. All manner of chicanery is possible through the debug library.
You also apparently need to solve this problem that Lua 5.1 has with loading bytecode from within a Lua script. That can be used to break the sandbox. Unfortunately, Lua 5.1 doesn't really have good tools for that. In Lua 5.2+, you can encapsulate load and loadfile, such that you internally pass "t" as the mode parameter no matter what the user provides. But with Lua 5.1, you need some way to encapsulate load et.al. such that you can tell when the data is text and when it's not. You could probably find the code that Lua uses to distinguish bytecode from text by reading the Lua source.
Or you can just disallow load and its friends altogether.
If you want to prevent the user from doing ugly things to the system, then disallow the os and io libraries.

Way to write code "in the debugger" in Lua?

I just played around a bit with Lua and tried the Koneki eclipse plugin, which is quite nice. Problem is that when I make changes in a function I'm debugging at the moment the changes do not become effective when saving the changes. So I'm forced to restart the application. Would be so nice if I could make changes in the debugger and they would become effective on the fly as for example with Smalltalk or to some extend as in hot code replacement in Java. Anybody has a clue whether this is possible?
It is possible to some degree with some limitations. I've been developing an IDE/debugger that provides this functionality. It gives you access to a remote console to execute commands in the context/environment of your running application. The IDE also supports live coding, which reloads modified code as you make changes to it; see demos here.
The main limitation is that you can't modify a currently running function (at least without changes to Lua VM). This means that the effect of your changes to the currently running function will only be seen after you exit and re-enter that function. It works well for environments that call the same function repeatedly (for example a game engine calling draw), but may not work in your case.
Another challenge is dealing with upvalues (values that are created outside of your function and are referenced inside it). There are methods to "read" current upvalues and re-create them when the (new) function is created, but it requires some code analysis to find what functions will be recreated to query them for upvalues, to get the current values, and then to create a new environment with those upvalue and assign proper values to them. My current implementation doesn't do this, which means you need to use global variables as a workaround.
There was also relevant discussion just the other day on the Lua mailing list.

Low-level Lua interpreter

Is there a way to run Lua code from a C/C++ program at a more fine-grained level than a standard "lua_pcall" function call? Ideally I'd like to be able to loop over a list of low-level bytecode instructions (assuming it has such things) and run them one by one, so that I could write my own scheduler which had more control of things than just running a complete Lua function from start to finish.
The reason I want to do this is because I wish to implement C functions which Lua code can call which would cause the program to wait until a certain (potentially long-winded) action had completed before continuing execution. There would be a high proportion of such function calls in a typical Lua script, so the idea of rewriting it to use callbacks once the action has completed isn't really practical.
Perhaps side-stepping the question, but you could use Lua coroutines rather than custom C stuff to wait until some event occurs.
For example, one coroutine could call a waitForEvent() function. In there, you can switch to another coro until that event occurs, then resume the first one. Take a look at the lua coro docs for more about that.
Jder's suggestion to use coroutines will work very well if you can write those long waiting C routines using Lua's cooperative threading (explicit yield) feature. You'll still use lua_pcall() to enter Lua, but the entry point will be your coroutine manager function.
This only works though if the C routines don't do anything while they wait. If they are long running because they calculate something for example, then you need to run multiple OS threads. Lua is threadsafe -- just create multiple threads and run lua_open() in each thread.
From http://www.lua.org/pil/24.1.html
The Lua library defines no global
variables at all. It keeps all its
state in the dynamic structure
lua_State and a pointer to this
structure is passed as an argument to
all functions inside Lua. This
implementation makes Lua reentrant and
ready to be used in multithreaded
code.
You can also combine the two approaches. If you have a wrapper Lua function to start an OS thread, you can yield after you start the thread. The coroutine manager will keep track of threads and continue a coroutine when the thread it started has finished. This lets you use a single Lua interpreter with multiple worker threads running pure C code.
If you go the OS threading way, please have a look at Lua Lanes. I would see it the perfect solution to what you're trying to achieve (= throw one addon module to the mix and you'll be making clear, understandable and simple code with multithreading seamlessly built in).
Please tell us how your issue got solved. :)
Does the debugging interface help?

Dynamically calling a NODLL cobol program from a DLL cobol program on z/OS

On the mainframe using Enterprise Cobol for z/OS, is it possible to dynamically CALL a Cobol Dyamic link library (DLL) program from a cobol program that has been compiled with NODLL?
There are a number of ways to do what you want.
If, by dynamically call, you mean call via a data definition variable, I don't think you can do this with the linker/binder since the binder needs to know the target functions at bind time.
You have to specifically dllload the DLL load module, dllqueryfn the function and call it that way.
To use the linker/binder, I believe the following steps are required (P1 is the NODLL COBOL program doing the calling, P2 is the DLL program being called):
P2 must be compiled and bound with the DLL option.
P1 must be compiled with NODYNAM and bound with DLL.
P1 must contain CALL 'dll-func' (i.e., literal calls only).
When binding P1, SYSLIB must first point to the P2 location.
This will cause the binder to incorporate both P1 and P2 into a single load module which is not exactly DLL calling but I don't think there's any way around that other than the dllload/dllqueryfn solution.
I've used the older-style dll-functions but, if you're at a high-enough level, there are also the newer dlopen/dlsym C helper functions.
This page provides support for my contention that NODLL/DLL programs can only call each other if bound into a single load module. You still have to use static calls however.
This page offers up another option, where you can put the DLL program into the same load module as the calling program and use static calls to get to it. It seems that the DLL program can call other DLL programs not in that load module. So it may be possible to provide a static gateway function in the DLL program that can dynamically call a DLL function not in the load module. This is beyond anything I've ever done on the big iron so you'll have to experiment.
Both those pages are from the publib-boulder sites which everyone using an IBM product should know about (along with the redbooks/redpapers site as well).
Me, I prefer the dllload/dllqueryfn solution since that's what I'm used to from AIX and other UNIXes and it seems to provide maximum flexibility.

Resources