Project

General

Profile

Bug #1465

/dev/fd should be symlink (was: BASH: Process substitution fails)

Added by Oliver Loch over 6 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
-
Target version:
Start date:
Due date:
% Done:

0%

Estimated time:
Affected versions:
Security IDs:

Description

Hi,

on the latest edge version of bash, process substitution fails. If you run:

==== SNIP ==== 8< =====

snow:~# read x y z < <(echo 1 2 3); echo $x
-bash: /dev/fd/62: No such file or directory

snow:~#

==== >8 ===== SNAP ====

you get the above error. It usually works.

I already talked to the guys in #bash on freenode and they think (!) it is uclibc related.

On a GNU libc machine one gets this result:

===== >8 === SNIP =====

[root@bomber ~]# read x y z < <(echo 1 2 3); echo $x
1
[root@bomber ~]#

==== SNAP === 8< ======

Some additional information:

snow:~# apk info bash
bash-4.2.037-r0 description:
The GNU Bourne Again shell

bash-4.2.037-r0 webpage:
http://www.gnu.org/software/bash/bash.html

bash-4.2.037-r0 installed size:
741376

snow:~#

snow:~# set | grep -E ^BASH
BASH=/bin/bash
BASHOPTS=cmdhist:expand_aliases:extglob:extquote:force_fignore:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION=/etc/bash_completion
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
BASH_COMPLETION_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="37" [3]="2" [4]="release" [5]="x86_64-unknown-linux-gnu")
BASH_VERSION='4.2.37(2)-release'
snow:~#

cu

Associated revisions

Revision 20dfee5a (diff)
Added by Natanael Copa over 6 years ago

main/busybox-initscripts: fix /dev/fd symlink

ref #1465

I think the initramfs create /dev/fd as a dir. When mdev-mount later runs
'ln -snf /proc/self/fd /dev/fd' the 'fd' symlink ends up as /dev/fd/fd.

We fix this by always remove /dev/fd before creating the symlink.

Revision 5ec48327 (diff)
Added by Natanael Copa over 6 years ago

main/udev: make sure /dev/fd is a symlink to /proc/self/fd

ref #1465

Revision 6438be23 (diff)
Added by Natanael Copa about 6 years ago

main/busybox-initscripts: fix /dev/fd symlink

ref #1465

I think the initramfs create /dev/fd as a dir. When mdev-mount later runs
'ln -snf /proc/self/fd /dev/fd' the 'fd' symlink ends up as /dev/fd/fd.

We fix this by always remove /dev/fd before creating the symlink.
(cherry picked from commit 20dfee5aff22b445738a27d737b31121b709d920)

History

#1 Updated by Natanael Copa over 6 years ago

  • Description updated (diff)

I can reproduce it on my 32 bit laptop:

ncopa-laptop:~$ read x y z < <(echo 1 2 3); echo $x
bash: /dev/fd/62: No such file or directory

#2 Updated by Natanael Copa over 6 years ago

This is not an uclibc issue. I think its an udev (and mdev?) issue.

Seems like the contents of /dev/fd is symlinks to /proc/self/fd/*. But when bash does dup2(somefd, 62), the /dev/fd/62 is never created. Just guessing here, but there are no udev event when a new fd is created with dup2().

Seems like replacing the /dev/fd dir with a symlink to /proc/self/fd makes it work.

I suspect that bash now depends on that /dev/fd is a symlink to /proc/self/fd. Maybe this was a change in recent udev? I am not sure what or how the /dev/fd/* stuff was set up in the first place, but should not be hard to fix.

#3 Updated by Natanael Copa over 6 years ago

The mdev stuff looks correct. Do you use udev or mdev?

#4 Updated by Oliver Loch over 6 years ago

Natanael Copa wrote:

The mdev stuff looks correct. Do you use udev or mdev?

Mdev

#5 Updated by Oliver Loch over 6 years ago

Hi,

I've been testing a bit and the "mdev hint" lead me into the right direction.

If one changes the following line:

"console root:tty 0600 @mkdir -pm 755 fd && cd fd && for x in 0 1 2 3 ; do ln -s /proc/self/fd/$x $x; done"

to:

"console root:tty 0600 @rm -r /dev/fd; ln -s /proc/self/fd /dev/fd;"

It begins to work.

Three things I don't like about that:

#1 I haven't found the point where /dev/fd is initially created and it should be better to just create instead of recreating it

#2 the "old" line just links the descriptors that are available the moment it is invoked. I don't think it's a good practice, so we should switch to linking complete /proc/self/fd instead of it's children.

#3 I don't know how the mdev line affects other tools/shells/whatever and wonder if it would be better to put the recreation of /dev/fd into "profile" or "bashrc" or something.

KR,

Oliver

#6 Updated by Natanael Copa over 6 years ago

Oliver Loch wrote:

Hi,

I've been testing a bit and the "mdev hint" lead me into the right direction.

If one changes the following line:

"console root:tty 0600 @mkdir -pm 755 fd && cd fd && for x in 0 1 2 3 ; do ln -s /proc/self/fd/$x $x; done"

to:

"console root:tty 0600 @rm -r /dev/fd; ln -s /proc/self/fd /dev/fd;"

It begins to work.

What happens if you change it to:

console root:tty 0600

It looks like the /etc/init.d/mdev-mount does the right thing which should be started before mdev is enabled.

Three things I don't like about that:

#1 I haven't found the point where /dev/fd is initially created and it should be better to just create instead of recreating it

Yes. Agree. Looks like its /etc/init.d/mdev-mount.

#2 the "old" line just links the descriptors that are available the moment it is invoked. I don't think it's a good practice, so we should switch to linking complete /proc/self/fd instead of it's children.

Agree.

#3 I don't know how the mdev line affects other tools/shells/whatever and wonder if it would be better to put the recreation of /dev/fd into "profile" or "bashrc" or something.

No. we should do this with the /dev/ handler, mdev scripts. I think this also affects udev.

Thanks!

#7 Updated by Oliver Loch over 6 years ago

Hi,

I just tested. For all tests I rebuilt the initramfs image so that it gets the latest config files and rebooted the machine.

Results:

Using the line you mentioned earlier in mdev.conf, doesn't work.
Removing it completely doesn't work.
Disabling everything in mdev that creates anything /dev/fd* like (except /dev/fd0), still produces a folder /dev/fd

Even without anything mdev related to /dev/fd it is still created. The only way to make it work is to remove /dev/fd by a command in /etc/init.d/mdev-mount and then link to the right folder.

I wonder how /dev/fd is created in the first place. Can't really find anything.

Grimeton

#8 Updated by Natanael Copa about 6 years ago

  • Subject changed from BASH: Process substitution fails to /dev/fd should be symlink (was: BASH: Process substitution fails)
  • Target version set to Alpine 2.5.1

we should fix this...

#9 Updated by Natanael Copa about 6 years ago

  • Status changed from New to Resolved

actually, the 6438be2342fc3c5bdaa777db3919eea3f069b0ef seems to fix this. I just checked the latest edge snapshot iso and it looks correct there.

#10 Updated by Natanael Copa about 6 years ago

  • Status changed from Resolved to Closed

#11 Updated by Carlo Landmeter 6 months ago

  • File deleted (smime.p7s)

Also available in: Atom PDF