[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
readlink("/proc/self/exe") with glibc 2.28 is broken?
From: |
Ludovic Courtès |
Subject: |
readlink("/proc/self/exe") with glibc 2.28 is broken? |
Date: |
Sat, 15 Dec 2018 18:47:46 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) |
Hello hacker herd!
The attached C code reads /proc/self/exe. I tested it on darnassus in
two contexts:
1. Natively compiled with the Debian toolchain available on darnassus;
2. Cross-built with the GNU toolchain (which includes stock
glibc 2.28) found in Guix, statically-linked.
#1 works as expected whereas for #2 readlink("/proc/self/exe") returns
EGRATUITOUS; #2 works for other symlinks though.
rpctrace shows that Guix’s libc doesn’t behave like Debian’s on
darnassus. Namely, Guix libc 2.28 does this:
--8<---------------cut here---------------start------------->8---
137<--176(pid8674)->dir_lookup ("proc/self/exe" 65 0) = 0 1 "self/exe"
191<--190(pid8674)
191<--190(pid8674)->dir_lookup ("self/exe" 65 0) = 0 3 "pid/exe" (null)
task163(pid8674)->mach_port_deallocate (pn{ 20}) = 0
task163(pid8674)->mach_port_mod_refs (pn{ 7} 0 1) = 0
task163(pid8674)->mach_port_mod_refs (pn{ 19} 0 1) = 0
124<--174(pid8674)->io_get_openmodes () = 0 3
124<--174(pid8674)->io_stat () = 0 {14 21405 0 0 0 1437067240 0 8397200 1
1006 5 0 0 1544895840 0 1544895840 0 1544895840 0 512 8 0 0 0 136648208 3259 0
0 1315456 3261 136650912 3262}
189<--188(pid8674)->io_write ("readlink: Gratuitous error\n" -1)readlink:
Gratuitous error
= 0 27
--8<---------------cut here---------------end--------------->8---
… whereas Debian’s libc does:
--8<---------------cut here---------------start------------->8---
137<--176(pid8678)->dir_lookup ("proc/self/exe" 65 0) = 0 1 "self/exe"
192<--191(pid8678)
task163(pid8678)->mach_port_mod_refs (pn{ 21} 0 1) = 0
192<--191(pid8678)->dir_lookup ("self/exe" 65 0) = 0 3 "pid/exe" (null)
task163(pid8678)->mach_port_deallocate (pn{ 21}) = 0
task163(pid8678)->mach_port_mod_refs (pn{ 21} 0 1) = 0
192<--191(pid8678)->dir_lookup ("8678/exe" 65 0) = 0 1 ""
194<--193(pid8678)
task163(pid8678)->mach_port_deallocate (pn{ 21}) = 0
task163(pid8678)->mach_port_deallocate (pn{ 21}) = 0
194<--193(pid8678)->io_stat () = 0 {0 0 0 -395048269 0 0 0 41471 0 1006 0 18
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
194<--193(pid8678)->io_read (0 256) = 0 "./cross-built.dynl"
task163(pid8678)->mach_port_deallocate (pn{ 22}) = 0
139<--173(pid8678)->io_stat () = 0 {14 21405 0 0 0 1437067240 0 8397200 1
1006 5 0 0 1544895879 0 1544895879 0 1544895879 0 512 8 0 0 0 136648208 3259 0
0 1315456 3261 136650912 3262}
188<--166(pid8678)->io_write ("readlink ("/proc/self/exe") =
"./cross-built.dynl"\n" -1)readlink ("/proc/self/exe") = "./cross-built.dynl"
= 0 51
--8<---------------cut here---------------end--------------->8---
So Debian libc (presumably ‘file_name_lookup’) is doing more work, which
proves to be useful. :-)
Am I missing anything obvious to you? For example, are there patches
that Debian uses and that upstream 2.28 still lacks?
Thanks in advance!
Ludo’.
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <errno.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
ssize_t ret;
char program[256] = { 0, };
const char *arg = (argc > 1) ? argv[1] : "/proc/self/exe";
ret = readlink (arg, program, sizeof program);
if (ret < 0)
perror ("readlink");
printf ("readlink (\"%s\") = \"%s\"\n", arg, program);
return 0;
}
- readlink("/proc/self/exe") with glibc 2.28 is broken?,
Ludovic Courtès <=