Fix possible integer overflow in lchown and fchown functions. For issue1747858.

This commit is contained in:
Gregory P. Smith 2009-12-23 09:31:11 +00:00
parent ca2dc4798b
commit 9f12d468f4
2 changed files with 52 additions and 28 deletions

View File

@ -207,14 +207,8 @@ class PosixTester(unittest.TestCase):
if hasattr(posix, 'stat'): if hasattr(posix, 'stat'):
self.assertTrue(posix.stat(test_support.TESTFN)) self.assertTrue(posix.stat(test_support.TESTFN))
if hasattr(posix, 'chown'): def _test_all_chown_common(self, chown_func, first_param):
def test_chown(self): """Common code for chown, fchown and lchown tests."""
# raise an OSError if the file does not exist
os.unlink(test_support.TESTFN)
self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
# re-create the file
open(test_support.TESTFN, 'w').close()
if os.getuid() == 0: if os.getuid() == 0:
try: try:
# Many linux distros have a nfsnobody user as MAX_UID-2 # Many linux distros have a nfsnobody user as MAX_UID-2
@ -223,16 +217,45 @@ class PosixTester(unittest.TestCase):
# This part of the test only runs when run as root. # This part of the test only runs when run as root.
# Only scary people run their tests as root. # Only scary people run their tests as root.
ent = pwd.getpwnam('nfsnobody') ent = pwd.getpwnam('nfsnobody')
posix.chown(test_support.TESTFN, ent.pw_uid, ent.pw_gid) chown_func(first_param, ent.pw_uid, ent.pw_gid)
except KeyError: except KeyError:
pass pass
else: else:
# non-root cannot chown to root, raises OSError # non-root cannot chown to root, raises OSError
self.assertRaises(OSError, posix.chown, self.assertRaises(OSError, chown_func,
test_support.TESTFN, 0, 0) first_param, 0, 0)
# test a successful chown call # test a successful chown call
posix.chown(test_support.TESTFN, os.getuid(), os.getgid()) chown_func(first_param, os.getuid(), os.getgid())
@unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
def test_chown(self):
# raise an OSError if the file does not exist
os.unlink(test_support.TESTFN)
self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
# re-create the file
open(test_support.TESTFN, 'w').close()
self._test_all_chown_common(posix.chown, test_support.TESTFN)
@unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
def test_fchown(self):
os.unlink(test_support.TESTFN)
# re-create the file
test_file = open(test_support.TESTFN, 'w')
try:
fd = test_file.fileno()
self._test_all_chown_common(posix.fchown, fd)
finally:
test_file.close()
@unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
def test_lchown(self):
os.unlink(test_support.TESTFN)
# create a symlink
os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN)
self._test_all_chown_common(posix.lchown, test_support.TESTFN)
def test_chdir(self): def test_chdir(self):
if hasattr(posix, 'chdir'): if hasattr(posix, 'chdir'):

View File

@ -1910,9 +1910,10 @@ fd to the numeric uid and gid.");
static PyObject * static PyObject *
posix_fchown(PyObject *self, PyObject *args) posix_fchown(PyObject *self, PyObject *args)
{ {
int fd, uid, gid; int fd;
long uid, gid;
int res; int res;
if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
return NULL; return NULL;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = fchown(fd, (uid_t) uid, (gid_t) gid); res = fchown(fd, (uid_t) uid, (gid_t) gid);
@ -1933,9 +1934,9 @@ static PyObject *
posix_lchown(PyObject *self, PyObject *args) posix_lchown(PyObject *self, PyObject *args)
{ {
char *path = NULL; char *path = NULL;
int uid, gid; long uid, gid;
int res; int res;
if (!PyArg_ParseTuple(args, "etii:lchown", if (!PyArg_ParseTuple(args, "etll:lchown",
Py_FileSystemDefaultEncoding, &path, Py_FileSystemDefaultEncoding, &path,
&uid, &gid)) &uid, &gid))
return NULL; return NULL;