Bash – process substitution in chroot without /dev and /proc

bashchrootprocess-substitution

I have a chroot jail without /dev and /proc mounted. When I try to do process substitution here, this happens:

bash-4.4# cat <(ls)   
cat: open /dev/fd/63: No such file or directory

I tried to create /dev/fd manually and made sure all users have enough permissions, but it did not help.

Is there even any way how I can get this to work without mounting anything from the external system?

Best Answer

On Linux, /dev/fd is a symbolic link to /proc/self/fd, where /proc/self is a symlink to the process directory of the calling process. /proc/$pid/fd then contains magic links to the open filehandles. Bash uses that to make pipes that can be accessed by filename without needing to leave anything on the actual filesystem.

So, you'd need to mount /proc and make the /dev/fd symlink.

Alternatively, you could see if it's possible to get Bash to use named pipes on the filesystem, according to the manual, it should be an option:

Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.

But that seems to require a re-compile. The configure script automatically detects if /dev/fd is available, but you can disable it in config.h, delete the line

#define HAVE_DEV_FD 1

(Or change it to #undef HAVE_DEV_FD to make sure. And don't make the mistake I did: changing the 1 to a 0 doesn't work.)

With those settings, you get

$ ./bash -c 'ls -l <(echo foo)'
prw------- 1 itvirta itvirta 0 Nov 18 13:13 /tmp/sh-np.pldKay

Though if you do that with ls or some other command that doesn't actually go and read the pipe, both the pipe and a shell process are left lying around.

Related Question