mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
metadata: allow reading metadata with invalid creation_time
lvm2 till version 2.02.169 (commit78d004efa8
) was printing invalid creation_time argument into metadata on 32bit arch. However with commitba9820b142
we started to properly validate all input numbers and thus we refused to accept invalid metadata with 'garbage' string - but this results in the situation where metadata produced on older lvm2 on 32 bit architecture will become unreadable after upgrade. To fix this case - extend libdm parser in a way, that whenever we find error integer value, we also check if the parsed value is not for creation_time node and in this case we let the metadata pass through with made-up date 2018-05-24 (release date of 2.02.169).
This commit is contained in:
parent
1f7c9da554
commit
85dbcda150
@ -51,6 +51,8 @@ struct parser {
|
|||||||
|
|
||||||
struct dm_pool *mem;
|
struct dm_pool *mem;
|
||||||
int no_dup_node_check; /* whether to disable dup node checking */
|
int no_dup_node_check; /* whether to disable dup node checking */
|
||||||
|
const char *key; /* last obtained key */
|
||||||
|
unsigned ignored_creation_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_output {
|
struct config_output {
|
||||||
@ -176,7 +178,7 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
|
|||||||
/* TODO? if (start == end) return 1; */
|
/* TODO? if (start == end) return 1; */
|
||||||
|
|
||||||
struct parser *p;
|
struct parser *p;
|
||||||
if (!(p = dm_pool_alloc(cft->mem, sizeof(*p))))
|
if (!(p = dm_pool_zalloc(cft->mem, sizeof(*p))))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
p->mem = cft->mem;
|
p->mem = cft->mem;
|
||||||
@ -615,6 +617,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
|
|||||||
match(TOK_SECTION_E);
|
match(TOK_SECTION_E);
|
||||||
} else {
|
} else {
|
||||||
match(TOK_EQ);
|
match(TOK_EQ);
|
||||||
|
p->key = root->key;
|
||||||
if (!(value = _value(p)))
|
if (!(value = _value(p)))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
if (root->v)
|
if (root->v)
|
||||||
@ -682,9 +685,18 @@ static struct dm_config_value *_type(struct parser *p)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
|
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
|
||||||
if (errno) {
|
if (errno) {
|
||||||
|
if (errno == ERANGE && p->key &&
|
||||||
|
strcmp("creation_time", p->key) == 0) {
|
||||||
|
/* Due to a bug in some older 32bit builds (<2.02.169),
|
||||||
|
* lvm was able to produce invalid creation_time string */
|
||||||
|
v->v.i = 1527120000; /* Pick 2018-05-24 day instead */
|
||||||
|
if (!p->ignored_creation_time++)
|
||||||
|
log_warn("WARNING: Invalid creation_time found in metadata (repaired with next metadata update).");
|
||||||
|
} else {
|
||||||
log_error("Failed to read int token.");
|
log_error("Failed to read int token.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
match(TOK_INT);
|
match(TOK_INT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ struct parser {
|
|||||||
|
|
||||||
struct dm_pool *mem;
|
struct dm_pool *mem;
|
||||||
int no_dup_node_check; /* whether to disable dup node checking */
|
int no_dup_node_check; /* whether to disable dup node checking */
|
||||||
|
const char *key; /* last obtained key */
|
||||||
|
unsigned ignored_creation_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_output {
|
struct config_output {
|
||||||
@ -176,7 +178,7 @@ static int _do_dm_config_parse(struct dm_config_tree *cft, const char *start, co
|
|||||||
/* TODO? if (start == end) return 1; */
|
/* TODO? if (start == end) return 1; */
|
||||||
|
|
||||||
struct parser *p;
|
struct parser *p;
|
||||||
if (!(p = dm_pool_alloc(cft->mem, sizeof(*p))))
|
if (!(p = dm_pool_zalloc(cft->mem, sizeof(*p))))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
p->mem = cft->mem;
|
p->mem = cft->mem;
|
||||||
@ -615,6 +617,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
|
|||||||
match(TOK_SECTION_E);
|
match(TOK_SECTION_E);
|
||||||
} else {
|
} else {
|
||||||
match(TOK_EQ);
|
match(TOK_EQ);
|
||||||
|
p->key = root->key;
|
||||||
if (!(value = _value(p)))
|
if (!(value = _value(p)))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
if (root->v)
|
if (root->v)
|
||||||
@ -682,9 +685,18 @@ static struct dm_config_value *_type(struct parser *p)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
|
v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */
|
||||||
if (errno) {
|
if (errno) {
|
||||||
|
if (errno == ERANGE && p->key &&
|
||||||
|
strcmp("creation_time", p->key) == 0) {
|
||||||
|
/* Due to a bug in some older 32bit builds (<2.02.169),
|
||||||
|
* lvm was able to produce invalid creation_time string */
|
||||||
|
v->v.i = 1527120000; /* Pick 2018-05-24 day instead */
|
||||||
|
if (!p->ignored_creation_time++)
|
||||||
|
log_warn("WARNING: Invalid creation_time found in metadata (repaired with next metadata update).");
|
||||||
|
} else {
|
||||||
log_error("Failed to read int token.");
|
log_error("Failed to read int token.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
match(TOK_INT);
|
match(TOK_INT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user