Package: libuv1
Version: 1.20.3
Tags: patch

libuv1 calls readlink() with buffer size zero for /proc/self due to
downstream patch 'path_max'.

This breaks a nodejs test-case on chroot, containers, and s390x (in
Ubuntu at least), on which /dev/stdin is a symlink pointing to
/proc/self/fd/0.

On sid chroot:

    # apt-get update
    # apt-get install nodejs strace
    # apt-get source nodejs
    # cd nodejs-*

The /dev/stdin device is a symlink to /proc/self/...

    # ls -l /dev/stdin
    lrwxrwxrwx 1 root root 15 Sep 14 13:40 /dev/stdin -> /proc/self/fd/0

The lstat() call reports 'st_size' of zero for /proc/self:

    # strace -e lstat \
      stat /proc/self \
      2>&1 | grep -e lstat -e File: -e Size:
    lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=0, ...}) = 0
      File: /proc/self -> 15804
      Size: 0               Blocks: 0          IO Block: 1024   symbolic link

This causes libuv1 to call readlink() with a buffer size of zero, and
hit EINVAL:

    # strace -f -e lstat,readlink \
      node test/parallel/test-fs-realpath-pipe.js

    [pid 15906] lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3780, ...}) = 0
    [pid 15907] lstat("/dev/stdin", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
    [pid 15909] lstat("/dev/stdin", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
    [pid 15909] readlink("/dev/stdin", "/proc/self/fd/0", 15) = 15

    [pid 15906] lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
    [pid 15907] lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=0, ...}) = 0
    [pid 15909] lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=0, ...}) = 0
    [pid 15909] readlink("/proc/self", 0x7ffa38000b40, 0) = -1 EINVAL
(Invalid argument)

With this patch applied, the call to readlink() has a non-zero buffer
size and returns correctly:

    # dpkg -i libuv1_1.23.0-1+fixpathmax1_amd64.deb

    # strace -f -e lstat,readlink \
      node test/parallel/test-fs-realpath-pipe.js

    [pid 31068] lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3780, ...}) = 0
    [pid 31068] lstat("/dev/stdin", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
    [pid 31068] lstat("/dev/stdin", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
    [pid 31068] readlink("/dev/stdin", "/proc/self/fd/0", 15) = 15

    [pid 31068] lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
    [pid 31068] lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=0, ...}) = 0
    [pid 31068] lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=0, ...}) = 0
    [pid 31068] readlink("/proc/self", "31068", 256) = 5

    [pid 31068] lstat("/proc/31068", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
    [pid 31068] lstat("/proc/31068/fd", {st_mode=S_IFDIR|0500,
st_size=0, ...}) = 0
    [pid 31068] lstat("/proc/31068/fd/0", {st_mode=S_IFLNK|0700,
st_size=64, ...}) = 0
    [pid 31068] lstat("/proc/31068/fd/0", {st_mode=S_IFLNK|0700,
st_size=64, ...}) = 0
    [pid 31068] readlink("/proc/31068/fd/0", "socket:[266186]", 64) = 15

Thanks,

-- 
Mauricio Faria de Oliveira

Attachment: sid-libuv1-path_max_zero_st_size.debdiff
Description: Binary data

Reply via email to