From 394984db9c8727f953b3499e6378d999a9c2dce4 Mon Sep 17 00:00:00 2001 From: barneygale Date: Tue, 2 Apr 2024 20:28:39 +0100 Subject: [PATCH 1/3] GH-114847: Raise FileNotFoundError when getcwd() returns '(unreachable)' On Linux >= 2.6.36 with glibc < 2.27, `getcwd()` can return a relative pathname starting with '(unreachable)'. We detect this and fail with ENOENT, matching new glibc behaviour. --- .../2024-04-02-20-30-12.gh-issue-114848.YX4pEc.rst | 2 ++ Modules/posixmodule.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-04-02-20-30-12.gh-issue-114848.YX4pEc.rst diff --git a/Misc/NEWS.d/next/Library/2024-04-02-20-30-12.gh-issue-114848.YX4pEc.rst b/Misc/NEWS.d/next/Library/2024-04-02-20-30-12.gh-issue-114848.YX4pEc.rst new file mode 100644 index 00000000000000..30b1a50976f52d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-02-20-30-12.gh-issue-114848.YX4pEc.rst @@ -0,0 +1,2 @@ +Raise :exc:`FileNotFoundError` when ``getcwd()`` returns '(unreachable)', +which can happen on Linux >= 2.6.36 with glibc < 2.27. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a4b635ef5bf629..ec93359c0c697e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4098,6 +4098,19 @@ posix_getcwd(int use_bytes) PyMem_RawFree(buf); return NULL; } +#ifdef __linux__ + if (buf[0] != '/') { + /* + * On Linux >= 2.6.36 with glibc < 2.27, getcwd() can return a + * relative pathname starting with '(unreachable)'. We detect this + * and fail with ENOENT, matching newer glibc behaviour. + */ + errno = ENOENT; + posix_error(); + PyMem_RawFree(buf); + return NULL; + } +#endif PyObject *obj; if (use_bytes) { From bec3b2cdb3e66ba429c9776c870571684ff80d34 Mon Sep 17 00:00:00 2001 From: barneygale Date: Tue, 2 Apr 2024 21:40:37 +0100 Subject: [PATCH 2/3] Add getcwd() result to OSError --- Modules/posixmodule.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ec93359c0c697e..5c1e697908e44a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4098,6 +4098,14 @@ posix_getcwd(int use_bytes) PyMem_RawFree(buf); return NULL; } + + PyObject *obj; + if (use_bytes) { + obj = PyBytes_FromStringAndSize(buf, strlen(buf)); + } + else { + obj = PyUnicode_DecodeFSDefault(buf); + } #ifdef __linux__ if (buf[0] != '/') { /* @@ -4106,19 +4114,11 @@ posix_getcwd(int use_bytes) * and fail with ENOENT, matching newer glibc behaviour. */ errno = ENOENT; - posix_error(); + path_object_error(obj); PyMem_RawFree(buf); return NULL; } #endif - - PyObject *obj; - if (use_bytes) { - obj = PyBytes_FromStringAndSize(buf, strlen(buf)); - } - else { - obj = PyUnicode_DecodeFSDefault(buf); - } PyMem_RawFree(buf); return obj; From c11f3a8be10516257f816ef5ffc002f99acbfbbf Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Wed, 3 Apr 2024 16:07:14 +0100 Subject: [PATCH 3/3] Update Modules/posixmodule.c Co-authored-by: Petr Viktorin --- Modules/posixmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 5c1e697908e44a..fcac3dbe3553ef 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4119,6 +4119,7 @@ posix_getcwd(int use_bytes) return NULL; } #endif + assert(buf[0] == '/'); PyMem_RawFree(buf); return obj;