Skip to content

Commit 5044368

Browse files
miss-islingtonaiskblurb-it[bot]
authored
[3.14] gh-145335: Fix crash when passing -1 as fd in os.pathconf (GH-145390) (#145433)
gh-145335: Fix crash when passing -1 as fd in os.pathconf (GH-145390) (cherry picked from commit 5c3a47b) Co-authored-by: AN Long <aisk@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
1 parent 4f07938 commit 5044368

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

Lib/test/test_os.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,16 @@ def test_fpathconf_bad_fd(self):
26072607
self.check(os.pathconf, "PC_NAME_MAX")
26082608
self.check(os.fpathconf, "PC_NAME_MAX")
26092609

2610+
@unittest.skipUnless(hasattr(os, 'pathconf'), 'test needs os.pathconf()')
2611+
@unittest.skipIf(
2612+
support.linked_to_musl(),
2613+
'musl fpathconf ignores the file descriptor and returns a constant',
2614+
)
2615+
def test_pathconf_negative_fd_uses_fd_semantics(self):
2616+
with self.assertRaises(OSError) as ctx:
2617+
os.pathconf(-1, 1)
2618+
self.assertEqual(ctx.exception.errno, errno.EBADF)
2619+
26102620
@unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
26112621
def test_ftruncate(self):
26122622
self.check(os.truncate, 0)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in :func:`os.pathconf` when called with ``-1`` as the path
2+
argument.

Modules/posixmodule.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,8 @@ get_posix_state(PyObject *module)
12511251
* Contains a file descriptor if path.accept_fd was true
12521252
* and the caller provided a signed integer instead of any
12531253
* sort of string.
1254+
* path.is_fd
1255+
* True if path was provided as a file descriptor.
12541256
*
12551257
* WARNING: if your "path" parameter is optional, and is
12561258
* unspecified, path_converter will never get called.
@@ -1303,6 +1305,7 @@ typedef struct {
13031305
const wchar_t *wide;
13041306
const char *narrow;
13051307
int fd;
1308+
bool is_fd;
13061309
int value_error;
13071310
Py_ssize_t length;
13081311
PyObject *object;
@@ -1312,7 +1315,7 @@ typedef struct {
13121315
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \
13131316
make_wide, suppress_value_error, allow_fd) \
13141317
{function_name, argument_name, nullable, nonstrict, make_wide, \
1315-
suppress_value_error, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL}
1318+
suppress_value_error, allow_fd, NULL, NULL, -1, false, 0, 0, NULL, NULL}
13161319
#ifdef MS_WINDOWS
13171320
#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \
13181321
nonstrict, suppress_value_error, allow_fd) \
@@ -1446,6 +1449,7 @@ path_converter(PyObject *o, void *p)
14461449
}
14471450
path->wide = NULL;
14481451
path->narrow = NULL;
1452+
path->is_fd = true;
14491453
goto success_exit;
14501454
}
14511455
else {
@@ -13841,8 +13845,9 @@ os_pathconf_impl(PyObject *module, path_t *path, int name)
1384113845

1384213846
errno = 0;
1384313847
#ifdef HAVE_FPATHCONF
13844-
if (path->fd != -1)
13848+
if (path->is_fd) {
1384513849
limit = fpathconf(path->fd, name);
13850+
}
1384613851
else
1384713852
#endif
1384813853
limit = pathconf(path->narrow, name);

0 commit comments

Comments
 (0)