make sure all segment file offsets fit into uint32, fixes #3592

C code and the repo index use uint32 type for segment file offsets,
so when opening a repo and the config max_segment_size is too big,
fail early.

Also disallow setting a too big value via "borg config".

(cherry picked from commit 0e0e6da585)
This commit is contained in:
Thomas Waldmann 2018-03-03 00:17:40 +01:00
parent e96730ac24
commit 1db42a58a5
3 changed files with 12 additions and 0 deletions

View file

@ -1729,6 +1729,9 @@ class Archiver:
int(value)
except ValueError:
raise ValueError('Invalid value') from None
if name == 'max_segment_size':
if int(value) >= MAX_SEGMENT_SIZE_LIMIT:
raise ValueError('Invalid value: max_segment_size >= %d' % MAX_SEGMENT_SIZE_LIMIT)
elif name in ['additional_free_space', ]:
if check_value:
try:

View file

@ -36,6 +36,9 @@ MAX_DATA_SIZE = 20971479
MAX_OBJECT_SIZE = MAX_DATA_SIZE + 41 # see LoggedIO.put_header_fmt.size assertion in repository module
assert MAX_OBJECT_SIZE == 20 * 1024 * 1024
# repo config max_segment_size value must be below this limit to stay within uint32 offsets:
MAX_SEGMENT_SIZE_LIMIT = 2 ** 32 - MAX_OBJECT_SIZE
# borg.remote read() buffer size
BUFSIZE = 10 * 1024 * 1024

View file

@ -122,6 +122,9 @@ class Repository:
class InvalidRepository(Error):
"""{} is not a valid repository. Check repo config."""
class InvalidRepositoryConfig(Error):
"""{} does not have a valid configuration. Check repo config [{}]."""
class AtticRepository(Error):
"""Attic repository detected. Please run "borg upgrade {}"."""
@ -383,6 +386,9 @@ class Repository:
self.close()
raise self.InvalidRepository(path)
self.max_segment_size = self.config.getint('repository', 'max_segment_size')
if self.max_segment_size >= MAX_SEGMENT_SIZE_LIMIT:
self.close()
raise self.InvalidRepositoryConfig(path, 'max_segment_size >= %d' % MAX_SEGMENT_SIZE_LIMIT) # issue 3592
self.segments_per_dir = self.config.getint('repository', 'segments_per_dir')
self.additional_free_space = parse_file_size(self.config.get('repository', 'additional_free_space', fallback=0))
# append_only can be set in the constructor