summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Thode <prometheanfire@gentoo.org>2013-08-13 16:07:36 +0000
committerMatt Thode <prometheanfire@gentoo.org>2013-08-13 16:07:36 +0000
commitc096bb7ba8fdf961f8f1539bb454f00251d23c34 (patch)
tree921a529ca5fe97d3b81c2191d82c789c6baab9c4 /sys-cluster
parentadding hacking as it is needed for testing support for sys-cluster/swift (diff)
downloadhistorical-c096bb7ba8fdf961f8f1539bb454f00251d23c34.tar.gz
historical-c096bb7ba8fdf961f8f1539bb454f00251d23c34.tar.bz2
historical-c096bb7ba8fdf961f8f1539bb454f00251d23c34.zip
fixing bug 480198 for CVE-2013-4155 for sys-cluster/swift
Package-Manager: portage-2.1.12.2/cvs/Linux x86_64 Manifest-Sign-Key: 0x2471EB3E40AC5AC3
Diffstat (limited to 'sys-cluster')
-rw-r--r--sys-cluster/swift/ChangeLog10
-rw-r--r--sys-cluster/swift/Manifest35
-rw-r--r--sys-cluster/swift/files/CVE-2013-4155-grizzly.patch419
-rw-r--r--sys-cluster/swift/swift-1.8.0-r3.ebuild (renamed from sys-cluster/swift/swift-1.8.0-r2.ebuild)3
-rw-r--r--sys-cluster/swift/swift-1.9.1.ebuild (renamed from sys-cluster/swift/swift-1.9.0.ebuild)13
5 files changed, 454 insertions, 26 deletions
diff --git a/sys-cluster/swift/ChangeLog b/sys-cluster/swift/ChangeLog
index 43c35aa36110..cc2adb7dd0cf 100644
--- a/sys-cluster/swift/ChangeLog
+++ b/sys-cluster/swift/ChangeLog
@@ -1,6 +1,14 @@
# ChangeLog for sys-cluster/swift
# Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/ChangeLog,v 1.11 2013/08/02 19:02:15 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/ChangeLog,v 1.12 2013/08/13 16:07:23 prometheanfire Exp $
+
+*swift-1.9.1 (13 Aug 2013)
+*swift-1.8.0-r3 (13 Aug 2013)
+
+ 13 Aug 2013; Matthew Thode <prometheanfire@gentoo.org>
+ +files/CVE-2013-4155-grizzly.patch, +swift-1.8.0-r3.ebuild,
+ +swift-1.9.1.ebuild, -swift-1.8.0-r2.ebuild, -swift-1.9.0.ebuild:
+ fixing bug 480198 for CVE-2013-4155 for sys-cluster/swift
*swift-2013.1.9999 (02 Aug 2013)
diff --git a/sys-cluster/swift/Manifest b/sys-cluster/swift/Manifest
index 435f0918744a..4cd5e0cf194e 100644
--- a/sys-cluster/swift/Manifest
+++ b/sys-cluster/swift/Manifest
@@ -2,32 +2,33 @@
Hash: SHA256
AUX CVE-2013-2161.patch 664 SHA256 728949effcf3669658bb8017f89b1a3a6ed481cc74d2f2c8e4bb235ccde24ba6 SHA512 ac95d6cf50209ffcec48ad16ca730816d5891b4adc2f110bab5974c0d31f3062cb0cc5552f8440b602eb88ed15c78faa30afa9c58c00e05abf2714b5503a7cfd WHIRLPOOL 92db329e49df48745b6401b2fb64963f8548a29dcd530f3449cfe7fa1c38ae05e61fc05bf2250e73c85b295aba4362745faa58c458b5ed80ccce3ea0f0467e7b
+AUX CVE-2013-4155-grizzly.patch 20586 SHA256 04870c36826c217266f4cca746f98dbe48f49dfb0ba500407565cfce6fd1c9d6 SHA512 ebb35c9ccd96c1d9cfbfe94d3534c0d3e68048ad5ebee632d99000c44ea29a187a99f273d42357d63c43d6f3ed6608f1a78e99a5f3cdbcbce3ee26b728779cb4 WHIRLPOOL a4454469700375bdfdfa874c9795bb2fe92a6de6a44e45241b69f848ff5770c2095c6de9830cf7397346fcebc2db623c694148d47bec20f81d4d2e7e29221863
AUX swift-account.initd 995 SHA256 f1d4594504b53de480abc69ccb72d37e002ad85118b9d90df12bfda42f4b5faa SHA512 93fcd08508f3efd4d1a75aa51c20b256a0f8c34f9b6ee27501d14376efd7a55e28ffd20fbf91b6406883603fc145e80c39d714b6eaa168fbf4a8c5be7ea63368 WHIRLPOOL ff3c69ad4801d742082dbe7131330b2fb154d1b30c8abfd688234a9f955515c9a1ffceb0ced432b1dd81d375e32e8416fa64b9d45eb199af4cc0ba3aa3c87e1a
AUX swift-container.initd 1007 SHA256 aba09a5e3396f79c5e49a258c283d37652e182ac62ef8952618ad32b4df1db86 SHA512 1202212955a6a0836abee2c8a2190e359c910037c2f38dbf6874253b21c0739548d9f48c75e3333d0d73376e35c43866b8d0dc38990d4d3b99c04efaab2407c2 WHIRLPOOL d1dc6e468fdd3ab616a53b5357dad09ef089927347a59b95961e7e6b395eec43dedef059fed8eed06f8f324ff0ec7121023953156dcf2266e00dc947aeb8da98
AUX swift-object.initd 989 SHA256 19a252739dca026435b0a861eea10ff76c22a41ec71d94cc6ce3dddd70b5df58 SHA512 1982f2f76df5d279c51a0a2fd5619dd12a6899559761ac7c0013aa5e5098058430e1a8dcc7cf46d5081bd6dffa17e4223de9b6a85bea4cddaf495b3ca91bacc9 WHIRLPOOL d2a16db387e6d3ff3452854672b5a9c64f03f485d3ddf7e2e67aa51dcb4aa4ab80fd375158dac99943f6c52fefc233cce503be26617110765fc859d82d6b01ab
AUX swift-proxy.initd 1505 SHA256 8e1ee2051116e869f5e51de426d640c7f57278f1fc2681bd80ec9393fa834c92 SHA512 a030a5b8ceedb69f89fca93abdd08d9f527d2789ed9983f7cca616b4a318176f84913e1d01ed09d5a1a9e55bd0d697d501f5698ea5b3f8ccce7f76b95984dff1 WHIRLPOOL e8653ceb1e19fead4b0941d158661fe6e81d66c71f032aa1be7aa56dd839d43a82adb090a7e509142bfa9a341c49fdf82c8f86e3a9159be63b538b588cca6e66
DIST swift-1.8.0.tar.gz 556736 SHA256 613185473e0c6f11c77bdc6b65efee195303268117afd9024fee82ebde6ed8a3 SHA512 c7eb92b7b6c952633ccc519f0b9125d1f95db548885c3ccdeaf872f1729797dde1525bcd6f87a8b094cf54c256e472d8d2b11e52954391b1636dc3c966152d37 WHIRLPOOL af4a841829e1d3c2ba85fae97cd2364bb16697f7bccc32a5c419a15946950dc32c95fb86fab40b35ae96f8b3203e450e93c9b8806df265522ac67667ebf5a75a
-DIST swift-1.9.0.tar.gz 617393 SHA256 12f86404bde15192415badd60ed7528a47967b66c29ba7f671fe5189290c7b64 SHA512 fef5277dc494dd066ec6a9e5d063256bf61f240cf35338c47f902de67f61c9dc35bf388b378e8d586379e578e8c1d66e11a55f3387a64dda8b85af894eaf86cd WHIRLPOOL 2b8e98f09ebcbf9d6751f90c4d3e0e148a9a9f76602cde195483d65b573327e40972e60d0282bae1564b292c1015a68293ef3dd82677bfdbaaf69b19526773f7
-EBUILD swift-1.8.0-r2.ebuild 4001 SHA256 e4a5ada179f773d1f27dab0cd15ee99fb8a890402661e1a4a3bfd082a788e8bf SHA512 e533a4f4306ba64c32a0c4a4ac66a000917ae968d0ae4820f5507807c65fb93c86032f0243af8e94b346a60c3d59e8086dd6eb0a32d3976a7e833ec0bb2b7f76 WHIRLPOOL 9ea0d5eb948d52b44af2450c7b0611309ac3f4e7aa01ea8a447b492352d52d9f4375e404db95947447b21bdb873e893cbc93d0e32df0cdb68a2df9e24a05e7e3
-EBUILD swift-1.9.0.ebuild 4243 SHA256 0bab26a5e5089d0850d761fdd3656d467dd68553a9149326530881194be292f9 SHA512 974c3eb746f57dab01380534fecdaa4336b70c03839831e997eb5c3169f7c77f4a01795eef3bb18725108281d3eb24aafc4b72a8faa03c4269f577f069a3ec40 WHIRLPOOL 8cca0519507b50cc024a16f2141f9dc0d7b3070ff7b0aded3fdc31499af7948364445b12391197fe6ffed4caca60aca184d5b698edf3aba29c9cc41382ba1ad1
+DIST swift-1.9.1.tar.gz 631902 SHA256 d95a8a158cc0dce4780ab462efca13b63be2485ee93a9dc70788b3372f264537 SHA512 ffc06ab87d2696360ded346aff0d29191b6921ab7d3eed35107dc6d8a9bb163b87eebbce4f2521a31df318b0d38e19ceaa2b25f2f066dffb601f9507121b6382 WHIRLPOOL 6fe37fe01589e6c1c82f1e743c001511c2fff402c7731070515d05a3a59192e0069938857752d441b2729e04db3f0cbe9147c32393d33f6dd6583e49b732cdb9
+EBUILD swift-1.8.0-r3.ebuild 4044 SHA256 6f7d60aeb80e9e50706171c4adbf449769f5b16cb9ab00487a81c5a806acf142 SHA512 3b2745c075b194f5e96b71c3ab845a9ebefffc7bcc818a2165e03e37a14e9f1d8c6c714011e4d512950eed1fd59df4be49b295d1f89e206d3fa5a83de133ae85 WHIRLPOOL 4b540f307c301291c33a6489414bbc1647aece3021dec2df2f5fa2eeb07235e000e553c8bfe56aff4f7bf46de86370502a61be9da3384953a3f8c2c74349dbd4
+EBUILD swift-1.9.1.ebuild 4205 SHA256 8ad365cf33cc55416bc886764d1515de93935495abf71d83e5140f5eb8c3b398 SHA512 fa81f338a530ce6b4d2cfe4cf0dce366770ead58b54fb1dee8d49ce6fa55d0d91800ed72919f89d4359ed55628058a09f73e8a2b42d6804aa14112318c9772fe WHIRLPOOL 468d34660d706362550e8ce04715bf15d676d5823a3cb0afaf0ff21123c09423686a8d54c5679e70b8f2a98f95ca578fbca97ef905fed7810ef4d98dfbbdf21a
EBUILD swift-2013.1.9999.ebuild 3940 SHA256 296aab83be17c2cfbd8adfc4bea57070bbde6e943c9bab540c643f6eb4c5f6e0 SHA512 ada463ece6038340c86904e520ab49b0066ab1bc4b194aaadb8c8453bdb9d8ae9a62d41e3e22f8da31cefa12690539b568b3a36fd50088ba85f4df0f391983a0 WHIRLPOOL 2f5efa1bd18199f02c1c66f1279ee13fb4a49af264a7bf35d8175cd01b054e9f3d45618c6632245f73f7a252ec200f3ba89f7d711c977765739fde3416fa3750
EBUILD swift-9999.ebuild 4028 SHA256 62e3b6bcf8a32ff6a77bca329678d4c70109f7bbfaf2054377a0fd5247eb2cc9 SHA512 b28ab173b140766699b228d0d633330a539bee5ffad4209aab214e79cf193eebb98c9d7a40589a5142524b26eb2893df55548bc79c7c1db79ddfb32a70557f34 WHIRLPOOL 866e3b6a0b805c4e769a4712483c23472254c149cbb0564667885f76fb3af919ca70474a4a9b3adfee9f8c6d8ac1f6ae162163ef990d31597cb3eb84c06c0eca
-MISC ChangeLog 2452 SHA256 8aa9051e84a40354da615613ab8adaba068b78b4b26b7f6f1f0f36d46ee9c1c5 SHA512 aaba33b2593cb4ca4fb25894ccfd5ac8b18008c5aaa431c724f904deed4276db7aaa174b7f58c49ec9867175275bbee2deb9077e2cec71389891f39092beabf5 WHIRLPOOL 2e7c2014b797a8ad05bed7f135b2cb5635833251b07427015f390b7f75361b3dec156b4523a2ba337fa3329126934439418399ef9e76d358dab8c278c9df710d
+MISC ChangeLog 2758 SHA256 c688983a2dc415ea36693b045bc50ceb0237339839bfbed0552cbc853008f8cd SHA512 70308d5b56f5cdabb4d2bb9d0e97afab7c8e7ff7d2c28e228157087213cd1c8a8dcea87b3f45c772b4bc783ea5cba97646186b47b68fb8f0398690061cc08de5 WHIRLPOOL 746355abb9c6f65975b843cc6d97b1005b5624f251ce8f04fb7e94139681501e8234f902b89613ec2f051d1d79e8b009003c67b12c9671651351e2629609b63b
MISC metadata.xml 694 SHA256 556c5cbba5f35997a06f1fb8225937b4d10d6c42540ea6263a58e8bdc27df514 SHA512 c23f67ab88832263600ee73a99ea4298043b11d397ea3375cd99e057af1d4d3dff397f510da1d5d6abb9b16cf6bca53c3fca0ea28c80627970a3da8f7076360d WHIRLPOOL f75febd6cc17191e3dab0dbe9a05f02c5bed3999549ae268968b39fc1fe0ccb62a47d881cd412bc14e67f5320a9fabb6d177359b936a62e219fe8362a18805c6
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)
-iQIcBAEBCAAGBQJR/AJsAAoJECRx6z5ArFrDwNwP/i683l/q+2iNXmrzpYZI6LDG
-7vCYFnU4CyH4TT1T/LSSSnkxELvZatohX4j7jAmF9EcBa7UreimLfCMXMTazzWok
-4qcW5gwZmWAXNTm+NKQpoVtWTyMAXeuPk4WjgMRDifdXRZf7F+8zjNcVwouryuUa
-Rrb6G1V4HEnzdYHLdiE+aDZd4mavWC64nesXNjdmkac7QyxvlbdBjkUqeoxUSdiB
-KjyW8adq1Bee+GSqO7tiCNl6VkBr0m8bdxc1O0KwKRbHEBiHckJ5GlIECO2IFuRR
-DYmB+Iyo6+0xEanOX4cKXfzR9uMsjmx6klOCKP7XjvRkcs0UGiJ3z5hzvDx3EDxT
-NrI7QCv3b6YqIN1b1fBMhpMZbVZ7bJwe+LyZxpSEVba7bCrBz8LkM6s3mIbpKWEd
-wli4ilrdlj77/QX2VvEwbmK1VzLNS3ZMVQJPW/7fwOJf34d1g6IjSaI0pHbcNQ1u
-P680QcgIKQ5Keao/pC0GwLodv9iGTku8WChGIVTc7OzQkv22LeL2lfaMDSBBXJaR
-PbHZLu9/v42wyaKb8jd6D3jLd8oZbewJnCeUeKy9Je79EXg9Vb+h4H4erJwvwpye
-rGZZZsWMUFD9Ee0gOrhbgeVCmdQo83tbqud1GLfc8oVYofvUWp0KJRtCRAsz0v80
-Uzb7hUy9yhipQKUeMXVV
-=kEE4
+iQIcBAEBCAAGBQJSCln9AAoJECRx6z5ArFrDPoIQALNZwYxErHmGNioKEcNhSVAU
+kaxRzvg5Qf+mNIcbXsoLj+4WOJ+Cr5spF5hxAQ+Xp89qwC0quvSG330NZOH3GFc+
+p1Plrnem6WV82ICFinTbMv2aRBR88eH/NakieB/Qb7eE1cBamcevFzOzGBT1c60B
+N978sibfR/1kHI/gAzbU0Ggqi5awNzdwWwZZlZ4jyY1hxDnRJMKbzrYjyRQh690j
+NSGJkRMjXxFXgBjF9kWK90allBsscefflmwa4z/tixPxIpQM9f6BdcT2+eC4yezS
+m+gVDbNtI8EmXAytt4NtnLkekpy3XXhvJWff+/wLm5n+TzPiMlO71okiNhTCGblM
+aW+7vW7c9XbBoIQsGTyb+D/+IHrCtBaU6ct5Yqj+euxiQ7zSBpvy0OoQZecI8mAa
+pNezo2kp/mBYTLAE9PBZsJsc6T6qMfgiKkhGqLsBeMVdKuXGHFWlkeqcuk6zl4X6
+273ciPk8w6THe9xq1rV1km51SPkLpbOvpw7htjFYqhWbF/kYOJ+/xi9lEb/37Vaf
+ebQBt9o3wUzDBF9rQB22DBI07rj1bpRqDSDgFIN5c3ynxPVUTu9YI4fq7YOR5Q6x
+OLI2ICG8OHKxewa8CDIJJ7/4oE4J0LlOynznA0/KRFw7FR9RASx/pd7iAoni36Ui
+TYyq290ugcZGEuyDg3ag
+=01Nz
-----END PGP SIGNATURE-----
diff --git a/sys-cluster/swift/files/CVE-2013-4155-grizzly.patch b/sys-cluster/swift/files/CVE-2013-4155-grizzly.patch
new file mode 100644
index 000000000000..e5e3ba1bff49
--- /dev/null
+++ b/sys-cluster/swift/files/CVE-2013-4155-grizzly.patch
@@ -0,0 +1,419 @@
+From 1f4ec235cdfd8c868f2d6458532f9dc32c00b8ca Mon Sep 17 00:00:00 2001
+From: Peter Portante <peter.portante@redhat.com>
+Date: Fri, 26 Jul 2013 15:03:34 -0400
+Subject: [PATCH] Fix handling of DELETE obj reqs with old timestamp
+
+The DELETE object REST API was creating tombstone files with old
+timestamps, potentially filling up the disk, as well as sending
+container updates.
+
+Here we now make DELETEs with a request timestamp return a 409 (HTTP
+Conflict) if a data file exists with a newer timestamp, only creating
+tombstones if they have a newer timestamp.
+
+The key fix is to actually read the timestamp metadata from an
+existing tombstone file (thanks to Pete Zaitcev for catching this),
+and then only create tombstone files with newer timestamps.
+
+We also prevent PUT and POST operations using old timestamps as well.
+
+Change-Id: I631957029d17c6578bca5779367df5144ba01fc9
+Signed-off-by: Peter Portante <peter.portante@redhat.com>
+---
+ swift/obj/server.py | 58 +++++++------
+ test/unit/obj/test_server.py | 194 ++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 225 insertions(+), 27 deletions(-)
+
+diff --git a/swift/obj/server.py b/swift/obj/server.py
+index fc23ea2..f416162 100644
+--- a/swift/obj/server.py
++++ b/swift/obj/server.py
+@@ -46,7 +46,7 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, HTTPCreated, \
+ HTTPInternalServerError, HTTPNoContent, HTTPNotFound, HTTPNotModified, \
+ HTTPPreconditionFailed, HTTPRequestTimeout, HTTPUnprocessableEntity, \
+ HTTPClientDisconnect, HTTPMethodNotAllowed, Request, Response, UTC, \
+- HTTPInsufficientStorage, multi_range_iterator
++ HTTPInsufficientStorage, multi_range_iterator, HTTPConflict
+
+
+ DATADIR = 'objects'
+@@ -121,7 +121,6 @@ class DiskFile(object):
+ self.tmppath = None
+ self.logger = logger
+ self.metadata = {}
+- self.meta_file = None
+ self.data_file = None
+ self.fp = None
+ self.iter_etag = None
+@@ -133,15 +132,18 @@ class DiskFile(object):
+ if not os.path.exists(self.datadir):
+ return
+ files = sorted(os.listdir(self.datadir), reverse=True)
+- for file in files:
+- if file.endswith('.ts'):
+- self.data_file = self.meta_file = None
+- self.metadata = {'deleted': True}
+- return
+- if file.endswith('.meta') and not self.meta_file:
+- self.meta_file = os.path.join(self.datadir, file)
+- if file.endswith('.data') and not self.data_file:
+- self.data_file = os.path.join(self.datadir, file)
++ meta_file = None
++ for afile in files:
++ if afile.endswith('.ts'):
++ self.data_file = None
++ with open(os.path.join(self.datadir, afile)) as mfp:
++ self.metadata = read_metadata(mfp)
++ self.metadata['deleted'] = True
++ break
++ if afile.endswith('.meta') and not meta_file:
++ meta_file = os.path.join(self.datadir, afile)
++ if afile.endswith('.data') and not self.data_file:
++ self.data_file = os.path.join(self.datadir, afile)
+ break
+ if not self.data_file:
+ return
+@@ -149,8 +151,8 @@ class DiskFile(object):
+ self.metadata = read_metadata(self.fp)
+ if not keep_data_fp:
+ self.close(verify_file=False)
+- if self.meta_file:
+- with open(self.meta_file) as mfp:
++ if meta_file:
++ with open(meta_file) as mfp:
+ for key in self.metadata.keys():
+ if key.lower() not in DISALLOWED_HEADERS:
+ del self.metadata[key]
+@@ -594,6 +596,9 @@ class ObjectController(object):
+ except (DiskFileError, DiskFileNotExist):
+ file.quarantine()
+ return HTTPNotFound(request=request)
++ orig_timestamp = file.metadata.get('X-Timestamp', '0')
++ if orig_timestamp >= request.headers['x-timestamp']:
++ return HTTPConflict(request=request)
+ metadata = {'X-Timestamp': request.headers['x-timestamp']}
+ metadata.update(val for val in request.headers.iteritems()
+ if val[0].lower().startswith('x-object-meta-'))
+@@ -639,6 +644,8 @@ class ObjectController(object):
+ file = DiskFile(self.devices, device, partition, account, container,
+ obj, self.logger, disk_chunk_size=self.disk_chunk_size)
+ orig_timestamp = file.metadata.get('X-Timestamp')
++ if orig_timestamp and orig_timestamp >= request.headers['x-timestamp']:
++ return HTTPConflict(request=request)
+ upload_expiration = time.time() + self.max_upload_time
+ etag = md5()
+ upload_size = 0
+@@ -863,23 +870,26 @@ class ObjectController(object):
+ return HTTPPreconditionFailed(
+ request=request,
+ body='X-If-Delete-At and X-Delete-At do not match')
+- orig_timestamp = file.metadata.get('X-Timestamp')
+- if file.is_deleted() or file.is_expired():
+- response_class = HTTPNotFound
+- metadata = {
+- 'X-Timestamp': request.headers['X-Timestamp'], 'deleted': True,
+- }
+ old_delete_at = int(file.metadata.get('X-Delete-At') or 0)
+ if old_delete_at:
+ self.delete_at_update('DELETE', old_delete_at, account,
+ container, obj, request.headers, device)
+- file.put_metadata(metadata, tombstone=True)
+- file.unlinkold(metadata['X-Timestamp'])
+- if not orig_timestamp or \
+- orig_timestamp < request.headers['x-timestamp']:
++ orig_timestamp = file.metadata.get('X-Timestamp', 0)
++ req_timestamp = request.headers['X-Timestamp']
++ if file.is_deleted() or file.is_expired():
++ response_class = HTTPNotFound
++ else:
++ if orig_timestamp < req_timestamp:
++ response_class = HTTPNoContent
++ else:
++ response_class = HTTPConflict
++ if orig_timestamp < req_timestamp:
++ file.put_metadata({'X-Timestamp': req_timestamp},
++ tombstone=True)
++ file.unlinkold(req_timestamp)
+ self.container_update(
+ 'DELETE', account, container, obj, request.headers,
+- {'x-timestamp': metadata['X-Timestamp'],
++ {'x-timestamp': req_timestamp,
+ 'x-trans-id': request.headers.get('x-trans-id', '-')},
+ device)
+ resp = response_class(request=request)
+diff --git a/test/unit/obj/test_server.py b/test/unit/obj/test_server.py
+index 8ee266b..b354b97 100755
+--- a/test/unit/obj/test_server.py
++++ b/test/unit/obj/test_server.py
+@@ -509,6 +509,41 @@ class TestObjectController(unittest.TestCase):
+ "X-Object-Meta-3" in resp.headers)
+ self.assertEquals(resp.headers['Content-Type'], 'application/x-test')
+
++ def test_POST_old_timestamp(self):
++ ts = time()
++ timestamp = normalize_timestamp(ts)
++ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
++ headers={'X-Timestamp': timestamp,
++ 'Content-Type': 'application/x-test',
++ 'X-Object-Meta-1': 'One',
++ 'X-Object-Meta-Two': 'Two'})
++ req.body = 'VERIFY'
++ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 201)
++
++ # Same timestamp should result in 409
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'POST'},
++ headers={'X-Timestamp': timestamp,
++ 'X-Object-Meta-3': 'Three',
++ 'X-Object-Meta-4': 'Four',
++ 'Content-Encoding': 'gzip',
++ 'Content-Type': 'application/x-test'})
++ resp = self.object_controller.POST(req)
++ self.assertEquals(resp.status_int, 409)
++
++ # Earlier timestamp should result in 409
++ timestamp = normalize_timestamp(ts - 1)
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'POST'},
++ headers={'X-Timestamp': timestamp,
++ 'X-Object-Meta-5': 'Five',
++ 'X-Object-Meta-6': 'Six',
++ 'Content-Encoding': 'gzip',
++ 'Content-Type': 'application/x-test'})
++ resp = self.object_controller.POST(req)
++ self.assertEquals(resp.status_int, 409)
++
+ def test_POST_not_exist(self):
+ timestamp = normalize_timestamp(time())
+ req = Request.blank('/sda1/p/a/c/fail',
+@@ -555,11 +590,15 @@ class TestObjectController(unittest.TestCase):
+
+ old_http_connect = object_server.http_connect
+ try:
+- timestamp = normalize_timestamp(time())
++ ts = time()
++ timestamp = normalize_timestamp(ts)
+ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD':
+ 'POST'}, headers={'X-Timestamp': timestamp, 'Content-Type':
+ 'text/plain', 'Content-Length': '0'})
+ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 201)
++
++ timestamp = normalize_timestamp(ts + 1)
+ req = Request.blank('/sda1/p/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
+ headers={'X-Timestamp': timestamp,
+@@ -571,6 +610,8 @@ class TestObjectController(unittest.TestCase):
+ object_server.http_connect = mock_http_connect(202)
+ resp = self.object_controller.POST(req)
+ self.assertEquals(resp.status_int, 202)
++
++ timestamp = normalize_timestamp(ts + 2)
+ req = Request.blank('/sda1/p/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
+ headers={'X-Timestamp': timestamp,
+@@ -582,6 +623,8 @@ class TestObjectController(unittest.TestCase):
+ object_server.http_connect = mock_http_connect(202, with_exc=True)
+ resp = self.object_controller.POST(req)
+ self.assertEquals(resp.status_int, 202)
++
++ timestamp = normalize_timestamp(ts + 3)
+ req = Request.blank('/sda1/p/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
+ headers={'X-Timestamp': timestamp,
+@@ -718,6 +761,32 @@ class TestObjectController(unittest.TestCase):
+ 'name': '/a/c/o',
+ 'Content-Encoding': 'gzip'})
+
++ def test_PUT_old_timestamp(self):
++ ts = time()
++ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
++ headers={'X-Timestamp': normalize_timestamp(ts),
++ 'Content-Length': '6',
++ 'Content-Type': 'application/octet-stream'})
++ req.body = 'VERIFY'
++ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 201)
++
++ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
++ headers={'X-Timestamp': normalize_timestamp(ts),
++ 'Content-Type': 'text/plain',
++ 'Content-Encoding': 'gzip'})
++ req.body = 'VERIFY TWO'
++ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 409)
++
++ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
++ headers={'X-Timestamp': normalize_timestamp(ts - 1),
++ 'Content-Type': 'text/plain',
++ 'Content-Encoding': 'gzip'})
++ req.body = 'VERIFY THREE'
++ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 409)
++
+ def test_PUT_no_etag(self):
+ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ headers={'X-Timestamp': normalize_timestamp(time()),
+@@ -1306,12 +1375,32 @@ class TestObjectController(unittest.TestCase):
+ self.assertEquals(resp.status_int, 400)
+ # self.assertRaises(KeyError, self.object_controller.DELETE, req)
+
++ # The following should have created a tombstone file
+ timestamp = normalize_timestamp(time())
+ req = Request.blank('/sda1/p/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'},
+ headers={'X-Timestamp': timestamp})
+ resp = self.object_controller.DELETE(req)
+ self.assertEquals(resp.status_int, 404)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assert_(os.path.isfile(objfile))
++
++ # The following should *not* have created a tombstone file.
++ timestamp = normalize_timestamp(float(timestamp) - 1)
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'DELETE'},
++ headers={'X-Timestamp': timestamp})
++ resp = self.object_controller.DELETE(req)
++ self.assertEquals(resp.status_int, 404)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assertFalse(os.path.exists(objfile))
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
+
+ sleep(.00001)
+ timestamp = normalize_timestamp(time())
+@@ -1325,17 +1414,19 @@ class TestObjectController(unittest.TestCase):
+ resp = self.object_controller.PUT(req)
+ self.assertEquals(resp.status_int, 201)
+
++ # The following should *not* have created a tombstone file.
+ timestamp = normalize_timestamp(float(timestamp) - 1)
+ req = Request.blank('/sda1/p/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'},
+ headers={'X-Timestamp': timestamp})
+ resp = self.object_controller.DELETE(req)
+- self.assertEquals(resp.status_int, 204)
++ self.assertEquals(resp.status_int, 409)
+ objfile = os.path.join(self.testdir, 'sda1',
+ storage_directory(object_server.DATADIR, 'p',
+ hash_path('a', 'c', 'o')),
+ timestamp + '.ts')
+- self.assert_(os.path.isfile(objfile))
++ self.assertFalse(os.path.exists(objfile))
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
+
+ sleep(.00001)
+ timestamp = normalize_timestamp(time())
+@@ -1350,6 +1441,103 @@ class TestObjectController(unittest.TestCase):
+ timestamp + '.ts')
+ self.assert_(os.path.isfile(objfile))
+
++ def test_DELETE_container_updates(self):
++ # Test swift.object_server.ObjectController.DELETE and container
++ # updates, making sure container update is called in the correct
++ # state.
++ timestamp = normalize_timestamp(time())
++ req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
++ headers={
++ 'X-Timestamp': timestamp,
++ 'Content-Type': 'application/octet-stream',
++ 'Content-Length': '4',
++ })
++ req.body = 'test'
++ resp = self.object_controller.PUT(req)
++ self.assertEquals(resp.status_int, 201)
++
++ calls_made = [0]
++
++ def our_container_update(*args, **kwargs):
++ calls_made[0] += 1
++
++ orig_cu = self.object_controller.container_update
++ self.object_controller.container_update = our_container_update
++ try:
++ # The following request should return 409 (HTTP Conflict). A
++ # tombstone file should not have been created with this timestamp.
++ timestamp = normalize_timestamp(float(timestamp) - 1)
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'DELETE'},
++ headers={'X-Timestamp': timestamp})
++ resp = self.object_controller.DELETE(req)
++ self.assertEquals(resp.status_int, 409)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assertFalse(os.path.isfile(objfile))
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
++ self.assertEquals(0, calls_made[0])
++
++ # The following request should return 204, and the object should
++ # be truly deleted (container update is performed) because this
++ # timestamp is newer. A tombstone file should have been created
++ # with this timestamp.
++ sleep(.00001)
++ timestamp = normalize_timestamp(time())
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'DELETE'},
++ headers={'X-Timestamp': timestamp})
++ resp = self.object_controller.DELETE(req)
++ self.assertEquals(resp.status_int, 204)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assert_(os.path.isfile(objfile))
++ self.assertEquals(1, calls_made[0])
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
++
++ # The following request should return a 404, as the object should
++ # already have been deleted, but it should have also performed a
++ # container update because the timestamp is newer, and a tombstone
++ # file should also exist with this timestamp.
++ sleep(.00001)
++ timestamp = normalize_timestamp(time())
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'DELETE'},
++ headers={'X-Timestamp': timestamp})
++ resp = self.object_controller.DELETE(req)
++ self.assertEquals(resp.status_int, 404)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assert_(os.path.isfile(objfile))
++ self.assertEquals(2, calls_made[0])
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
++
++ # The following request should return a 404, as the object should
++ # already have been deleted, and it should not have performed a
++ # container update because the timestamp is older, or created a
++ # tombstone file with this timestamp.
++ timestamp = normalize_timestamp(float(timestamp) - 1)
++ req = Request.blank('/sda1/p/a/c/o',
++ environ={'REQUEST_METHOD': 'DELETE'},
++ headers={'X-Timestamp': timestamp})
++ resp = self.object_controller.DELETE(req)
++ self.assertEquals(resp.status_int, 404)
++ objfile = os.path.join(self.testdir, 'sda1',
++ storage_directory(object_server.DATADIR, 'p',
++ hash_path('a', 'c', 'o')),
++ timestamp + '.ts')
++ self.assertFalse(os.path.isfile(objfile))
++ self.assertEquals(2, calls_made[0])
++ self.assertEquals(len(os.listdir(os.path.dirname(objfile))), 1)
++ finally:
++ self.object_controller.container_update = orig_cu
++
+ def test_call(self):
+ """ Test swift.object_server.ObjectController.__call__ """
+ inbuf = StringIO()
+--
+1.8.1.5
+
diff --git a/sys-cluster/swift/swift-1.8.0-r2.ebuild b/sys-cluster/swift/swift-1.8.0-r3.ebuild
index da8d5c9aa99b..f65aa7008b42 100644
--- a/sys-cluster/swift/swift-1.8.0-r2.ebuild
+++ b/sys-cluster/swift/swift-1.8.0-r3.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/swift-1.8.0-r2.ebuild,v 1.1 2013/06/14 22:11:19 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/swift-1.8.0-r3.ebuild,v 1.1 2013/08/13 16:07:23 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -47,6 +47,7 @@ CONFIG_CHECK="~EXT3_FS_XATTR ~SQUASHFS_XATTR ~CIFS_XATTR ~JFFS2_FS_XATTR
PATCHES=(
"${FILESDIR}/CVE-2013-2161.patch"
+ "${FILESDIR}/CVE-2013-4155-grizzly.patch"
)
src_test () {
diff --git a/sys-cluster/swift/swift-1.9.0.ebuild b/sys-cluster/swift/swift-1.9.1.ebuild
index d8f79f0e5615..bfcc0a7384b4 100644
--- a/sys-cluster/swift/swift-1.9.0.ebuild
+++ b/sys-cluster/swift/swift-1.9.1.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/swift-1.9.0.ebuild,v 1.1 2013/07/02 14:34:42 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/swift/swift-1.9.1.ebuild,v 1.1 2013/08/13 16:07:23 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -22,9 +22,11 @@ DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
dev-python/nosexcover[${PYTHON_USEDEP}]
dev-python/openstack-nose-plugin[${PYTHON_USEDEP}]
dev-python/nosehtmloutput[${PYTHON_USEDEP}]
- =dev-python/pep8-1.4.5[${PYTHON_USEDEP}]
- >=dev-python/pyflakes-0.7.2[${PYTHON_USEDEP}]
- >=dev-python/flake8-2.0[${PYTHON_USEDEP}]
+ ~dev-python/pep8-1.4.5[${PYTHON_USEDEP}]
+ ~dev-python/pyflakes-0.7.2[${PYTHON_USEDEP}]
+ ~dev-python/flake8-2.0[${PYTHON_USEDEP}]
+ >=dev-python/hacking-0.5.6[${PYTHON_USEDEP}]
+ <dev-python/hacking-0.6[${PYTHON_USEDEP}]
>=dev-python/mock-0.8.0[${PYTHON_USEDEP}]
>=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}] )"
@@ -38,9 +40,6 @@ RDEPEND=">=dev-python/eventlet-0.9.15[${PYTHON_USEDEP}]
dev-python/python-swiftclient[${PYTHON_USEDEP}]
memcache? ( net-misc/memcached )
net-misc/rsync[xattr]"
-# dev-python/configobj[${PYTHON_USEDEP}]
-# >=dev-python/webob-1.0.8[${PYTHON_USEDEP}]
-# <dev-python/webob-1.3[${PYTHON_USEDEP}]
REQUIRED_USE="|| ( proxy account container object )"