From b88539964da53bbe641b3ac1dc650d4f648c465a Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Mon, 13 Sep 2021 17:38:17 +1000 Subject: [PATCH] Do not allow incorrect sized layers This is a partial revert of I70a7bb5f73d1dddc540e96529784bb8c9bb0b9e3 The off-by-one error turned out to come from our range response (I1fb1abf3c76ea8db7820caa90c97ddbf92997842). There are no clients we know of that send an incorrect size in the manifest; we should error if we see that. Revert the adding of layer sizes done with Id5b1c5726fbe046b2f9f2994bf34f5fd7ecd90de and replace it with a hard error. I have tested both docker and podman pushes against this change and both correctly set a size for each layer in the manifest per [1]. Although I can not replicate it, the missing sizes might have already been fixed upstream, or related to the aforementioned off-by-one response we were giving. [1] https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list-field-descriptions Change-Id: Ibe061171bfd8ab6043b491bbab933bf277f8e12b --- tools/conf.yaml | 5 ----- zuul_registry/main.py | 29 +++++++---------------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/tools/conf.yaml b/tools/conf.yaml index 5da6e70..b334253 100644 --- a/tools/conf.yaml +++ b/tools/conf.yaml @@ -21,8 +21,3 @@ registry: storage: driver: filesystem root: /tmp/storage - # Check the size of layers matches the size specified in the - # container manifest. Some versions of docker can push invalid - # manifests (and *also* don't care about a size mismatch when - # pulling); set this to false to ignore layer-size mismatches. - strict: true diff --git a/zuul_registry/main.py b/zuul_registry/main.py index ccb324d..aa936ab 100644 --- a/zuul_registry/main.py +++ b/zuul_registry/main.py @@ -323,38 +323,23 @@ class RegistryAPI: data['config']['size'] = size changed = True + # Validate layer sizes for layer in data['layers']: digest = layer['digest'] actual_size = self.storage.blob_size(namespace, digest) - - # As above, we may or may not have a size for layers. If - # this layer doesn't have a size, add it. if 'size' not in layer: - layer['size'] = actual_size - changed = True - continue - - # However, if we got a size, we validate it + msg = ('Client push error: layer %s missing size ' % digest) + raise cherrypy.HTTPError(400, msg) size = layer['size'] if size == actual_size: continue - msg = ("Manifest has invalid size for layer %s " "(size:%d actual:%d)" % (digest, size, actual_size)) self.log.error(msg) - # Docker pushes a manifest with sizes one byte larger - # than it actaully sends. We choose to ignore this. - # https://github.com/docker/for-linux/issues/1296 - if ('docker/' in request.headers.get('User-Agent', '') - and (actual_size + 1 == size)): - self.log.info("Fix docker layer size for %s" % digest) - layer['size'] = actual_size - changed = True - elif self.conf.get('strict', True): - # We don't delete layers here as they may be used by - # different images with valid manifests. Return an error to - # the client so it can try again. - raise cherrypy.HTTPError(400, msg) + # We don't delete layers here as they may be used by + # different images with valid manifests. Return an error to + # the client so it can try again. + raise cherrypy.HTTPError(400, msg) if changed: body = json.dumps(data).encode('utf8')