[C++-sig] profiling python extension

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Mon Mar 1 05:39:48 CET 2010


> The only inconvenience is that I need to start and finish it only being a root. This means
> I either have to switch back and forth oftenly or do all profiling (and development as a root). 

I'm in an environment with relatively few users which I fully trust. To get around the
inconvenience I run the script below which installs two set-user-id-root commands
"opcontrol_start" and "opcontrol_shutdown".

Ralf


#! /bin/csh -f
set verbose

gcc -o setuid_linux setuid_linux.c
cp setuid_linux /usr/bin/opcontrol_start
mv setuid_linux /usr/bin/opcontrol_shutdown

cat << EOT > /usr/bin/opcontrol_start.script
#! /bin/bash -r
set -v
opcontrol --reset; opcontrol --start
EOT

cat << EOT > /usr/bin/opcontrol_shutdown.script
#! /bin/bash -r
set -v
opcontrol --shutdown
EOT

chmod 6711 /usr/bin/opcontrol_start /usr/bin/opcontrol_shutdown
chmod 755 /usr/bin/opcontrol_start.script /usr/bin/opcontrol_shutdown.script
opcontrol --no-vmlinux




% cat setuid_linux.c

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

static char **cpargv(int argc, char *argv[], const char *cmd_name)
{
  int   i;
  char  **cargv;

      cargv = malloc((argc + 1) * sizeof (*cargv));
  if (cargv == NULL)
    return NULL;

  cargv[0] = (char *) cmd_name;

  for (i = 1; i < argc; i++)
    cargv[i] = argv[i];

  cargv[i] = NULL;

  return cargv;
}

static const char *StripFileName(const char *PathName, int Separator)
{
  const char  *FileName;


  for (FileName = PathName; *PathName; PathName++)
    if (*PathName == Separator)
      FileName = PathName + 1;

  return FileName;
}

static const char *TrustedCommands[] =
{
  "opcontrol_start",
  "opcontrol_shutdown",
  NULL
};

int main(int argc, char *argv[])
{
  const char  *progn, **tc, *cmd_dir, *cmd_ext;
  char        *cmd_path, **run_cmd_argv;
  int         n;

  progn = StripFileName(argv[0], '/');

  for (tc = TrustedCommands; *tc; tc++)
    if (strcmp(progn, *tc) == 0)
      break;

  if (*tc == NULL)
  {
    fprintf(stderr, "%s: Not a trusted command.\n", progn);
    exit(1);
  }

  if (setuid(0) != 0) {
    perror(progn);
    exit(1);
  }
  if (setgid(0) != 0) {
    perror(progn);
    exit(1);
  }

      run_cmd_argv = cpargv(argc, argv, progn);
  if (run_cmd_argv == NULL)
  {
    fprintf(stderr, "%s: Not enough core.\n", progn);
    exit(1);
  }

  cmd_dir = "/usr/bin/";
  cmd_ext = ".script";

  n = strlen(cmd_dir) + strlen(progn) + strlen(cmd_ext) + 1;

      cmd_path = malloc(n * sizeof (*cmd_path));
  if (cmd_path == NULL)
  {
    fprintf(stderr, "%s: Not enough core.\n", progn);
    exit(1);
  }

  strcpy(cmd_path, cmd_dir);
  strcat(cmd_path, progn);
  strcat(cmd_path, cmd_ext);

  (void) execv(cmd_path, run_cmd_argv);

  perror(progn);

  exit (1);
  return 0;
}


More information about the Cplusplus-sig mailing list