[Top][All Lists]
[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);
}