[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#800627: marked as done (linux: fs/isofs/util.c iso_date() will map years >= 2028 to 1970)



Your message dated Sun, 9 May 2021 15:39:40 +0200
with message-id <YJfmHFoJBedoo2hF@eldamar.lan>
and subject line Re: Bug#800627: linux: fs/isofs/util.c iso_date() will map years >= 2028 to 1970
has caused the Debian Bug report #800627,
regarding linux: fs/isofs/util.c iso_date() will map years >= 2028 to 1970
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
800627: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=800627
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: linux
Version: 4.1.6
Severity: normal

Dear Maintainer,

as the title says, we have 12 years left until timestamps
of newly created ISOs will begin to collapse.
Glimpse of future (assuming you have a file "/bin/true"):

  xorriso -outdev test.iso \
          -blank as_needed \
          -map /bin/true /victim \
          -alter_date m 'Oct 01 22:06:12 2030' /victim --

  mount -o loop test.iso /mnt/iso

  ls -l /mnt/iso/victim

shows something like

  -rwxr-xr-x 1 root root 27080 Jan  1  1970 /mnt/iso/victim


The cause is a signedness issue in fs/isofs/util.c, function iso_date()

  int iso_date(char * p, int flag)
  {
          int year, ...;
          ...
          year = p[0];
          ...
          if (year < 0) {
                  crtime = 0;
          } else {
                  ...
          }
          return crtime;
  }

ECMA-119 9.1.5 and 7.1.1 specify byte p[0] as unsigned 8 bit
value counting the years since 1900. Signed p[0] will be less
than zero with unsigned value 128 = 2028.

If there was not the problem in year 2028, the next one would
appear in 2038 when seconds since 1970 exceed 2 exp 31 - 1.
Then the signed 32 bit return value of iso_date() will roll over
and throw us back to year 1901.

A minimal remedy (up to 2038) would be:

  -         year = p[0];
  +         year = isonum_711(p + 0);


I am now testing a candidate which is hopefully ready for up to
year 2156, when the 8 bit counter of ISO 9660 rolls over
(with changed return type declared in fs/isofs/isofs.h):
--------------------------------------------------------------------

time64_t iso_date(char * p, int flag)
{
	unsigned int year, month, day, hour, minute, second;
	int tz;
	time64_t crtime;

	year = isonum_711(p + 0);
	month = isonum_711(p + 1);
	if (month > 12) month = 12;
	day = isonum_711(p + 2);
	if (day > 31) day = 31;
	hour = isonum_711(p + 3);
	if (hour > 23) hour = 23;
	minute = isonum_711(p + 4);
	if (minute > 59) minute = 59;
	second = isonum_711(p + 5);
	if (second > 59) second = 59;
	if (flag == 0)
		tz = isonum_712(p + 6);  /* High sierra has no time zone */
	else
		tz = 0;

	crtime = mktime64(year+1900, month, day, hour, minute, second);

	/* sign extend */
	if (tz & 0x80)
		tz |= (-1 << 8);

	/*
	 * The timezone offset is unreliable on some disks,
	 ...
	 * Thanks to kuhlmav@elec.canterbury.ac.nz (Volker Kuhlmann)
	 * for pointing out the sign error.
	 */
	if (-52 <= tz && tz <= 52)
		crtime -= tz * 15 * 60;

	return crtime;
}

--------------------------------------------------------------------

It can say dates like

  -rwxr-xr-x 1 root root 27080 Oct  4  2144 victim


Have a nice day :)

Thomas


-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.1.6 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

--- End Message ---
--- Begin Message ---
Source: linux
Source-Version: 4.14.7-1

On Thu, Oct 01, 2015 at 10:42:10PM +0200, Thomas Schmitt wrote:
> 
> Package: linux
> Version: 4.1.6
> Severity: normal
> 
> Dear Maintainer,
> 
> as the title says, we have 12 years left until timestamps
> of newly created ISOs will begin to collapse.
> Glimpse of future (assuming you have a file "/bin/true"):
> 
>   xorriso -outdev test.iso \
>           -blank as_needed \
>           -map /bin/true /victim \
>           -alter_date m 'Oct 01 22:06:12 2030' /victim --
> 
>   mount -o loop test.iso /mnt/iso
> 
>   ls -l /mnt/iso/victim
> 
> shows something like
> 
>   -rwxr-xr-x 1 root root 27080 Jan  1  1970 /mnt/iso/victim
> 
> 
> The cause is a signedness issue in fs/isofs/util.c, function iso_date()
> 
>   int iso_date(char * p, int flag)
>   {
>           int year, ...;
>           ...
>           year = p[0];
>           ...
>           if (year < 0) {
>                   crtime = 0;
>           } else {
>                   ...
>           }
>           return crtime;
>   }
> 
> ECMA-119 9.1.5 and 7.1.1 specify byte p[0] as unsigned 8 bit
> value counting the years since 1900. Signed p[0] will be less
> than zero with unsigned value 128 = 2028.
> 
> If there was not the problem in year 2028, the next one would
> appear in 2038 when seconds since 1970 exceed 2 exp 31 - 1.
> Then the signed 32 bit return value of iso_date() will roll over
> and throw us back to year 1901.
> 
> A minimal remedy (up to 2038) would be:
> 
>   -         year = p[0];
>   +         year = isonum_711(p + 0);
> 
> 
> I am now testing a candidate which is hopefully ready for up to
> year 2156, when the 8 bit counter of ISO 9660 rolls over
> (with changed return type declared in fs/isofs/isofs.h):
> --------------------------------------------------------------------
> 
> time64_t iso_date(char * p, int flag)
> {
> 	unsigned int year, month, day, hour, minute, second;
> 	int tz;
> 	time64_t crtime;
> 
> 	year = isonum_711(p + 0);
> 	month = isonum_711(p + 1);
> 	if (month > 12) month = 12;
> 	day = isonum_711(p + 2);
> 	if (day > 31) day = 31;
> 	hour = isonum_711(p + 3);
> 	if (hour > 23) hour = 23;
> 	minute = isonum_711(p + 4);
> 	if (minute > 59) minute = 59;
> 	second = isonum_711(p + 5);
> 	if (second > 59) second = 59;
> 	if (flag == 0)
> 		tz = isonum_712(p + 6);  /* High sierra has no time zone */
> 	else
> 		tz = 0;
> 
> 	crtime = mktime64(year+1900, month, day, hour, minute, second);
> 
> 	/* sign extend */
> 	if (tz & 0x80)
> 		tz |= (-1 << 8);
> 
> 	/*
> 	 * The timezone offset is unreliable on some disks,
> 	 ...
> 	 * Thanks to kuhlmav@elec.canterbury.ac.nz (Volker Kuhlmann)
> 	 * for pointing out the sign error.
> 	 */
> 	if (-52 <= tz && tz <= 52)
> 		crtime -= tz * 15 * 60;
> 
> 	return crtime;
> }
> 
> --------------------------------------------------------------------
> 
> It can say dates like
> 
>   -rwxr-xr-x 1 root root 27080 Oct  4  2144 victim
> 
> 
> Have a nice day :)

This has been fixed upstream with 34be4dbf87fc ("isofs: fix timestamps
beyond 2027") which was backported to various table series.

Regards,
Salvatore

--- End Message ---

Reply to: