librados: cap the IoCtxImpl::{aio_}*{write,append} buffer length

If the value of the len parameter is greater than UINT_MAX/2,
IoCtxImpl::aio_write, IoCtxImpl::aio_write_full, IoCtxImpl::aio_append,
IoCtxImpl::write, IoCtxImpl::append will fail with E2BIG.

IoCtxImpl::write_full is the exception because it does not have a
length argument to check.

For more information see 33501d2426

http://tracker.ceph.com/issues/9592 Fixes: #9592

Signed-off-by: Loic Dachary <loic-201408@dachary.org>
This commit is contained in:
Loic Dachary 2014-09-29 00:39:50 +02:00
parent becc1140ac
commit 5d1d9dba60
3 changed files with 27 additions and 0 deletions

View File

@ -408,6 +408,8 @@ int librados::IoCtxImpl::create(const object_t& oid, bool exclusive,
int librados::IoCtxImpl::write(const object_t& oid, bufferlist& bl,
size_t len, uint64_t off)
{
if (len > UINT_MAX/2)
return -E2BIG;
::ObjectOperation op;
prepare_assert_ops(&op);
bufferlist mybl;
@ -418,6 +420,8 @@ int librados::IoCtxImpl::write(const object_t& oid, bufferlist& bl,
int librados::IoCtxImpl::append(const object_t& oid, bufferlist& bl, size_t len)
{
if (len > UINT_MAX/2)
return -E2BIG;
::ObjectOperation op;
prepare_assert_ops(&op);
bufferlist mybl;
@ -646,6 +650,8 @@ int librados::IoCtxImpl::aio_write(const object_t &oid, AioCompletionImpl *c,
utime_t ut = ceph_clock_now(client->cct);
ldout(client->cct, 20) << "aio_write " << oid << " " << off << "~" << len << " snapc=" << snapc << " snap_seq=" << snap_seq << dendl;
if (len > UINT_MAX/2)
return -E2BIG;
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
@ -668,6 +674,8 @@ int librados::IoCtxImpl::aio_append(const object_t &oid, AioCompletionImpl *c,
{
utime_t ut = ceph_clock_now(client->cct);
if (len > UINT_MAX/2)
return -E2BIG;
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
@ -691,6 +699,8 @@ int librados::IoCtxImpl::aio_write_full(const object_t &oid,
{
utime_t ut = ceph_clock_now(client->cct);
if (bl.length() > UINT_MAX/2)
return -E2BIG;
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;

View File

@ -177,6 +177,18 @@ TEST(LibRadosAio, TooBig) {
my_completion, buf, UINT_MAX));
}
TEST(LibRadosAio, TooBigPP) {
AioTestDataPP test_data;
ASSERT_EQ("", test_data.init());
bufferlist bl;
AioCompletion *aio_completion = test_data.m_cluster.aio_create_completion(
(void*)&test_data, NULL, NULL);
ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_write("foo", aio_completion, bl, UINT_MAX, 0));
ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_append("foo", aio_completion, bl, UINT_MAX));
// ioctx.aio_write_full no way to overflow bl.length()
}
TEST(LibRadosAio, SimpleWrite) {
AioTestData test_data;
rados_completion_t my_completion;

View File

@ -32,6 +32,11 @@ TEST_F(LibRadosIo, TooBig) {
ASSERT_EQ(-E2BIG, rados_write(ioctx, "A", buf, UINT_MAX, 0));
ASSERT_EQ(-E2BIG, rados_append(ioctx, "A", buf, UINT_MAX));
ASSERT_EQ(-E2BIG, rados_write_full(ioctx, "A", buf, UINT_MAX));
IoCtx ioctx;
bufferlist bl;
ASSERT_EQ(-E2BIG, ioctx.write("foo", bl, UINT_MAX, 0));
ASSERT_EQ(-E2BIG, ioctx.append("foo", bl, UINT_MAX));
// ioctx.write_full no way to overflow bl.length()
}
TEST_F(LibRadosIo, ReadTimeout) {