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
This commit is contained in:
parent
ce2fb31a72
commit
b88539964d
@ -21,8 +21,3 @@ registry:
|
|||||||
storage:
|
storage:
|
||||||
driver: filesystem
|
driver: filesystem
|
||||||
root: /tmp/storage
|
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
|
|
||||||
|
@ -323,34 +323,19 @@ class RegistryAPI:
|
|||||||
data['config']['size'] = size
|
data['config']['size'] = size
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
# Validate layer sizes
|
||||||
for layer in data['layers']:
|
for layer in data['layers']:
|
||||||
digest = layer['digest']
|
digest = layer['digest']
|
||||||
actual_size = self.storage.blob_size(namespace, 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:
|
if 'size' not in layer:
|
||||||
layer['size'] = actual_size
|
msg = ('Client push error: layer %s missing size ' % digest)
|
||||||
changed = True
|
raise cherrypy.HTTPError(400, msg)
|
||||||
continue
|
|
||||||
|
|
||||||
# However, if we got a size, we validate it
|
|
||||||
size = layer['size']
|
size = layer['size']
|
||||||
if size == actual_size:
|
if size == actual_size:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
msg = ("Manifest has invalid size for layer %s "
|
msg = ("Manifest has invalid size for layer %s "
|
||||||
"(size:%d actual:%d)" % (digest, size, actual_size))
|
"(size:%d actual:%d)" % (digest, size, actual_size))
|
||||||
self.log.error(msg)
|
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
|
# We don't delete layers here as they may be used by
|
||||||
# different images with valid manifests. Return an error to
|
# different images with valid manifests. Return an error to
|
||||||
# the client so it can try again.
|
# the client so it can try again.
|
||||||
|
Loading…
Reference in New Issue
Block a user