SRCDS Steam group


Running srcds through setgid
#1
So I am making a semi-public SRCDS test enviornment where users can test their server-side mods and scripts in a controlled environment through SSH console. This also implies that I need to control precisely the parameters given to the srcds_amd executable (for example setting the IP, port, tickrate and maxplayers) and not let the users directly call it with their own parameters.

For this my permission control denies the user accounts from accessing srcds_run or srcds_amd directly but they have access to my own program that then executes srcds_amd with elevated privilegies (setgid flag) and appropriate parameters.


The problem is that srcds_amd requires LD_LIBRARY_PATH environment variable to be set to .:bin for it to be able to load the .so files. Unfortunately for my case the Linux system - as a security measure - clears the LD_LIBRARY_PATH environment variable on any process running with setuid or setgid. This means that srcds_amd can never load its libraries (it fails on loading bin/dedicated_amd.so).

The box hosts both older Source games (Counter-Strike: Source, Half-Life 2: Deathmach) and Orange Box engine games (Team Fortress 2, Day of Defeat: Source), so the load paths also cannot be statically set for ld.so (and won't even work, ldconfig only caches files that begin with lib -prefix).


Now I would need some good ideas on how to make srcds_amd able to load its files in this setup.

Thanks in advance.
Reply
#2
It seems you're way ahead of us already Wink I don't think you get good help from here. Linux specific forum might be better place to ask - but then again, it's even harder to find Linux forum where everybody aren't total idiots Wink.

What if you do "export LD_LIBRARY_PATH=.:bin" (or eg. export LD_LIBRARY_PATH=/home/testacc1234/srcds/:/...../srcds/bin/") in the privileged script? Wouldn't it then set up its own environment variables for that session?

What shell are you using? Are you sure you can setuid/setgid the shell script in the system you're using? On some system installations scripts can't be suid'd. Actually I think it's majority of systems where shell scripts aren't allowed to be suid.

What did you exactly mean with that ld.so and ldconfig stuff? So you can't run program for example "/lib/ld-2.3.6.so --library-path /home/testacc123/srcds/:/home/testacc123/srcds/bin:/lib:/usr/lib:/usr/local/lib /home/testacc123/srcds/srcds_amd -game cstrike +map ..."? Or did you mean that if you edit /etc/ld.so.conf and add for example /home/testacc123/srcds/bin/ there, then ldconfig doesn't really process the files under /bin/? Could you work-around this by linking bin/dedicated_amd.so to /usr/local/lib/?

Post you progress here. I'd be interested to know what kind of system you've got, and how you've managed to set semi-restricted SSH access for users.
Reply
#3
Thanks for the reply.

You are right, one cannot setuid/setgid shell scripts. That's how I originally planned to do it. So I recoded my scripts in C and compiled them as 32-bit ELF binaries to be able to run them with setuid/setgid flags.

The first thing I tried was setting the environment variable LD_LIBRARY_PATH inside the setgid'd C program which calls srcds_amd using execl (or execle, tried both), but even then the called program does not receive LD_LIBRARY_PATH. I prove it to myself by creating another program that simply goes through its environment variables and prints them out. If I set any other envvar than LD_LIBRARY_PATH, it is passed on correctly, but the loader apparently always strips off LD_LIBRARY_PATH when the new executable is running with other credentials (srcds_amd itself does not have setuid or setgid flags).

It didn't occur to me to try executing the ld loader itself. However, now that I tried it, it does not still work when executed from inside the C coded program, I get the usual complaint:
Quote:Failed to open bin/dedicated_amd.so (tier0_i486.so: cannot open shared object file: No such file or directory)

When I tried the exact same calling directly from shell (using bash, BTW), there were no problems. This is how I am doing the call from my program currently (folder is const char*, set earlier to point to the location where srcds_amd is, depending on the game being hosted):
Code:
sprintf(newLD, "%s:%s/bin", folder, folder);
        if (chdir(folder)!=0) {
                printf("chdir(%s) failed!\n",folder);
                return 4;
        }

        retval = execl("/lib/ld-linux.so.2", "/lib/ld-linux.so.2", "--library-path", newLD, "./srcds_amd", "-game", argv[1], "-ip", "192.168.11.150", "-port", "27015", "-maxplayers", "8", "+fps_max", "0", "-tickrate", "33", NULL);

When I remove the setgid flag from this program and run it directly with the user account that has permission to run the SRCDS directly, it works correctly. Only when the setgid or setuid flag which I need in this case, is set, the ld loader just does not want to provide any extra library path.

Ironically this is a security feature, but to get it actually working I would need to compromise my security even more than simply allowing custom library paths for elevated processes would. Only if the srcds executable itself could load its libraries from the correct locations...

Linking the bin folder inside /usr/lib does not seem so good idea to me, since the orangebox version might very well be using different versions of the files. And if you run two servers at the same time, one for CS:S and the other for TF2, which one's bin folder would I link?
Reply
#4
I'm surprised that LD_LIBRARY_PATH is completely discarded in suid programs. Obviously it's good thing not to use the user defined path, but why is it bad if the path is set inside the program itself. I don't know.

You have to search this from other more Linux/Coding specific forums.

My last wild suggestion is to link the dedicated_amd.so to your suid'd startup program. Then it should be available for srcds_amd too. However, I'm pretty much guessing this up, so I recommend doing it some other way Wink

Are you sure you even need to suid the startup script? Do you have one shared SSH account for testing, or do you automagically create user accounts on demand? You could chroot users to some extremely limited home directories with shared ~/bin/ where there is all the stuff they can run. There you could have the simple startup script without suid. You shouldn't worry so much about someone doing something nasty because users would practically just have eg. ls, mv, cp and pico. Obviously users couldn't write to ~/bin/ or somewhere else where they don't need to - or then you could have other suid'd programs which do the necessary editing.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)