mirror of https://github.com/schoebel/mars
infra: protect lamport clock against illegal future values
This commit is contained in:
parent
178d041f71
commit
e1426525cd
|
@ -58,6 +58,8 @@ void set_lamport(struct timespec *old)
|
||||||
{
|
{
|
||||||
int diff;
|
int diff;
|
||||||
|
|
||||||
|
protect_timespec(old);
|
||||||
|
|
||||||
down(&lamport_sem);
|
down(&lamport_sem);
|
||||||
|
|
||||||
diff = timespec_compare(old, &lamport_now);
|
diff = timespec_compare(old, &lamport_now);
|
||||||
|
@ -69,3 +71,27 @@ void set_lamport(struct timespec *old)
|
||||||
up(&lamport_sem);
|
up(&lamport_sem);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(set_lamport);
|
EXPORT_SYMBOL_GPL(set_lamport);
|
||||||
|
|
||||||
|
|
||||||
|
/* Protect against illegal values, e.g. from currupt filesystems etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int max_lamport_future = 30 * 24 * 3600;
|
||||||
|
|
||||||
|
bool protect_timespec(struct timespec *check)
|
||||||
|
{
|
||||||
|
struct timespec limit = CURRENT_TIME;
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
limit.tv_sec += max_lamport_future;
|
||||||
|
if (unlikely(check->tv_sec >= limit.tv_sec)) {
|
||||||
|
down(&lamport_sem);
|
||||||
|
timespec_add_ns(&lamport_now, 1);
|
||||||
|
memcpy(check, &lamport_now, sizeof(*check));
|
||||||
|
if (unlikely(check->tv_sec > limit.tv_sec))
|
||||||
|
max_lamport_future += check->tv_sec - limit.tv_sec;
|
||||||
|
up(&lamport_sem);
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -29,4 +29,10 @@
|
||||||
extern void get_lamport(struct timespec *now);
|
extern void get_lamport(struct timespec *now);
|
||||||
extern void set_lamport(struct timespec *old);
|
extern void set_lamport(struct timespec *old);
|
||||||
|
|
||||||
|
/* Protect against illegal values, e.g. from currupt filesystems etc.
|
||||||
|
*/
|
||||||
|
extern int max_lamport_future;
|
||||||
|
|
||||||
|
extern bool protect_timespec(struct timespec *check);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -321,6 +321,7 @@ struct ctl_table mars_table[] = {
|
||||||
.mode = 0400,
|
.mode = 0400,
|
||||||
.proc_handler = &lamport_sysctl_handler,
|
.proc_handler = &lamport_sysctl_handler,
|
||||||
},
|
},
|
||||||
|
INT_ENTRY("max_lamport_future", max_lamport_future, 0600),
|
||||||
INT_ENTRY("show_log_messages", brick_say_logging, 0600),
|
INT_ENTRY("show_log_messages", brick_say_logging, 0600),
|
||||||
INT_ENTRY("show_debug_messages", brick_say_debug, 0600),
|
INT_ENTRY("show_debug_messages", brick_say_debug, 0600),
|
||||||
INT_ENTRY("show_statistics_global", global_show_statist, 0600),
|
INT_ENTRY("show_statistics_global", global_show_statist, 0600),
|
||||||
|
|
|
@ -1039,6 +1039,16 @@ int get_inode(char *newpath, struct mars_dent *dent)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Correct illegal timestamps */
|
||||||
|
if (unlikely(protect_timespec(&tmp.mtime)) &&
|
||||||
|
S_ISLNK(dent->new_stat.mode)) {
|
||||||
|
char *val = mars_readlink(newpath);
|
||||||
|
if (val) {
|
||||||
|
mars_symlink(val, newpath, &tmp.mtime, 0);
|
||||||
|
brick_string_free(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&dent->old_stat, &dent->new_stat, sizeof(dent->old_stat));
|
memcpy(&dent->old_stat, &dent->new_stat, sizeof(dent->old_stat));
|
||||||
memcpy(&dent->new_stat, &tmp, sizeof(dent->new_stat));
|
memcpy(&dent->new_stat, &tmp, sizeof(dent->new_stat));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue