os.execute safety

Post Reply
User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

os.execute safety

by v-rob » Post

I'm making a mod that needs to use the filesystem because node metadata isn't good for what I'm trying to do. Lua doesn't have much support for using the filesystem, so as a result, I need to use os.execute to use a few commands. But I have two questions: How can I tell if the user is running Linux or Windows to determine the commands I should use, and how can I sandbox the commands properly? Would making sure the command stays within a designated folder inside the world folder be enough, or is there a way to exploit that?

Thanks.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

User avatar
octacian
Member
Posts: 597
Joined: Mon Dec 21, 2015 22:18
GitHub: octacian
IRC: octacian
In-game: octacian
Location: Canada

Re: os.execute safety

by octacian » Post

Is mod storage not sufficient either? I'd turn to that first, but otherwise, use the basic Lua IO library. A good example of a mod where I had to do this is with my computer mod, digicompute. You're welcome to refer to it for examples on how to implement functions to perform the different filesystem operation if you'd like. In particular, see builtin.lua. When I last tested, everything appeared to work on Windows as well as Linux, however, it ought to be tested a bit more, as there are a few things I saw when I last skimmed through the code that don't look quite right.

Now, please note that the API I provided you for reference does nothing to lock down the directory which is accessible, although unless mod security is disabled or an exception is added, no mod can write outside of the Minetest directory. However, I'd still recommend that you add a function to process the path, forcing the addition of a base directory at the front of the path string. You should also parse the path for occurrences of `..` that are separated from the rest, as it is possible to use this to back out even of a base directory prepended to the path string (a bug I have yet to fix in digicompute).
MicroExpansion, Working Computers, All Projects - Check out my YouTube channel! (octacian)
I'm currently inactive in the Minetest community! So if I don't respond, that's why.

User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

Re: os.execute safety

by v-rob » Post

So, you're saying that if I keep the mod contained within the accessible directory, then it's perfectly safe? That's good to know. But here's why I asked about telling whether the user is running Windows or Linux. In both Windows and Linux, you can't normally remove a full directory using just rd <directory name>. Instead, on Linux, you need to use rm -r <directory name> and on Windows rm /s <directory name>. So, for example, could I say this on runtime to detect the operating system?

Code: Select all

local os_type = ""
if os.execute("ls") then
     os_type = "linux"
elseif os.execute("dir") then
     os_type = "windows"
else
     os_type = "unknown"
end
Of course, I don't know anything about Macs, but from what I saw online, their command lines are fairly similar to Linux, and I wouldn't have to worry about the differences, although I am not 100% sure.

I do have protection against getting out of the designated folder. The base folder name will be prepended by a special symbol, and the mod will detect if you try to cd .. your way out of it. So, unless you have access to the real world filesystem, there's no way out of it. Also, you won't be able to make directories or files using that symbol.

And no, mod storage is not enough. I could potentially use meta, but meta is not like a filesystem.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: os.execute safety

by Linuxdirk » Post

v-rob wrote:

Code: Select all

local os_type = ""
if os.execute("ls") then
     os_type = "linux"
elseif os.execute("dir") then
     os_type = "windows"
else
     os_type = "unknown"
end
Woops, I broke your code. It now says I use Windows.

Code: Select all

$ ls
file1  file2  file3
$ dir
file1  file2  file3
$
… because …

Code: Select all

$ type dir
dir is hashed (/usr/bin/dir)
$ pacman -Qo /usr/bin/dir
/usr/bin/dir is owned by coreutils 8.29-1
$

User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

Re: os.execute safety

by v-rob » Post

Linuxdirk wrote:
v-rob wrote:

Code: Select all

local os_type = ""
if os.execute("ls") then
     os_type = "linux"
elseif os.execute("dir") then
     os_type = "windows"
else
     os_type = "unknown"
end
Woops, I broke your code. It now says I use Windows.

Code: Select all

$ ls
file1  file2  file3
$ dir
file1  file2  file3
$
… because …

Code: Select all

$ type dir
dir is hashed (/usr/bin/dir)
$ pacman -Qo /usr/bin/dir
/usr/bin/dir is owned by coreutils 8.29-1
$
That's not true if your reasoning is that since Linux has both dir and ls. If the command line has ls, then it must be Linux. Windows has no ls command. Therefore, since ls exists, then the os is Linux. The dir check afterwords has no effect if it's Linux because the if statement has been satisfied. The dir check is actually to make sure that it's actually Windows. I could potentially use a plain else, but that's unnecessary.

Of course, I could use any command there, not just ls and dir.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

User avatar
octacian
Member
Posts: 597
Joined: Mon Dec 21, 2015 22:18
GitHub: octacian
IRC: octacian
In-game: octacian
Location: Canada

Re: os.execute safety

by octacian » Post

Ok, first off, if you really want to determine the OS, see the answers to this StackOverflow post.

However, I don't really think you need to determine the OS in order to interact with the filesystem in every way, including listing directory contents, creating files, removing files, creating directory, removing directories, checking if files exist, checking if a file or directory (not sure if this quite works right in my API though), and writing to files. From my knowledge, my API in digicompute for interaction with the filesystem works completely fine on both POSIX-compatible machines and Windows machines.

