This is why in UNIX-like systems, file/device permissions have to be checked using the authorisation that was in place at open() time and not at write() / read() time; this allows passed or inherited file descriptors to function like capabilities in this sense.
For example, when you run a setuid binary, it inherits file descriptors (stdin, stdout and stderr) that were opened by the caller - to prevent a certain class of confused deputy attacks, writes and reads on these file descriptors should not use the elevated privileges of the binary but the original privileges of the opener.
For example, when you run a setuid binary, it inherits file descriptors (stdin, stdout and stderr) that were opened by the caller - to prevent a certain class of confused deputy attacks, writes and reads on these file descriptors should not use the elevated privileges of the binary but the original privileges of the opener.