Bug 1916968 - realpath sets errno to EINVAL on success
Summary: realpath sets errno to EINVAL on success
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: rawhide
Hardware: x86_64
OS: Linux
unspecified
low
Target Milestone: ---
Assignee: Carlos O'Donell
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-01-16 00:49 UTC by Jerry James
Modified: 2021-02-08 12:19 UTC (History)
11 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2021-01-18 21:59:39 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Program demonstrating that realpath sets errno to EINVAL on success (1.22 KB, text/x-csrc)
2021-01-16 00:49 UTC, Jerry James
no flags Details

Description Jerry James 2021-01-16 00:49:59 UTC
Created attachment 1748055 [details]
Program demonstrating that realpath sets errno to EINVAL on success

Description of problem:
Koschei let me know today that the gcl package started failing to build.  Investigation shows that this is because realpath("/proc/self/exe", buffer) returns a pointer to buffer to indicate success, but also sets errno to EINVAL.  This is new behavior.  The attached program, when built and run on Fedora 33 and earlier, reports:

/proc/self/exe is a regular file
It's real path is [path to executable]
[path to executable]: Success

but in Rawhide it reports:

/proc/self/exe is a regular file
It's real path is [path to executable]
[path to executable]: Invalid argument

Version-Release number of selected component (if applicable):
glibc-2.32.9000-26.fc34.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Compile the attached C program on Rawhide
2. Run it on Rawhide

Actual results:
See that realpath sets errno to EINVAL on success.

Expected results:
realpath should not touch errno or set it to zero on success

Additional info:

Comment 1 Florian Weimer 2021-01-16 10:41:41 UTC
In general, POSIX specifies that errno only has a valid value after an unsuccessful function call. glibc follows this policy.

What is the purpose of the errno check in gcl? It sounds like a bug in the code.

Comment 2 Jerry James 2021-01-18 21:05:25 UTC
It's part of a function that gcl uses to find a path to itself:

static int
mbin(const char *s,char *o) {
  struct stat ss;

  if (!stat(s,&ss) && (ss.st_mode&S_IFMT)==S_IFREG && !access(s,R_OK|X_OK)) {
    massert(realpath(s,o));
    return 1;
  }
  return 0;
}

where "massert" is a macro that sets errno to 0, evaluates its argument, then asserts that errno is still 0.

It looks like the BSD realpath() also follows the convention of returning NULL on error, so I'll talk to upstream about changing the assert.  Thanks for the reply, Florian.

Comment 3 Florian Weimer 2021-01-18 21:59:39 UTC
Interesting. On Linux, it's probably best to just read /proc/self/exe, or maybe use that directly (depending on the use case).

Anyway, thanks for providing the background. I don't think this is a glibc bug, so closing.


Note You need to log in before you can comment on or make changes to this bug.