infra: protect lamport clock against illegal future values

This commit is contained in:
Thomas Schoebel-Theuer 2017-12-13 22:11:27 +01:00 committed by Thomas Schoebel-Theuer
parent 178d041f71
commit e1426525cd
4 changed files with 43 additions and 0 deletions

View File

@ -58,6 +58,8 @@ void set_lamport(struct timespec *old)
{
int diff;
protect_timespec(old);
down(&lamport_sem);
diff = timespec_compare(old, &lamport_now);
@ -69,3 +71,27 @@ void set_lamport(struct timespec *old)
up(&lamport_sem);
}
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;
}

View File

@ -29,4 +29,10 @@
extern void get_lamport(struct timespec *now);
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

View File

@ -321,6 +321,7 @@ struct ctl_table mars_table[] = {
.mode = 0400,
.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_debug_messages", brick_say_debug, 0600),
INT_ENTRY("show_statistics_global", global_show_statist, 0600),

View File

@ -1039,6 +1039,16 @@ int get_inode(char *newpath, struct mars_dent *dent)
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->new_stat, &tmp, sizeof(dent->new_stat));