fs: Use 64-bit type for filesystem timestamp
Some filesystems nowadays use 64-bit types for timestamps. So, update grub_dirhook_info struct to use an grub_int64_t type to store mtime. This also updates the grub_unixtime2datetime() function to receive a 64-bit timestamp argument and do 64-bit-safe divisions. All the remaining conversion from 32-bit to 64-bit should be safe, as 32-bit to 64-bit attributions will be implicitly casted. The most critical part in the 32-bit to 64-bit conversion is in the function grub_unixtime2datetime() where it needs to deal with the 64-bit type. So, for that, the grub_divmod64() helper has been used. These changes enables the GRUB to support dates beyond y2038. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
af54062b54
commit
81f1962393
@ -641,7 +641,7 @@ grub_affs_label (grub_device_t device, char **label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_affs_mtime (grub_device_t device, grub_int32_t *t)
|
grub_affs_mtime (grub_device_t device, grub_int64_t *t)
|
||||||
{
|
{
|
||||||
struct grub_affs_data *data;
|
struct grub_affs_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|||||||
@ -1055,7 +1055,7 @@ grub_ext2_uuid (grub_device_t device, char **uuid)
|
|||||||
|
|
||||||
/* Get mtime. */
|
/* Get mtime. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
|
grub_ext2_mtime (grub_device_t device, grub_int64_t *tm)
|
||||||
{
|
{
|
||||||
struct grub_ext2_data *data;
|
struct grub_ext2_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|||||||
@ -737,7 +737,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||||||
* https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
|
* https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int32_t *nix) {
|
grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int64_t *nix) {
|
||||||
struct grub_datetime datetime = {
|
struct grub_datetime datetime = {
|
||||||
.year = (field >> 25) + 1980,
|
.year = (field >> 25) + 1980,
|
||||||
.month = (field & 0x01E00000) >> 21,
|
.month = (field & 0x01E00000) >> 21,
|
||||||
@ -891,7 +891,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||||||
* https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-107.pdf
|
* https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-107.pdf
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int32_t *nix) {
|
grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int64_t *nix) {
|
||||||
struct grub_datetime datetime = {
|
struct grub_datetime datetime = {
|
||||||
.year = (date >> 9) + 1980,
|
.year = (date >> 9) + 1980,
|
||||||
.month = (date & 0x01E0) >> 5,
|
.month = (date & 0x01E0) >> 5,
|
||||||
|
|||||||
@ -1374,7 +1374,7 @@ grub_hfs_label (grub_device_t device, char **label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
|
grub_hfs_mtime (grub_device_t device, grub_int64_t *tm)
|
||||||
{
|
{
|
||||||
struct grub_hfs_data *data;
|
struct grub_hfs_data *data;
|
||||||
|
|
||||||
|
|||||||
@ -1083,7 +1083,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
|||||||
|
|
||||||
/* Get mtime. */
|
/* Get mtime. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
|
grub_hfsplus_mtime (grub_device_t device, grub_int64_t *tm)
|
||||||
{
|
{
|
||||||
struct grub_hfsplus_data *data;
|
struct grub_hfsplus_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|||||||
@ -178,7 +178,7 @@ static grub_dl_t my_mod;
|
|||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
|
iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int64_t *nix)
|
||||||
{
|
{
|
||||||
struct grub_datetime datetime;
|
struct grub_datetime datetime;
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
|
iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int64_t *nix)
|
||||||
{
|
{
|
||||||
struct grub_datetime datetime;
|
struct grub_datetime datetime;
|
||||||
|
|
||||||
@ -1107,7 +1107,7 @@ grub_iso9660_uuid (grub_device_t device, char **uuid)
|
|||||||
|
|
||||||
/* Get writing time of filesystem. */
|
/* Get writing time of filesystem. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
|
grub_iso9660_mtime (grub_device_t device, grub_int64_t *timebuf)
|
||||||
{
|
{
|
||||||
struct grub_iso9660_data *data;
|
struct grub_iso9660_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|||||||
@ -1186,7 +1186,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid)
|
|||||||
|
|
||||||
/* Get mtime. */
|
/* Get mtime. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm)
|
grub_nilfs2_mtime (grub_device_t device, grub_int64_t * tm)
|
||||||
{
|
{
|
||||||
struct grub_nilfs2_data *data;
|
struct grub_nilfs2_data *data;
|
||||||
grub_disk_t disk = device->disk;
|
grub_disk_t disk = device->disk;
|
||||||
|
|||||||
@ -1003,7 +1003,7 @@ grub_squash_close (grub_file_t file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_squash_mtime (grub_device_t dev, grub_int32_t *tm)
|
grub_squash_mtime (grub_device_t dev, grub_int64_t *tm)
|
||||||
{
|
{
|
||||||
struct grub_squash_data *data = 0;
|
struct grub_squash_data *data = 0;
|
||||||
|
|
||||||
|
|||||||
@ -837,7 +837,7 @@ grub_ufs_uuid (grub_device_t device, char **uuid)
|
|||||||
|
|
||||||
/* Get mtime. */
|
/* Get mtime. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
|
grub_ufs_mtime (grub_device_t device, grub_int64_t *tm)
|
||||||
{
|
{
|
||||||
struct grub_ufs_data *data = 0;
|
struct grub_ufs_data *data = 0;
|
||||||
|
|
||||||
|
|||||||
@ -3771,7 +3771,7 @@ zfs_uuid (grub_device_t device, char **uuid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
zfs_mtime (grub_device_t device, grub_int32_t *mt)
|
zfs_mtime (grub_device_t device, grub_int64_t *mt)
|
||||||
{
|
{
|
||||||
struct grub_zfs_data *data;
|
struct grub_zfs_data *data;
|
||||||
grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
|
grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include <grub/datetime.h>
|
#include <grub/datetime.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
static const char *const grub_weekday_names[] =
|
static const char *const grub_weekday_names[] =
|
||||||
{
|
{
|
||||||
@ -60,7 +62,7 @@ grub_get_weekday_name (struct grub_datetime *datetime)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
|
grub_unixtime2datetime (grub_int64_t nix, struct grub_datetime *datetime)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
@ -73,11 +75,17 @@ grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
|
|||||||
unsigned days;
|
unsigned days;
|
||||||
/* Seconds into current day. */
|
/* Seconds into current day. */
|
||||||
unsigned secs_in_day;
|
unsigned secs_in_day;
|
||||||
|
|
||||||
/* Transform C divisions and modulos to mathematical ones */
|
/* Transform C divisions and modulos to mathematical ones */
|
||||||
if (nix < 0)
|
if (nix < 0)
|
||||||
days_epoch = -(((unsigned) (SECPERDAY-nix-1)) / SECPERDAY);
|
/*
|
||||||
|
* The result of division here shouldn't be larger than GRUB_INT_MAX.
|
||||||
|
* So, it's safe to store the result back in an int.
|
||||||
|
*/
|
||||||
|
days_epoch = -(grub_divmod64 (((grub_int64_t) (SECPERDAY) - nix - 1), SECPERDAY, NULL));
|
||||||
else
|
else
|
||||||
days_epoch = ((unsigned) nix) / SECPERDAY;
|
days_epoch = grub_divmod64 (nix, SECPERDAY, NULL);
|
||||||
|
|
||||||
secs_in_day = nix - days_epoch * SECPERDAY;
|
secs_in_day = nix - days_epoch * SECPERDAY;
|
||||||
days = days_epoch + 69 * DAYSPERYEAR + 17;
|
days = days_epoch + 69 * DAYSPERYEAR + 17;
|
||||||
|
|
||||||
|
|||||||
@ -468,7 +468,7 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface)
|
|||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
struct grub_net_bootp_packet *pack;
|
struct grub_net_bootp_packet *pack;
|
||||||
struct grub_datetime date;
|
struct grub_datetime date;
|
||||||
grub_int32_t t = 0;
|
grub_int64_t t = 0;
|
||||||
struct grub_net_buff *nb;
|
struct grub_net_buff *nb;
|
||||||
struct udphdr *udph;
|
struct udphdr *udph;
|
||||||
grub_net_network_level_address_t target;
|
grub_net_network_level_address_t target;
|
||||||
|
|||||||
@ -136,7 +136,7 @@ grub_normal_print_device_info (const char *name)
|
|||||||
}
|
}
|
||||||
if (fs->fs_mtime)
|
if (fs->fs_mtime)
|
||||||
{
|
{
|
||||||
grub_int32_t tm;
|
grub_int64_t tm;
|
||||||
struct grub_datetime datetime;
|
struct grub_datetime datetime;
|
||||||
(fs->fs_mtime) (dev, &tm);
|
(fs->fs_mtime) (dev, &tm);
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
|||||||
@ -32,7 +32,7 @@ static void
|
|||||||
sleep_test (void)
|
sleep_test (void)
|
||||||
{
|
{
|
||||||
struct grub_datetime st, en;
|
struct grub_datetime st, en;
|
||||||
grub_int32_t stu = 0, enu = 0;
|
grub_int64_t stu = 0, enu = 0;
|
||||||
int is_delayok;
|
int is_delayok;
|
||||||
grub_test_assert (!grub_get_datetime (&st), "Couldn't retrieve start time");
|
grub_test_assert (!grub_get_datetime (&st), "Couldn't retrieve start time");
|
||||||
grub_millisleep (10000);
|
grub_millisleep (10000);
|
||||||
@ -45,8 +45,7 @@ sleep_test (void)
|
|||||||
if (enu - stu >= 15 && enu - stu <= 17)
|
if (enu - stu >= 15 && enu - stu <= 17)
|
||||||
is_delayok = 1;
|
is_delayok = 1;
|
||||||
#endif
|
#endif
|
||||||
grub_test_assert (is_delayok, "Interval out of range: %d", enu-stu);
|
grub_test_assert (is_delayok, "Interval out of range: %" PRIdGRUB_INT64_T, enu - stu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_FUNCTIONAL_TEST (sleep_test, sleep_test);
|
GRUB_FUNCTIONAL_TEST (sleep_test, sleep_test);
|
||||||
|
|||||||
@ -48,11 +48,11 @@ grub_err_t grub_set_datetime (struct grub_datetime *datetime);
|
|||||||
int grub_get_weekday (struct grub_datetime *datetime);
|
int grub_get_weekday (struct grub_datetime *datetime);
|
||||||
const char *grub_get_weekday_name (struct grub_datetime *datetime);
|
const char *grub_get_weekday_name (struct grub_datetime *datetime);
|
||||||
|
|
||||||
void grub_unixtime2datetime (grub_int32_t nix,
|
void grub_unixtime2datetime (grub_int64_t nix,
|
||||||
struct grub_datetime *datetime);
|
struct grub_datetime *datetime);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix)
|
grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int64_t *nix)
|
||||||
{
|
{
|
||||||
grub_int32_t ret;
|
grub_int32_t ret;
|
||||||
int y4, ay;
|
int y4, ay;
|
||||||
|
|||||||
@ -39,7 +39,7 @@ struct grub_dirhook_info
|
|||||||
unsigned mtimeset:1;
|
unsigned mtimeset:1;
|
||||||
unsigned case_insensitive:1;
|
unsigned case_insensitive:1;
|
||||||
unsigned inodeset:1;
|
unsigned inodeset:1;
|
||||||
grub_int32_t mtime;
|
grub_int64_t mtime;
|
||||||
grub_uint64_t inode;
|
grub_uint64_t inode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ struct grub_fs
|
|||||||
grub_err_t (*fs_uuid) (grub_device_t device, char **uuid);
|
grub_err_t (*fs_uuid) (grub_device_t device, char **uuid);
|
||||||
|
|
||||||
/* Get writing time of filesystem. */
|
/* Get writing time of filesystem. */
|
||||||
grub_err_t (*fs_mtime) (grub_device_t device, grub_int32_t *timebuf);
|
grub_err_t (*fs_mtime) (grub_device_t device, grub_int64_t *timebuf);
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
/* Determine sectors available for embedding. */
|
/* Determine sectors available for embedding. */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user