===== sticky-bit matrix on /df2716h ===== --- a1 control: rmdir victim, NO trailing slash (expect EACCES/EPERM) phase=a1 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rmdir (/df2716h/df2716/victim ) = -1 errno=13 (Permission denied) rc=0 --- a2 PoC: rmdir victim WITH trailing slash (BUG: expect 0) phase=a2 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rmdir (/df2716h/df2716/victim/ ) = -1 errno=13 (Permission denied) rc=0 --- a3 control: rename victim out, NO slash (expect EACCES/EPERM) phase=a3 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rename (/df2716h/df2716/victim , /df2716h/df2716/df2716_stolen) = -1 errno=13 (Permission denied) rc=0 --- a4 PoC: rename victim out WITH trailing slash (BUG: expect 0) phase=a4 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rename (/df2716h/df2716/victim/ , /df2716h/df2716/df2716_stolen) = -1 errno=13 (Permission denied) rc=0 --- a5 PoC: rename own dir ONTO victim/ (BUG: expect 0) phase=a5 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rename (/df2716h/df2716/df2716_own_dir, /df2716h/df2716/victim/) = -1 errno=2 (No such file or directory) rc=0 ===== append-only (sappnd) matrix on /df2716h ===== --- b1 control: rmdir sappnd-dir entry, NO slash (expect EPERM) phase=b1 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rmdir (/df2716h/df2716b/sub ) = -1 errno=1 (Operation not permitted) rc=0 --- b2 PoC: rmdir sappnd-dir entry WITH trailing slash (BUG: expect 0) phase=b2 uid=1001 euid=1001 base=/df2716h/df2716 baseb=/df2716h/df2716b rmdir (/df2716h/df2716b/sub/ ) = -1 errno=1 (Operation not permitted) rc=0 ===== post-state ===== ls: /df2716h/df2716_stolen: No such file or directory drwxrwxrwt 1 root wheel 0 Aug 31 05:54 /df2716h/df2716 drwxr-xr-x 1 root wheel 0 Aug 31 05:54 /df2716h/df2716/victim drwxr-xr-x 1 maxx maxx 0 Aug 31 05:54 /df2716h/df2716_own_dir drwxrwxrwt 1 root wheel 0 Aug 31 05:54 /df2716h/df2716b drwxr-xr-x 1 root wheel 0 Aug 31 05:54 /df2716h/df2716b/sub + rm -rf /tmp/df2716reg + mkdir /tmp/df2716reg + chmod 1777 /tmp/df2716reg + su -m maxx -c 'mkdir /tmp/df2716reg/own1 /tmp/df2716reg/own2' + su -m maxx -c 'touch /tmp/df2716reg/own1/f' + su -m maxx -c 'rmdir /tmp/df2716reg/own2' + su -m maxx -c 'rmdir /tmp/df2716reg/own2' + su -m maxx -c 'mv /tmp/df2716reg/own1 /tmp/df2716reg/own1b' + echo RENAME_OK + su -m maxx -c '/tmp/df2716_bin/df2716 2>/dev/null || true' RENAME_OK bad phase + mkdir -p /tmp/df2716reg2 + chmod 1777 /tmp/df2716reg2 + mkdir /tmp/df2716reg2/od + chown maxx:maxx /tmp/df2716reg2/od + cat + cc -o /tmp/reg /tmp/reg.c /tmp/reg.c: In function 'main': /tmp/reg.c:4:7: warning: implicit declaration of function 'rmdir' [-Wimplicit-function-declaration] if (rmdir("/tmp/df2716reg2/od/")<0) printf("own-dir rmdir slash errno=%d\n", errno); ^~~~~ + su -m maxx -c /tmp/reg own-dir rmdir slash OK + rm -rf /tmp/nst + mkdir /tmp/nst + chmod 777 /tmp/nst + mkdir /tmp/nst/a /tmp/nst/b + chown maxx:maxx /tmp/nst/a /tmp/nst/b + cat + mkdir /tmp/nst/a2 + chown maxx:maxx /tmp/nst/a2 + cat + cc -o /tmp/reg2 /tmp/reg2.c + cc -o /tmp/reg3 /tmp/reg3.c + su -m maxx -c /tmp/reg2 noslash OK + su -m maxx -c /tmp/reg3 slash OK