Bug 16028 - Investigate pseudo/uutils incompatibilities
Summary: Investigate pseudo/uutils incompatibilities
Status: ACCEPTED
Alias: None
Product: OE-Core
Classification: Build System, Metadata & Runtime
Component: core (show other bugs)
Version: 5.2
Hardware: All Multiple
: Medium+ normal
Target Milestone: 6.1 M1
Assignee: Ross Burton
QA Contact:
URL:
Whiteboard:
: 16027 (view as bug list)
Depends on: 16075
Blocks:
  Show dependency tree
 
Reported: 2025-10-23 13:23 UTC by Ross Burton
Modified: 2026-03-26 16:52 UTC (History)
10 users (show)

See Also:
OS type for building Yocto: ---
Type of Regression: ---
Verified:
Documentation change: Yes (doc changes required)


Attachments
Verbose pseudo log (45.69 KB, text/plain)
2025-10-24 14:27 UTC, Ross Burton
no flags Details
Error base-passwd (8.32 KB, text/plain)
2025-10-25 06:48 UTC, Hains
no flags Details
fix up the implementation of realpath (1.24 KB, patch)
2025-12-19 13:20 UTC, Gauthier HADERER
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ross Burton 2025-10-23 13:23:59 UTC
We've had reports (https://lists.openembedded.org/g/openembedded-core/message/225182) that Ubuntu 25.10 has uutils/coreutils instead of GNU coreutils, which is implemented in Rust so instead of hitting symbols that pseudo can intercept, directly invokes syscalls.

pseudo cannot handle this, so we should detect this and tell the user to install gnu coreutils, assuming ubuntu doesn't actually install both and we can be clever with our hosttools links.
Comment 1 Tim Orling 2025-10-23 14:52:30 UTC
*** Bug 16027 has been marked as a duplicate of this bug. ***
Comment 2 Tim Orling 2025-10-23 14:56:21 UTC
Ross will try to find an owner.
Comment 3 Ross Burton 2025-10-24 12:34:27 UTC
Of note, not all of coreutils is redirected to uutils:

lrwxrwxrwx   1 root root        8 Sep 26 21:16 chmod -> gnuchmod
lrwxrwxrwx   1 root root        8 Sep 26 21:16 chown -> gnuchown
lrwxrwxrwx   1 root root        5 Sep 26 21:16 cp -> gnucp
lrwxrwxrwx   1 root root        5 Sep 26 21:16 df -> gnudf
lrwxrwxrwx   1 root root        5 Sep 26 21:16 mv -> gnumv
lrwxrwxrwx   1 root root        5 Sep 26 21:16 rm -> gnurm
lrwxrwxrwx   1 root root        7 Sep 26 21:16 true -> gnutrue
Comment 4 Ross Burton 2025-10-24 12:57:34 UTC
Easiest reproducer is glibc-locale:

ERROR: glibc-locale-2.42+git-r0 do_install: Execution of '/home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/temp/run.do_install.9977' failed with exit code 1
ERROR: Logfile of failure stored in: /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/temp/log.do_install.9977



| couldn't allocate absolute path for 'null'.
| couldn't allocate absolute path for 'null'.
| couldn't allocate absolute path for 'null'.
| couldn't allocate absolute path for 'null'.
...


And as expected, switching our hosttools/install link to to gnuinstall fixes this.
Comment 5 Ross Burton 2025-10-24 13:08:42 UTC
The crash is from pseudo, so the rust implementation is still calling some glibc functions that break pseudo.
Comment 6 Ross Burton 2025-10-24 13:17:29 UTC
So the good news is that uutils mostly wraps the libc functions, so eg install.rs ends up calling libc:chown() which is a binding to the libc function, not syscalls directly.

Which makes why it fails even more annoying...
Comment 7 Ross Burton 2025-10-24 13:35:09 UTC
I put PSEUDO_DEBUG=1 into glibc-locales.inc and replaced hosttools/install with a wrapper that prints the command being invoked and this happens:

DEBUG: Executing shell function do_install
openat(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/sources/glibc-2.42+git), flags 2000000, stat rc 0, stat mode 40755
openat(path /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/bin), flags 2144400, stat rc 0, stat mode 40755
RUNNING /home/ross/poky/build/tmp/hosttools/install -d /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/.
couldn't allocate absolute path for 'null'.
creating directory '/home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin'
statx(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin), flags 0, stat rc 0, stat uid 1750
openat(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/sources/glibc-2.42+git), flags 2000000, stat rc 0, stat mode 40755
openat(path /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/bin), flags 2144400, stat rc 0, stat mode 40755
chdirat : (48534) (no request)
RUNNING /home/ross/poky/build/tmp/hosttools/install -m 0755 -t /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/. /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/bin/./localedef
couldn't allocate absolute path for 'null'.
statx(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin), flags 0, stat rc 0, stat uid 1750
statx(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin), flags 0, stat rc 0, stat uid 1750
openat(path /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/bin/localedef), flags 2000000, stat rc 0, stat mode 100755
openat_creat: /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/localedef -> 0100755
openat(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/localedef), flags 2001101, stat rc 0, stat mode 100755
statx(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/localedef), flags 10400, stat rc 0, stat uid 1750
statx(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/localedef), flags 0, stat rc 0, stat uid 1750
'/home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/bin/./localedef' -> '/home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/image/usr/bin/./localedef'
openat(path /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/sources/glibc-2.42+git), flags 2000000, stat rc 0, stat mode 40755
openat(path /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/usr/lib/locale), flags 2144400, stat rc 0, stat mode 40755
...

Copying in Mark as he knows way more about pseudo than I do.
Comment 8 Ross Burton 2025-10-24 14:27:51 UTC
Created attachment 5150 [details]
Verbose pseudo log

Attached is a verbose log from pseudo with PSEUDO_DEBUG=foyw and breaking the install loop in glibc-locale.inc:copy_locale_files() on the first iteration (so, two calls to install, one to make a directory and the other to copy a file).
Comment 9 Ross Burton 2025-10-24 15:21:19 UTC
I think those are a false lead, the actual fail is a little later:

| RUNNING /home/ross/poky/build/tmp/hosttools/install -m 0644 /home/ross/poky/build/tmp/sysroots-components/x86-64-v3/glibc-stash-locale/SUPPORTED /home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/SUPPORTED
...
| wrapper called: lchown
| lchown ignored path, calling real syscall.
| wrapper completed: lchown returns -1 (errno: 22)
| /usr/bin/install: failed to chown '/home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/SUPPORTED': changing group of '/home/ross/poky/build/tmp/work/x86-64-v3-poky-linux/glibc-locale/2.42+git/SUPPORTED': Invalid argument (os error 22)

Note that this error is expected: we don't pseudo in that directory.

A minimal reproducer is this recipe:

SUMMARY = "foo"
LICENSE = "CLOSED"

export PSEUDO_DEBUG = "foyw"

do_install() {
        touch ${WORKDIR}/foo
        install ${WORKDIR}/foo ${WORKDIR}/foo2
}

I believe the problem here is that:
- install is being asked to put a file into WORKDIR
- as it's in fakeroot context, uid is root:root
- uutils-install wants to chown to root:root once it has created the file
- however, workdir is outside of the allowed pseudo directories and so it doesn't intercept the call and forwards it, which then fails because normal users can't chown(root).

Note that there are almost definitely multiple issues: #16027 reported symlinks appearing in build/ which looked like they were part of the busybox build too.

Hains: if you're willing to test, switching your system back to having coreutils-from-uutils (so /usr/bin/install is from uutils, not gnuinstall) would be interesting. I'm curious what fails if you create a clean build tree, and then switch the tmp/hosttools/install symlink to /usr/bin/gnuinstall.
Comment 10 Ross Burton 2025-10-24 15:45:23 UTC
I wish you could edit previous comments in bugzilla...

The spurious links are from busybox's update-alternatives running at rootfs time:

+ update-alternatives --install /bin/ash ash /bin/busybox.nosuid 50
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for ''.
tail: cannot open 'standard input' for reading: No such file or directory
couldn't allocate absolute path for 'null'.
couldn't allocate absolute path for 'null'.
ln: Permission denied
%post(busybox-1.37.0-r0.x86_64_v3): waitpid(61372) rc 61372 status 100


At least two issues:
1) bad install/chown/pseudo behaviour that doesn't match gnu install
2) "couldn't allocate absolute path for 'null'" at least spams the logs
2.5) ...and possibly causes further problems
Comment 11 Ross Burton 2025-10-24 15:46:13 UTC
Notably, I reproduced the rootfs failure by doing a build entirely from public sstate, so the actual packages are good and it's just the rootfs creation that is failing.
Comment 12 Hains 2025-10-25 06:48:20 UTC
I started from scratch. I removed the entire build directory.

Beside errors during rootfs and do_install glibc, I got an error with base-password during do_package stage when coreutils-from-gnu has been removed from system.

For test I had to comment out line 112, 'addtask do_package after do_populate_sysroot'.
Comment 13 Hains 2025-10-25 06:48:56 UTC
Created attachment 5152 [details]
Error base-passwd
Comment 14 Hains 2025-10-25 06:52:39 UTC
Edit comment 12. glibc must be glibc-locale.
Comment 15 Ross Burton 2025-10-27 21:44:28 UTC
Confirmed issue from sysvinit-inittab:

3) tail: cannot open 'standard input' for reading: No such file or directory
Comment 16 Ross Burton 2025-10-27 22:43:23 UTC
4) various tools call statx() with NULL instead of "", which appears to be wrong according to POSIX, and causes "couldn't allocate absolute path for 'null'".
Comment 17 Khem Raj 2025-10-28 01:31:43 UTC
(In reply to Ross Burton from comment #16)
> 4) various tools call statx() with NULL instead of "", which appears to be
> wrong according to POSIX, and causes "couldn't allocate absolute path for
> 'null'".

I wonder if syscall has AT_EMPTY_PATH in flags, which would let kernel process/ignore path variable even when its NULL, and use the file descriptor for operation ( provided its fstatat call )
Comment 18 Ross Burton 2025-10-29 13:07:20 UTC
Sent a patch to prefer gnu-prefixed binaries until the breakage is fixed.
Comment 19 Ross Burton 2025-11-02 14:44:06 UTC
5) perl's build does a cp in a deleted directory which upsets things. https://github.com/openembedded/openembedded-core/pull/110 has a workaround, needs a little investigation to see if this is a cp-specific issue or another instance of (2).
Comment 20 Ross Burton 2025-11-06 10:48:29 UTC
The workaround to prefer gnu-prefixed tools has been merged in oe-core 16f2684ebeffa72b5d90525cf9102751b68c298e.

Root-causing the other bugs are not a high priority release blocker.
Comment 21 Ross Burton 2025-11-17 10:44:58 UTC
Issues that have been filed with uutils, which may or may not be bugs in uutils itself but are definitely either issues in pseudo, or exposed by pseudo:

https://github.com/uutils/coreutils/issues/9288
https://github.com/uutils/coreutils/issues/9292
Comment 22 Ross Burton 2025-11-27 15:46:52 UTC
Pulling out "couldn't allocate absolute path for 'null'" to 16075.
Comment 23 Gauthier HADERER 2025-12-19 13:20:33 UTC
Created attachment 5163 [details]
fix up the implementation of realpath

The pseudo implementation of `realpath()' may return a path which doesn't exist. This is not POSIX compliant and causes troubles with uutils (coreutils in Rust).

For example, the tail commands tries to determine the file path of its standard input file descriptor by calling `realpath("/dev/fd/0")'. When the input is a pipe, the GNU C library returns NULL but pseudo returns `/proc/<pid>/fd/pipe:[xxxxxx]'. As it got a path, the tail command tries to open it and fails.
Comment 24 Gauthier HADERER 2025-12-19 13:21:43 UTC
Hi all,

I attached a patch which enables to build a full image on Ubuntu 25.10. It was tested with scarthgap only. I hope this helps.
Comment 25 Ross Burton 2025-12-19 13:46:35 UTC
Gauthier, could you post that patch to the mailing list for review?  The last few lines of the README has the configuration for git-send-email. Thanks!
Comment 26 Gauthier HADERER 2025-12-19 14:08:02 UTC
Hi Ross,

I've just done it: https://lists.yoctoproject.org/g/yocto-patches/topic/pseudo_patch_unix/116859482. Let me know if I did it wrong or missed something.

Cheers
Comment 27 Ross Burton 2025-12-19 14:09:22 UTC
Looks good, thanks
Comment 28 Mark Hatle 2025-12-22 17:36:21 UTC
I think a simple test case for the tail issue (using _GNU_ tail) would be:

echo "test" | tail /dev/fd/0

without pseudo this returns the expected "tail"


with pseudo this returns:

tail: cannot open '/dev/fd/0' for reading: No such file or directory
Comment 29 Mark Hatle 2025-12-23 22:18:11 UTC
I've sent a patch for review.  After doing further investigation the function (and what it calls) pseudo_fix_path is what needs to do special behavior to address the issue.  It appears the problems are unique to the special /proc filesystem semantics, so the fix is likely to resolve path names until /proc and then stop doing further resolution.