To make sure though, I'll try to test it via WINE or on my dualboot installation in order to make sure, and will post back here later.
MicroExpansion, Working Computers, All Projects - Check out my YouTube channel! (octacian)
I'm currently inactive in the Minetest community! So if I don't respond, that's why.

User avatar
Linuxdirk
Member
Posts: 3218
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: os.execute safety

by Linuxdirk » Post

v-rob wrote:If the command line has ls, then it must be Linux. Windows has no ls command.
Well …

But let’s skip this discussion here. It is not possible to tell the operating system basing on the availability of a command. Doing so is unreliable and stupid.

User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

Re: os.execute safety

by v-rob » Post

The reason why I'm hesitant to use digicompute's API is that parts of it didn't seem to work when I first tried them out. But the only reason I need os.execute is for changing and deleting directories, as well as copying, renaming, and moving files and directories. For instance, in Linux, the command for copying files is cp, but in Windows, you have to use copy for files or xcopy for files and directories.

I wish that there was an API for this in Minetest.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

User avatar
octacian
Member
Posts: 597
Joined: Mon Dec 21, 2015 22:18
GitHub: octacian
IRC: octacian
In-game: octacian
Location: Canada

Re: os.execute safety

by octacian » Post

v-rob wrote:The reason why I'm hesitant to use digicompute's API is that parts of it didn't seem to work when I first tried them out. But the only reason I need os.execute is for changing and deleting directories, as well as copying, renaming, and moving files and directories. For instance, in Linux, the command for copying files is cp, but in Windows, you have to use copy for files or xcopy for files and directories.

I wish that there was an API for this in Minetest.
Personally, I wouldn't even bother with trying to use the command. Just read the contents of a file and write it to another.

And, I can confirm that digicompute's API is completely functional on Linux (including copying and removing directories), just gotta mess around with Windows.

BTW, I previously had a PR open to implement cpdir and rmdir APIs in MT, but never got around to finish it. There were a couple more APIs that devs requested I implement, and I think it didn't handle symlinks or something. As I haven't really been active in MT anymore though, the PR was closed. Should anyone be interested, it can be found here. Being a simpler thing, I might actually finish it one day, but if someone were to do so first, that'd be fine.
MicroExpansion, Working Computers, All Projects - Check out my YouTube channel! (octacian)
I'm currently inactive in the Minetest community! So if I don't respond, that's why.

hajo
Member
Posts: 606
Joined: Thu Oct 13, 2016 10:45
Location: DE
Contact:

Re: os.execute safety

by hajo » Post

v-rob wrote:changing and deleting directories, as well as copying, renaming, and moving files and directories.
I wish that there was an API for this
Well, there is POSIX...

OTOH, what you want to do, maybe it can be done in some other ways -
but you would need to provide more details about your concept.

User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

Re: os.execute safety

by v-rob » Post

Well, I just found that meta is, in fact, suitable enough for my purposes. My first idea was to use a table as a filesystem, but node metadata uses strings, not tables. So, I turned to the actual filesystem and found that Lua has little filesystem management. I didn't really like the idea of using os.execute, but I didn't see any other way. But now I just found minetest.serialize and minetest.deserialize, and I can use node metadata without having to hack around with os.execute.

I still can't say that this is solved though, and I think the cpdir/rmdir/mvdir API is a good idea still.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

User avatar
octacian
Member
Posts: 597
Joined: Mon Dec 21, 2015 22:18
GitHub: octacian
IRC: octacian
In-game: octacian
Location: Canada

Re: os.execute safety

by octacian » Post

Glad you found a way to do it. I am really curious now though, what are you actually trying to do?

And regarding using os.execute, yeah, it would've been a bit of a hack to use it in the way that you had suggested. I just want to remind you though, that there are, even without a new API being exposed, ways to do exactly what you wanted in Lua (refer to the SO post and to digicompute's builtin.lua, which while far from perfect, demonstrates that the task is possible.
MicroExpansion, Working Computers, All Projects - Check out my YouTube channel! (octacian)
I'm currently inactive in the Minetest community! So if I don't respond, that's why.

User avatar
v-rob
Developer
Posts: 970
Joined: Thu Mar 24, 2016 03:19
GitHub: v-rob
IRC: v-rob
Location: Right behind you.

Re: os.execute safety

by v-rob » Post

octacian wrote:Glad you found a way to do it. I am really curious now though, what are you actually trying to do?
Well, I usually try not to talk about my mods or post them until they're finished in case I can't actually finish them and disappoint people, but I'm fairly sure that I can finish this mod.

I want a filesystem because I'm making a computer mod akin to both digicompute and the laptop mod, but combining, in my opinion, the best qualities of both, although it's a lot more like digicompute. To name the basics, it's terminal based, will have a complete filesystem, printer, mail, simple mesecon and digiline support, and removable floppy disks.

I'm doing this instead of using digicompute or the laptop mod because digicompute probably won't have the same level of functionality as mine will since you're moving away from Minetest, and the laptop mod is a large mod and not terminal oriented, and has no filesystem at all. I'm not using digicompute's API because I find it easier to code from scratch and I have more leeway as to what I can do.

There are a lot more fine details, but I'll explain them when I finish and post the mod. If nothing goes wrong, I'll probably have it done in two weeks or so, but there are always complications that I can't account for.
Core Developer | My Best Mods: Bridger - Slats - Stained Glass

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests