Subject: bug#8292: COREUTILS-8.9: Potential bug in tests/cp/preserve-gid

From: gmail <[email-masked]>
Date: Sun, 20 Mar 2011 14:33:32 +0100

Jim Meyering wrote :
> gmail wrote:
>
>> Some commands in other test scripts could have the same problem and
>> should be then enforced in the same way, i'll do this if this is the
>> right solution.
> Nice analysis.  Thanks for reporting that.
> That's a particularly convoluted part of the test suite.
> I think the patch below solves the problem, too, while
> continuing to invoke tools solely by their name
> (i.e., with no relative or absolute prefix)
> Can you confirm?
>
> BTW, coreutils-8.10 is the latest stable release.
>
>  From 7a3eca37167590a0cc245dc4ea7cb23815d81665 Mon Sep 17 00:00:00 2001
> From: Jim Meyering<[email-masked]>
> Date: Sun, 20 Mar 2011 08:56:06 +0100
> Subject: [PATCH] tests: fix a bug in cp/preserve-gid
>
> * tests/cp/preserve-gid (t1): Export PATH into the environment used
> by setuidgid, so that it runs the just-built "cp", rather than whatever
> happens to be in $PATH.  Otherwise, we would see a test failure
> whenever there is a less-functional cp in PATH.
> Analysis by [email-masked] in http://debbugs.gnu.org/8292.
> ---
>   tests/cp/preserve-gid |    3 ++-
>   1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/tests/cp/preserve-gid b/tests/cp/preserve-gid
> index ac6d221..41b993c 100755
> --- a/tests/cp/preserve-gid
> +++ b/tests/cp/preserve-gid
> @@ -56,7 +56,8 @@ t1() {
>     f=$1; shift
>     u=$1; shift
>     g=$1; shift
> -  t0 "$f" "$u" "$g" setuidgid -g "$nameless_gid1,$nameless_gid2" \
> +  t0 "$f" "$u" "$g" env PATH="$PATH" \
> +      setuidgid -g "$nameless_gid1,$nameless_gid2" \
>         "$nameless_uid" "$@"
>   }
>
> --
> 1.7.4.1.499.g53f9

It's a far better way to solve this, imho. I was reluctant to alter the 
environment, fearing side effects due to my lack of knownledge regarding 
coreutils test chain, but  your approach, a local change, is elegant, 
efficient and riskless.
Alas, i was wrong thinking it was due to an unexported PATH variable, 
the PATH variable was already exporterd, the problem was elsewhere   :

    (adding <typeset -p PATH> in the test) :

+ typeset -p PATH
declare -x 
PATH="/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"

But the setuigid command does not use this path, so the test fail :

[root@pompomgalli]# cd coreutils-8.9_build3

[root@pompomgalli]# cd tests/gt-preserve-gid.o3Qn

[root@zeus gt-preserve-gid.o3Qn]# ../../src/setuidgid -g 1000,1001 1000 
../../src/cp -p c1 ww

[root@zeus gt-preserve-gid.o3Qn]# ../../src/setuidgid -g 1000,1001 1000 
cp -p c1 ww2

[root@zeus gt-preserve-gid.o3Qn]# ls -l

total 32
-rw-r--r-- 1 root root 3 Mar 20 12:51 a0
-rw-r--r-- 1 1000 1000 3 Mar 20 12:51 b
-rw-r--r-- 1 1000 1000 3 Mar 20 12:51 b0
-rw-r--r-- 1 1000 1001 3 Mar 20 12:51 b1
-rw-r--r-- 1 root 1000 3 Mar 20 12:51 c0
-rw-r--r-- 1 root 1001 3 Mar 20 12:51 c1
-rw-r--r-- 1 1000 1001 3 Mar 20 12:51 ww
-rw-r--r-- 1 1000 1000 3 Mar 20 12:51 ww2

[root@zeus gt-preserve-gid.o3Qn]# cd ../..

[root@pompomgalli] NON_ROOT_USERNAME=cedric make -k check 
TESTS=cp/preserve-gid VERBOSE=yes

     FAIL: cp/preserve-gid (exit: 1)
     ===============================

     ++ initial_cwd_=/usr/src/coreutils-8.9_build3/tests
     ++ fail=0
     +++ testdir_prefix_
     +++ printf gt
     ++ pfx_=gt
     +++ mktempd_ /usr/src/coreutils-8.9_build3/tests gt-preserve-gid.XXXX
     +++ destdir_=/usr/src/coreutils-8.9_build3/tests
     +++ template_=gt-preserve-gid.XXXX
     +++ MAX_TRIES_=4
     ++++ unset TMPDIR
     ++++ mktemp -d -t -p /usr/src/coreutils-8.9_build3/tests 
gt-preserve-gid.XXXX
     +++ d=/usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     +++ test -d /usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     ++++ tr S -
     ++++ ls -dgo /usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     +++ perms=drwx------ 2 4096 Mar 20 12:40 
/usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     +++ test 0 = 0
     +++ echo /usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     +++ return
     ++ test_dir_=/usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     ++ cd /usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     ++ gl_init_sh_nl_=

     ++ IFS=

     +++ expr 1 + 128
     ++ eval 'trap '\''Exit 129'\'' 1'
     +++ trap 'Exit 129' 1
     +++ expr 2 + 128
     ++ eval 'trap '\''Exit 130'\'' 2'
     +++ trap 'Exit 130' 2
     +++ expr 3 + 128
     ++ eval 'trap '\''Exit 131'\'' 3'
     +++ trap 'Exit 131' 3
     +++ expr 13 + 128
     ++ eval 'trap '\''Exit 141'\'' 13'
     +++ trap 'Exit 141' 13
     +++ expr 15 + 128
     ++ eval 'trap '\''Exit 143'\'' 15'
     +++ trap 'Exit 143' 15
     ++ trap remove_tmp_ 0
     + path_prepend_ ../src
     + test 1 '!=' 0
     + path_dir_=../src
     ++ cd /usr/src/coreutils-8.9_build3/tests/../src
     ++ echo /usr/src/coreutils-8.9_build3/src
     + abs_path_dir_=/usr/src/coreutils-8.9_build3/src
     + 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
     + create_exe_shims_ /usr/src/coreutils-8.9_build3/src
     + return 0
     + shift
     + test 0 '!=' 0
     + export PATH
     + print_ver_ cp
     + test yes = yes
     + local i
     + env cp --version
     cp (GNU coreutils) 8.9
     Copyright (C) 2011 Free Software Foundation, Inc.
     License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
     This is free software: you are free to change and redistribute it.
     There is NO WARRANTY, to the extent permitted by law.

     Written by Torbj"orn Granlund, David MacKenzie, and Jim Meyering.
     + require_root_
     + uid_is_privileged_
     ++ id -u
     + my_uid=0
     + NON_ROOT_USERNAME=cedric
     ++ id -g cedric
     + NON_ROOT_GROUP=2003
     + working_umask_or_skip_
     + umask 022
     + touch file1 file2
     + chmod 644 file2
     ++ uniq
     ++ sed 's/ .*//'
     ++ ls -l file1 file2
     + perms=-rw-r--r--
     + rm -f file1 file2
     ++ id -g
     + primary_group_num=0
     ++ perl -le '
       foreach my $i (1000..16*1024-1)
         {
           getpwuid $i or (print $i), exit
         }
     '
     + nameless_uid=1000
     ++ perl -le '
       foreach my $i (1000..16*1024)
         {
           getgrgid $i or (print $i), exit
         }
     '
     + nameless_gid1=1000
     ++ perl -le '
       foreach my $i (1000+1..16*1024)
         {
           getgrgid $i or (print $i), exit
         }
     '
     + nameless_gid2=1001
     + test -z 1000
     + test -z 1000
     + test -z 1001
     + chown +1000:+0 .
     + create a0 0 0
     + echo a0
     + chown +0:+0 a0
     + create b0 1000 1000
     + echo b0
     + chown +1000:+1000 b0
     + create b1 1000 1001
     + echo b1
     + chown +1000:+1001 b1
     + create c0 0 1000
     + echo c0
     + chown +0:+1000 c0
     + create c1 0 1001
     + echo c1
     + chown +0:+1001 c1
     + t0 a0 0 0 cp
     + f=a0
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp a0 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 b0 0 0 cp
     + f=b0
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp b0 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 b1 0 0 cp
     + f=b1
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp b1 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 c0 0 0 cp
     + f=c0
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp c0 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 c1 0 0 cp
     + f=c1
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp c1 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 a0 0 0 cp -p
     + f=a0
     + shift
     + u=0
     + shift
     + g=0
     + shift
     + rm -f b
     + cp -p a0 b
     ++ stat -c '%u %g' b
     + s=0 0
     + test 'x0 0' '!=' 'x0 0'
     + t0 b0 1000 1000 cp -p
     + f=b0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + cp -p b0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t0 b1 1000 1001 cp -p
     + f=b1
     + shift
     + u=1000
     + shift
     + g=1001
     + shift
     + rm -f b
     + cp -p b1 b
     ++ stat -c '%u %g' b
     + s=1000 1001
     + test 'x1000 1001' '!=' 'x1000 1001'
     + t0 c0 0 1000 cp -p
     + f=c0
     + shift
     + u=0
     + shift
     + g=1000
     + shift
     + rm -f b
     + cp -p c0 b
     ++ stat -c '%u %g' b
     + s=0 1000
     + test 'x0 1000' '!=' 'x0 1000'
     + t0 c1 0 1001 cp -p
     + f=c1
     + shift
     + u=0
     + shift
     + g=1001
     + shift
     + rm -f b
     + cp -p c1 b
     ++ stat -c '%u %g' b
     + s=0 1001
     + test 'x0 1001' '!=' 'x0 1001'
     + t1 a0 1000 1000 cp
     + f=a0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 a0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp
     + f=a0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp a0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 b0 1000 1000 cp
     + f=b0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 b0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp
     + f=b0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp b0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 b1 1000 1000 cp
     + f=b1
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 b1 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp
     + f=b1
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp b1 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 c0 1000 1000 cp
     + f=c0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 c0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp
     + f=c0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp c0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 c1 1000 1000 cp
     + f=c1
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 c1 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp
     + f=c1
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp c1 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 a0 1000 1000 cp -p
     + f=a0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 a0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p
     + f=a0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p a0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 b0 1000 1000 cp -p
     + f=b0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 b0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p
     + f=b0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p b0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 b1 1000 1001 cp -p
     + f=b1
     + shift
     + u=1000
     + shift
     + g=1001
     + shift
     + t0 b1 1000 1001 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p
     + f=b1
     + shift
     + u=1000
     + shift
     + shift
     + u=1000
     + shift
     + g=1001
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p b1 b
     ++ stat -c '%u %g' b
     + s=1000 1001
     + test 'x1000 1001' '!=' 'x1000 1001'
     + t1 c0 1000 1000 cp -p
     + f=c0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + t0 c0 1000 1000 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p
     + f=c0
     + shift
     + u=1000
     + shift
     + g=1000
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p c0 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1000'
     + t1 c1 1000 1001 cp -p
     + f=c1
     + shift
     + u=1000
     + shift
     + g=1001
     + shift
     + t0 c1 1000 1001 env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p
     + f=c1
     + shift
     + u=1000
     + shift
     + g=1001
     + shift
     + rm -f b
     + env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p c1 b
     ++ stat -c '%u %g' b
     + s=1000 1000
     + test 'x1000 1000' '!=' 'x1000 1001'
     + test 'x1000 1000' = 'x1000 0'
     + echo '../../coreutils-8.9/tests/cp/preserve-gid: env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -
     p c1 b: 1000 1001 != 1000 1000'
     ../../coreutils-8.9/tests/cp/preserve-gid: env 
PATH=/usr/src/coreutils-8.9_build3/src:/usr/src/coreutils-8.9_build3/src:.:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin 
setuidgid -g 1000,1001 1000 cp -p c1 b:
     1000 1001 != 1000 1000
     + Exit 1
     + set +e
     + exit 1
     + exit 1
     + remove_tmp_
     + __st=1
     + cleanup_
     + :
     + cd /usr/src/coreutils-8.9_build3/tests
     + chmod -R u+rwx 
/usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     + rm -rf /usr/src/coreutils-8.9_build3/tests/gt-preserve-gid.bDee
     + exit 1

Normally setuidgid MUST take the parent shell environment, so i finally 
add a strace in the test to the original source :

--- tests/cp/preserve-gid       2011-03-20 13:34:52.000000000 +0100
+++ tests/cp/preserve-gid.orig  2011-01-01 22:19:23.000000000 +0100
@@ -38,7 +38,7 @@
    u=$1; shift
    g=$1; shift
    rm -f b || exit 1
-  strace -o ../../trace.txt "$@" "$f" b || exit 1
+  "$@" "$f" b || exit 1
    s=`stat -c '%u %g' b`
    if test "x$s" != "x$u $g"; then
      # Allow the actual group to match that of the parent directory

And got this .... :

     execve("/usr/src/coreutils-8.9_build3/src/setuidgid", ["setuidgid", 
"-g", "1000,1001", "1000", "cp", "-p", "c1", "b"], [/* 72 vars */]) = 0
     brk(0)                                  = 0x804f000
     mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
-1, 0) = 0xb77c0000
     access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file 
or directory)
     open("/lib/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file 
or directory)
     stat64("/lib/tls/i686", 0xbf916d80)     = -1 ENOENT (No such file 
or directory)
     open("/lib/tls/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file 
or directory)
     stat64("/lib/tls", 0xbf916d80)          = -1 ENOENT (No such file 
or directory)
     open("/lib/i686/libc.so.6", O_RDONLY)   = 3
     read(3, 
"\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`o\1\000"..., 512) = 512
     fstat64(3, {st_mode=S_IFREG|0755, st_size=9034904, ...}) = 0
     mmap2(NULL, 1427976, PROT_READ|PROT_EXEC, 
MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7663000
     mprotect(0xb77b9000, 4096, PROT_NONE)   = 0
     mmap2(0xb77ba000, 12288, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x156) = 0xb77ba000
     mmap2(0xb77bd000, 10760, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb77bd000
     close(3)                                = 0
     mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
-1, 0) = 0xb7662000
     set_thread_area({entry_number:-1 -> 6, base_addr:0xb76626c0, 
limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, 
limit_in_pages:1, seg_not_present:0, useable:1}) = 0
     mprotect(0xb77ba000, 8192, PROT_READ)   = 0
     mprotect(0xb77dd000, 4096, PROT_READ)   = 0
     brk(0)                                  = 0x804f000
     brk(0x8070000)                          = 0x8070000
     setgroups32(0x2, 0x804f038)             = 0
     setgid32(0x3e8)                         = 0
     setuid32(0x3e8)                         = 0
 >>  execve("/usr/src/coreutils-8.9_build3/src/cp", ["cp", "-p", "c1", 
"b"], [/* 72 vars */]) = -1 EACCES (Permission denied)
 >>  execve("/usr/src/coreutils-8.9_build3/src/cp", ["cp", "-p", "c1", 
"b"], [/* 72 vars */]) = -1 EACCES (Permission denied)
     execve("./cp", ["cp", "-p", "c1", "b"], [/* 72 vars */]) = -1 
ENOENT (No such file or directory)
     execve("/bin/cp", ["cp", "-p", "c1", "b"], [/* 72 vars */]) = 0
     brk(0)                                  = 0x8055000

The setuidgid has the PATH, but this is an absolute PATH and PATH 
traversal with the test uid/gid  fail. The command then fall on the 
first available cp command on the remaining PATH...

So i have lightly modified your patch in the following way :

--- tests/cp/preserve-gid.jme   2011-03-20 12:57:53.000000000 +0100
+++ tests/cp/preserve-gid       2011-03-20 14:05:19.000000000 +0100
@@ -56,7 +56,7 @@
    f=$1; shift
    u=$1; shift
    g=$1; shift
-  t0 "$f" "$u" "$g" env PATH="$PATH" \
+  t0 "$f" "$u" "$g" env PATH="../../src:$PATH" \
        setuidgid -g "$nameless_gid1,$nameless_gid2" \
        "$nameless_uid" "$@"
  }

And the test was then succesfull.

Perhaps the use of absolute paths with test uid/gid  is the real problem 
that should be addressed ?

Regards, Cédric.