bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rm: avoiding a race condition on non-glibc systems


From: Jim Meyering
Subject: Re: rm: avoiding a race condition on non-glibc systems
Date: Sat, 14 May 2005 15:57:06 +0200

Jim Meyering <address@hidden> wrote:
> Paul Eggert <address@hidden> wrote:
> ...
>> How about this patch?  It incorporates the above ideas.
>>
>> 2005-05-13  Paul Eggert  <address@hidden>
>>
>>      * m4/prereqs.m4 (gl_PREREQ): Require gl_UNLINKDIR.
>>      * src/remove.c: Include unlinkdir.h.
>>      (UNLINK_CAN_UNLINK_DIRS): Remove.
>>      (remove_entry): Use cannot_unlink_dirs () rather than
>>      UNLINK_CAN_UNLINK_DIRS.
>>      * lib/unlinkdir.c, lib/unlinkdir.h: New files.
>>      * m4/unlinkdir.m4: New file.
...
> I'll see if I can find someone to test the give-up-privilege
> code as root on Solaris 10.

It works.

Nelson Beebe was kind enough to run the following test program
as root on a Solaris 10 system.  He reported that it does indeed
print "Good! unlink failed -- as it should!".

-----------------------
#define HAVE_PRIV_H 1
#define HAVE_UNISTD_H 1

#if HAVE_PRIV_H
# include <priv.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

int
main ()
{
  priv_set_t *pset = priv_allocset ();
  if (!pset)
    {
      perror ("priv_allocset failed");
      exit (1);
    }

  if (getppriv (PRIV_EFFECTIVE, pset) != 0)
    {
      perror ("getppriv failed");
      exit (1);
    }

  bool can_unlink = priv_ismember (pset, PRIV_SYS_LINKDIR);
  if (!can_unlink)
    {
      printf ("you lack the PRIV_SYS_LINKDIR privilege\n");
      exit (1);
    }

  if (priv_delset (pset, PRIV_SYS_LINKDIR) != 0)
    {
      perror ("priv_delset failed");
      exit (1);
    }

  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, pset) != 0)
    {
      perror ("setppriv failed");
      exit (1);
    }

  priv_freeset (pset);

  /* Create an empty directory.  */
  char const *dir = "unlink-dir-test-dir";
  if (mkdir (dir, 0700) != 0)
    {
      perror ("mkdir failed");
      exit (1);
    }

  /* then try to unlink it */
  if (unlink (dir) != 0)
    {
      perror ("Good! unlink failed -- as it should!");
      rmdir (dir);
      exit (1);
    }

  printf ("Whoops!! you've just used unlink to remove an empty directory\n");

  exit (0);
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]