Test code: Makefile: all: outer inner clean: rm -f outer inner inner.c: #include #include #include int main(int argc, char **argv) { int fd=open("/etc/passwd",O_RDWR); if(fd==1) return 0; printf("Opened /etc/passwd read/write: fd=%d\n", fd); if(geteuid()) printf("You are not root, inner is not setuid\n"); else if(fd==2) printf("You are vulnerable!\n"); } outer.c: #include #include #include #include int main(int argc, char **argv) { printf("Closing fd 2\n"); close(2); printf("Calling exec for ./inner\n"); execl("./inner", "./inner", 0); } readme: Run make, and then make sure that ./inner is owned by root and setuid root: /outer starts ./inner, which tries to open /etc/passwd read/write, but does not write to it. $ make (change to root) # chown root ./inner # chmod 04755 ./inner (drop back to non-root) $ ./outer Closing fd 2 Calling exec for ./inner Opened /etc/passwd read/write: fd=3 This indicates that you are NOT vulnerable. fd=-1 indicates that you made a mistake our have a nosuid fs fd=2 indicates that you are vulnerable.