I've come across two games so far that allow user-contributed content, but am unsure of how to proceed with the file permissions.
The first game, njam, has an in-game editor for users to create new levels. The directory where user-levels are saved is /usr/share/njam/levels.
The second game, hack (part of bsd-games), creates 'bones' files when a character dies. These bones files are later loaded and removed when other players start a game to create ghosts and treasure piles.
In both cases this user-contributed content needs to be placed in a directory that is writable by the game binary. This is similar to the shared scoreboard file, except that in both of these cases the name of the file is not known in advance, so we can't open a setgid filehandle when the game starts up and then drop setgid.
hack works around this by not dropping setgid so that the app is free to create new files in the content directory, which isn't the safest thing to do.
Does anyone have any ideas on how we can allow this user-contributed content without sacrificing too much security in the games?
--Mike
"w" == wart wart@kobold.org writes:
w> The first game, njam, has an in-game editor for users to create new w> levels. The directory where user-levels are saved is w> /usr/share/njam/levels.
If you really want to support something like this, (and I'd argue that it isn't worth it) here are a couple of ideas:
Save in a known place in the user's home directory and set read permission. Of course, to load a level, you need to know what user made it.
Somehow pass the data to a small program that has the appropriate privileges that does nothing but move the data into place.
w> The second game, hack (part of bsd-games), creates 'bones' files w> when a character dies. These bones files are later loaded and w> removed when other players start a game to create ghosts and w> treasure piles.
Ugh; it is really not possible to determine the name of the bones file early in the process? Is there some reason it can't just be some random string?
- J<
It occurred to me that you could fix the hack bone file issue by using some sort of structured format and storing all of the bone information in a single file.
- J<
Jason L Tibbitts III wrote:
It occurred to me that you could fix the hack bone file issue by using some sort of structured format and storing all of the bone information in a single file.
This would take some work to implement, but it's a good idea. I'll definitely look into it.
Thanks,
--Mike
Jason L Tibbitts III wrote:
"w" == wart wart@kobold.org writes:
w> The first game, njam, has an in-game editor for users to create new w> levels. The directory where user-levels are saved is w> /usr/share/njam/levels.
If you really want to support something like this, (and I'd argue that it isn't worth it) here are a couple of ideas:
Save in a known place in the user's home directory and set read permission. Of course, to load a level, you need to know what user made it.
Somehow pass the data to a small program that has the appropriate privileges that does nothing but move the data into place.
This is a pretty good idea. Something like 'njam-install-level' that could also perform some sanity checks on the game data to prevent bad data from being installed.
w> The second game, hack (part of bsd-games), creates 'bones' files w> when a character dies. These bones files are later loaded and w> removed when other players start a game to create ghosts and w> treasure piles.
Ugh; it is really not possible to determine the name of the bones file early in the process? Is there some reason it can't just be some random string?
The bones files are created based on the dungeon level that the user died on. There is a maximum of one bones file per user per dungeon level. This means that we don't know the name of the file until the user dies, that is, until the game ends.
I found an article by David Wheeler discussing secure programming techniques. Section 7.4 discusses minimizing privileges and is quite a good read:
http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/minimize-privi...
--Mike
"w" == wart wart@kobold.org writes:
w> The bones files are created based on the dungeon level that the w> user died on. There is a maximum of one bones file per user per w> dungeon level. This means that we don't know the name of the file w> until the user dies, that is, until the game ends.
In that case, store the level inside the file and use a partially random name. It means that if you want to open a file for a particular dungeon level then you have to scan, but these days that isn't too much of a concern unless you have tens of thousands of files.
It doesn't help you if you need to modify arbitrary files during play, however.
- J<
Wart wrote:
I've come across two games so far that allow user-contributed content, but am unsure of how to proceed with the file permissions.
The first game, njam, has an in-game editor for users to create new levels. The directory where user-levels are saved is /usr/share/njam/levels.
The second game, hack (part of bsd-games), creates 'bones' files when a character dies. These bones files are later loaded and removed when other players start a game to create ghosts and treasure piles.
In both cases this user-contributed content needs to be placed in a directory that is writable by the game binary. This is similar to the shared scoreboard file, except that in both of these cases the name of the file is not known in advance, so we can't open a setgid filehandle when the game starts up and then drop setgid.
hack works around this by not dropping setgid so that the app is free to create new files in the content directory, which isn't the safest thing to do.
Does anyone have any ideas on how we can allow this user-contributed content without sacrificing too much security in the games?
I _really_ believe we shouldn't try to wrangle ourself into all kinda corners for things like this. Either we can solve things simply, or we should try to not solve them at all.
My suggestions for the 2 given examples: -just give hack its own private group and let it run as that, that reduces the risc to: -someone manages to get hack-rights -this someone uses those rights to create malformed input files for hack -if someone-else runs hack these malformed input files could cause hack todo unwanted stuff with someone-else's rights. Then the question becomes is this an acceptable risk, we could make the risk even smaller by implementing the suggestions done by Jason so that the files can be opened immediatly in main and rights dropped, if we do things Jason's way we probably don't even need a seperate hack user. -for njam, teach it to save and look for levels under $HOME, if a user wants to share his levels he can just give them to other users to copy to their level dir, or ask his sysadmin to put them in the global dir, why should we assume he wants to share them and jump through hoops to automaticly share them for him?
Regards,
Hans
Hans de Goede wrote:
Wart wrote:
I've come across two games so far that allow user-contributed content, but am unsure of how to proceed with the file permissions.
The first game, njam, has an in-game editor for users to create new levels. The directory where user-levels are saved is /usr/share/njam/levels.
The second game, hack (part of bsd-games), creates 'bones' files when a character dies. These bones files are later loaded and removed when other players start a game to create ghosts and treasure piles.
In both cases this user-contributed content needs to be placed in a directory that is writable by the game binary. This is similar to the shared scoreboard file, except that in both of these cases the name of the file is not known in advance, so we can't open a setgid filehandle when the game starts up and then drop setgid.
hack works around this by not dropping setgid so that the app is free to create new files in the content directory, which isn't the safest thing to do.
Does anyone have any ideas on how we can allow this user-contributed content without sacrificing too much security in the games?
I _really_ believe we shouldn't try to wrangle ourself into all kinda corners for things like this. Either we can solve things simply, or we should try to not solve them at all.
My suggestions for the 2 given examples: -just give hack its own private group and let it run as that, that reduces the risc to: -someone manages to get hack-rights -this someone uses those rights to create malformed input files for hack -if someone-else runs hack these malformed input files could cause hack todo unwanted stuff with someone-else's rights. Then the question becomes is this an acceptable risk, we could make the risk even smaller by implementing the suggestions done by Jason so that the files can be opened immediatly in main and rights dropped, if we do things Jason's way we probably don't even need a seperate hack user.
The more I work on hack, the more I realize how tricky this one is. I was able to make a patch to deal with the bones files, and the scoreboard file, but then ran into problems with file locks. It seems that hack wants to use hardlinks to create a file lock to prevent concurrent writing. It also wants to create a lock file to prevent two people from playing simultaneously under the same name. While I might be able to make a patch to work around all of this, it is quickly becoming nontrivial and pretty invasive. I'm starting to prefer this custom gid solution...
-for njam, teach it to save and look for levels under $HOME, if a user wants to share his levels he can just give them to other users to copy to their level dir, or ask his sysadmin to put them in the global dir, why should we assume he wants to share them and jump through hoops to automaticly share them for him?
That sounds fair enough. I still think a njam-install-level command would be useful, but it's something that upstream could provide.
--Mike
On Sat, Apr 22, 2006 at 07:27:45PM -0700, Wart wrote:
I've come across two games so far that allow user-contributed content, but am unsure of how to proceed with the file permissions. The first game, njam, has an in-game editor for users to create new levels. The directory where user-levels are saved is /usr/share/njam/levels.
Everything else aside, this needs to be modified to be in /var instead of /usr.