Subject: Re: bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call

From: Bernhard Voelker <[email-masked]>
Date: Mon, 25 Nov 2013 08:31:41 +0100

On 11/25/2013 02:10 AM, Pádraig Brady wrote:
> On 11/25/2013 12:15 AM, Bernhard Voelker wrote:
>> +cat > k.c <<'EOF' || framework_failure_
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <unistd.h>
>> +
>> +int unlinkat (int dirfd, const char *pathname, int flags)
>> +{
>> +  /* Prove that LD_PRELOAD works: create the evidence file "x".  */
>> +  fclose (fopen ("x", "w"));
>> +
>> +  /* Immediately terminate, unless indicated otherwise.  */
>> +  if (! getenv("CU_TEST_SKIP_EXIT"))
>> +    _exit (0);
>> +
>> +  /* Pretend success.  */
>> +  return 0;
>> +}
>> +EOF

>> +exercise_rm_rf_root ()
> 
> s/rf/r/
> 
>> +{
>> +  # Remove the evidence file "x"; verify that.
>> +  rm -f x   || framework_failure_
>> +  test -f x && framework_failure_
>> +
>> +  local pid
>> +  if [ "$CU_TEST_SKIP_EXIT" = 1 ]; then
>> +    # Pass on this variable into 'rm's environment.
>> +    LD_PRELOAD=./k.so CU_TEST_SKIP_EXIT=1 rm \
>> +      -rv --one-file-system "$@" > out 2> err & pid=$!
>> +  else
>> +    LD_PRELOAD=./k.so rm -rv --one-file-system "$@" > out 2> err & pid=$!
>> +  fi
>> +
>> +  # Wait for the evidence file to appear, or until the process has terminated.
>> +  for i in $(seq 10); do
>> +    test -f x    && break
>> +    kill -0 $pid || break
>> +    sleep .1
>> +  done
>> +
>> +  # At this point, rm(1) usually has already terminated.  Kill it anyway.
>> +  kill -9 $pid
> 
> So this might race with rm being preempted between the touch() and the exit(),
> causing a false failure? It's probably best to not kill if the 'x' file exists,
> as it's very unlikely that rm will run as normal in that case.

outch, the race is even more likely for the newly added "rm -r file1 / file2"
case where unlinkat() is called twice without the immediate _exit() due to
CU_TEST_SKIP_EXIT=1.

I have to reconsider, but won't have time for that today.

Thanks!

Have a nice day,
Berny