Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a system that needs to be able to reboot a different piece of hardware partway through a script that programs it. It used to wait for me to come and reboot the hardware halfway through, but I've since automated that. I use this python script to control a USB Net Power 8800.

I have two setups to show you: First is a system that I'm sure is secure, but is pretty annoying to maintain; I'm sure the second is insecure.

First:

/usr/bin/power (not set-uid)

#!/bin/sh
if [ -e /opt/usbnetpower/_powerwrapper_$1 ] ; then
        /opt/usbnetpower/_powerwrapper_$1
else
        /opt/usbnetpower/_powerwrapper_
fi

/opt/usbnetpower/_powerwrapper_reboot.c (The source code to one of six almost identical set-uid programs)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
   setuid( 0 );
   system( "/usr/bin/python /opt/usbnetpower/usbnetpower8800.py reboot" );

   return 0;
}

The reason why there are six is that I didn't trust myself to write correct sanitization code in C that wasn't vulnerable to buffer overflows and the like.

/opt/usbnetpower/usbnetpower8800.py (not set-uid)

Essentially this, but modified to add a reboot command.

This setup is what I am currently using.

Second:

/opt/usbnetpower/usbnetpower8800.py (set-uid)

Much simpler, but I'm concerned that a vulnerability like this would apply. Also, suid python programs appear to be disabled on my system. (CentOS 6)

share|improve this question
    
Personally I gradually abandon all set-uid things in my system. I primarily use daemons listening UNIX sockets which nonprivileged programs can connect to and ask commands. That way you control what exactly is being used (instead of just all user environment by default). I've developed a program to start other programs over UNIX sockets in controlled way. –  Vi. May 22 '13 at 22:37

1 Answer 1

up vote 2 down vote accepted

Both of your programs are insecure. The problem is that I can set PYTHONPATH to anything I like before executing the program. I can set it to something so that it loads my own usb module which can execute whatever code I like. At that point, I'm executing code as the root user and can do whatever I please. That's why set-uid doesn't work on scripts, and your binary C program wrapper doesn't change that at all.

For more information see: http://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts

In your case, what you should be doing is changing the permissions so that your user has access to the USB device you are supposed to be controlling. That way you don't need to run the script as another user. That's what this portion of the script you are using is referring to:

# If you have a permission error using the script and udev is used on your
# system, it can be used to apply the correct permissions. Example:
#  $ cat /etc/udev/rules.d/51-usbpower.rules
#  SUBSYSTEM=="usb", ATTR{idVendor}=="067b", MODE="0666", GROUP="plugdev"

Discussion of how to adjust your system to give you permission to access the USB device is out of scope for this site. I'm also not really an expert on that. So you may need to ask elsewhere for that.

share|improve this answer
    
In your case, what you should be doing is changing the permissions so that your user has access to the USB device you are supposed to be controlling. This is what I ended up doing; I open-sourced my changes –  Nick ODell Apr 2 '13 at 0:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.