[PATCH 8/8] Reject bup_getpwuid bup_getgrgid argument overflow

4 views
Skip to first unread message

Rob Browning

unread,
May 30, 2023, 9:55:54 PM5/30/23
to bup-...@googlegroups.com
Replace PyArg_ParseTuple "K" checks (which ignore overflow) with
BUP_ASSIGN_PYLONG_TO_INTEGRAL.

Signed-off-by: Rob Browning <r...@defaultvalue.org>
Tested-by: Rob Browning <r...@defaultvalue.org>
---
lib/bup/_helpers.c | 25 ++++++++++++++++---------
src/bup/pyutil.h | 4 ++--
2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/lib/bup/_helpers.c b/lib/bup/_helpers.c
index 9bfb5e35a..9a8e1555a 100644
--- a/lib/bup/_helpers.c
+++ b/lib/bup/_helpers.c
@@ -1347,13 +1347,16 @@ static PyObject *pwd_struct_to_py(const struct passwd *pwd)

static PyObject *bup_getpwuid(PyObject *self, PyObject *args)
{
- unsigned long long py_uid;
- if (!PyArg_ParseTuple(args, "K", &py_uid))
+ PyObject *py_uid = NULL;
+ if (!PyArg_ParseTuple(args, "O", &py_uid))
return NULL;
uid_t uid;
- if (!INTEGRAL_ASSIGNMENT_FITS(&uid, py_uid))
- return PyErr_Format(PyExc_OverflowError, "uid too large for uid_t");
-
+ int overflow;
+ if (!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&uid, py_uid, &overflow)) {
+ if (overflow)
+ return PyErr_Format(PyExc_OverflowError, "uid too large for uid_t");
+ return NULL;
+ }
errno = 0;
struct passwd *pwd = getpwuid(uid);
if (!pwd && errno)
@@ -1395,12 +1398,16 @@ static PyObject *grp_struct_to_py(const struct group *grp)

static PyObject *bup_getgrgid(PyObject *self, PyObject *args)
{
- unsigned long long py_gid;
- if (!PyArg_ParseTuple(args, "K", &py_gid))
+ PyObject *py_gid = NULL;
+ if (!PyArg_ParseTuple(args, "O", &py_gid))
return NULL;
gid_t gid;
- if (!INTEGRAL_ASSIGNMENT_FITS(&gid, py_gid))
- return PyErr_Format(PyExc_OverflowError, "gid too large for gid_t");
+ int overflow;
+ if (!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&gid, py_gid, &overflow)) {
+ if (overflow)
+ return PyErr_Format(PyExc_OverflowError, "gid too large for gid_t");
+ return NULL;
+ }

errno = 0;
struct group *grp = getgrgid(gid);
diff --git a/src/bup/pyutil.h b/src/bup/pyutil.h
index 37f4a100b..93059e985 100644
--- a/src/bup/pyutil.h
+++ b/src/bup/pyutil.h
@@ -18,7 +18,7 @@ int bup_ullong_from_py(unsigned long long *x, PyObject *py, const char *name);
// success returns non-zero. On failure returns 0 and overflow will
// be non-zero if there was an overflow, otherwise a python exception
// will be pending.
-#define BUP_ASSIGN_PYLONG_TO_INTEGRAL (dest, pylong, overflow) \
+#define BUP_ASSIGN_PYLONG_TO_INTEGRAL(dest, pylong, overflow) \
({ \
int result = 0; \
int pending_overflow = 0; \
@@ -36,7 +36,7 @@ int bup_ullong_from_py(unsigned long long *x, PyObject *py, const char *name);
} else { \
const unsigned long long tmp = \
PyLong_AsUnsignedLongLong(pylong); \
- if (tmp == -1 && PyErr_Occurred() \
+ if (tmp == (unsigned long long) -1 && PyErr_Occurred() \
&& PyErr_ExceptionMatches(PyExc_OverflowError)) \
pending_overflow = 2; \
else { \
--
2.39.2

Reply all
Reply to author
Forward
0 new messages