[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-02 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 11:11 PM, Alexandre Belloni wrote:
> On 01/09/2022 22:33:46+0200, Arnd Bergmann wrote:
>> On Thu, Sep 1, 2022, at 6:02 PM, Russell King (Oracle) wrote:
>> > On Thu, Sep 01, 2022 at 05:48:01PM +0200, Arnd Bergmann wrote:
>> >
>> >> I think the systems that can send the timekeeping back into the early
>> >> 1900s (or at least after 1970) are fine, the problem is the systems
>> >> that can randomly send the timekeeping into the post-2038 future.
>> >
>> > I believe Armada 388 systems can do that - and since Armada 388 systems
>> > are involved in my connectivity, I would very much prefer it if someone
>> > doesn't patch stuff that causes them to explode when I decide to
>> > upgrade the kernel.
>> >
>> > (Yes, I've run into the broken systemd issue with them when the RTC
>> > was not correctly set on platform delivery.)
>> 
>> Ok, good to know. I wonder if this patch would be sufficient for
>> this particular driver:
>
> I'm pretty sure we don't want to play whack-a-mole with all the drivers,
> especially with those for RTCs that are available on both 32b and 64b
> systems.

If we want to address all drivers at the same time, this also affects
every architecture including x86: any 32-bit setup that relies on
RTC_HCTOSYS will break in 2038 unless we remove the INT_MAX hack,
but removing it everywhere immediately breaks setups that run
systemd when the RTC fails.

Note that this is not actually 32-bit specific, since the kernel
has no idea if it's running 32-bit or 64-bit userspace. I think we
are increasingly seeing users run 32-bit userland on arm64 and rv64
kernels as low-end SoCs are moving to 64-bit cores but remain
memory constrained.

>> diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
>> index cc542e6b1d5b..f2bbb8efed18 100644
>> --- a/drivers/rtc/rtc-armada38x.c
>> +++ b/drivers/rtc/rtc-armada38x.c
>> @@ -219,7 +219,7 @@ static int armada38x_rtc_read_time(struct device *dev, 
>> struct rtc_time *tm)
>>  time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
>>  spin_unlock_irqrestore(>lock, flags);
>>  
>> -rtc_time64_to_tm(time, tm);
>> +rtc_time64_to_tm((s32)time, tm);
>
> You may as well just clamp the value here, the RTC subsystem
> specifically considers a timestamp to be positive and this is why it is
> not affected by y2038 with 32bit second counters.

Do you mean clamping to a non-negative value? That would break
the 'start-time' trick that I suggested. As far as I can tell,
the rtc_device_get_offset() function should work correctly and
not apply any translation when start-year is unset, but use a
translated range when it is set. If all negative values are
capped in the armada38x driver, that would make anything
break that is in the wrong half of the translated range.

Arnd
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-01 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 6:02 PM, Russell King (Oracle) wrote:
> On Thu, Sep 01, 2022 at 05:48:01PM +0200, Arnd Bergmann wrote:
>
>> I think the systems that can send the timekeeping back into the early
>> 1900s (or at least after 1970) are fine, the problem is the systems
>> that can randomly send the timekeeping into the post-2038 future.
>
> I believe Armada 388 systems can do that - and since Armada 388 systems
> are involved in my connectivity, I would very much prefer it if someone
> doesn't patch stuff that causes them to explode when I decide to
> upgrade the kernel.
>
> (Yes, I've run into the broken systemd issue with them when the RTC
> was not correctly set on platform delivery.)

Ok, good to know. I wonder if this patch would be sufficient for
this particular driver:

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index cc542e6b1d5b..f2bbb8efed18 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -219,7 +219,7 @@ static int armada38x_rtc_read_time(struct device *dev, 
struct rtc_time *tm)
time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
spin_unlock_irqrestore(>lock, flags);
 
-   rtc_time64_to_tm(time, tm);
+   rtc_time64_to_tm((s32)time, tm);
 
return 0;
 }
@@ -541,7 +541,8 @@ static __init int armada38x_rtc_probe(struct 
platform_device *pdev)
rtc->data->update_mbus_timing(rtc);
 
rtc->rtc_dev->ops = _rtc_ops;
-   rtc->rtc_dev->range_max = U32_MAX;
+   rtc->rtc_dev->range_min = S32_MIN;
+   rtc->rtc_dev->range_max = S32_MAX;
 
return devm_rtc_register_device(rtc->rtc_dev);
 }

The effect of this is to interpret the RTC values as range
1902...2038 instead of 1970...2106, which should make
systemd not crash any more on random input, but have no
other side-effects within the 1970...2038 range.

Users that care about running systems beyond 2038 and
run a time64 userland can then set the wrap-around point
in DT e.g. to 2022...2156 using the 'start-year=<2022>;'
property, or any other value they like. If we can do the
equivalent for all RTC drivers that may suffer from the
same problem, the HCTOSYS hack for the S32_MAX value
can just get removed.

  Arnd

[I accidentally dropped Rainier from Cc, adding him back now. For
reference, the other mail are archived at
https://lore.kernel.org/linux-arm-kernel/cakyb531cyl8xrvrcrn30cc3xrgsd-1fzxues7o2lizqalj4...@mail.gmail.com/]
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-01 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 3:46 PM, Russell King (Oracle) wrote:
> On Thu, Sep 01, 2022 at 03:12:57PM +0200, Arnd Bergmann wrote:
>> Ah, I forgot that systemd actually needs it. So I guess there is
>> currently no way to use systemd on 32-bit machines that are
>> meant to survive 2038, regardless of whether systemd and glibc are
>> built with a 64-bit time_t or not, right?
>> 
>> Is there perhaps a way to change the logic in a way that
>> it does not depend on the current time but instead depends
>> on a property of the RTC device itself, so we make systems
>> break immediately instead of by surprise in 2038?
>
> Are you seriously suggesting to cause regressions on systems where
> the RTC can send the kernel's timekeeping back to the early 1900s,
> rather than printing a big fat warning message in the kernel log?

I think the systems that can send the timekeeping back into the early
1900s (or at least after 1970) are fine, the problem is the systems
that can randomly send the timekeeping into the post-2038 future.

What kind of warning would you suggest to print here? I don't see
how warning about broken hardware at every boot would help, since
there is no way for users to react to that warning. Similarly,
warning about a time_t value past 2038 does not help because
at that time one either has a bricked system (if using a systemd
with 32-bit time_t)  or it is actually 2038 and the system
reverts back to 1970.

What might work is to have all drivers for broken RTC devices
default to a 1902-2037 (or 1970-2037) date range to ensure
that only those devices are broken in 2038, but still allow
overriding the "start-year" property in DT for machines that
don't use the broken systemd.

  Arnd
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-01 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 3:57 PM, Alexandre Belloni wrote:
> On 01/09/2022 15:12:57+0200, Arnd Bergmann wrote:
>> As far as I remember, the workaround was only needed for
>> certain devices that may set the time to something after 2038
>> on a depleted battery, but other devices would have a better
>> failure case, right?
>> 
>
> Yes, this is the main cause, anything able to set the system time after
> 2038 with a 32bit userspace will cause that (and basically I think this
> is only hctosys). The issue is that many RTCs don't have a default value
> for the time registers after power failure. This is usually not an issue
> as there is also a bit allowing to detect whether the time is correct.
> note that this will also be an issue once we actually reach 2038 with a
> 32bit userspace.

The problem is that people are deploying systems already with the
expectation that they will survive y2038, and it is rather unlikely that
the developers that build these systems will be around to update the
systems anywhere close to that. glibc now has the 64-bit time_t support
(and musl has had it for a while), so even if you do unit tests on
your own software to check for bugs, you wouldn't necessarily run into
the issue unless you reboot the system with the RTC set to the future
as part of the testing.

In effect, whatever we will need in 2038, we also need to have today,
so the current code cannot remain unchanged, the question is just
about how to minimize the damage.

Is there any way to find out which RTC drivers are affected by this?

Arnd
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-01 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 2:49 PM, Alexandre Belloni wrote:
> On 01/09/2022 13:55:19+0200, Arnd Bergmann wrote:
>> 
>> The only reliable fix I can see would be to disable
>> CONFIG_RTC_HCTOSYS_DEVICE. I think this is Alexandre's plan
>> for the long run anyway, but I don't know if there has been any
>> progress in convincing distros to turn it off.
>> 
>
> This is still my plan but systemd mandates RTC_HCTOSYS and I couldn't
> convince Lennart otherwise.

Ah, I forgot that systemd actually needs it. So I guess there is
currently no way to use systemd on 32-bit machines that are
meant to survive 2038, regardless of whether systemd and glibc are
built with a 64-bit time_t or not, right?

Is there perhaps a way to change the logic in a way that
it does not depend on the current time but instead depends
on a property of the RTC device itself, so we make systems
break immediately instead of by surprise in 2038?

As far as I remember, the workaround was only needed for
certain devices that may set the time to something after 2038
on a depleted battery, but other devices would have a better
failure case, right?

   Arnd
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: RTC hctosys disabled for 32-bit systems

2022-09-01 Thread Arnd Bergmann
On Thu, Sep 1, 2022, at 1:31 PM, Reinier Kuipers wrote:
>
> I'm working to fix the y2038 issue for an existing sama5d3-based
> product. This involves updating the kernel and glibc to appropriate
> versions (5.10 and 2.35.1 respectively) and I got things running up to
> a state where, from userspace, both date and hwclock commands have no
> issue accepting dates beyond 2038. However, even with the RTC_HCTOSYS
> and RTC_HCTOSYS_DEVICE options configured correctly, the RTC driver
> fails to initialize the system clock at bootup.
>
> Some digging in rtc/class.c::rtc_hctosys() indicates that
> do_settimeofday64() is deliberately not executed on systems with
> BITS_PER_LONG==32 and a second counter higher than INT_MAX. I assumed
> that the work on 64-bits timestamps was already fully implemented for
> 32-bit systems as well, so my gut feel is that this
> BITS_PER_LONG/INT_MAX check has become unnecessary. A test build with
> these checks disabled results in correct time initialization at bootup
> with, at a glance, no adverse effects. Does anybody here know whether
> do_settimeofday64()  is robust on 32-bit systems or that the checks
> are still required to prevent further breakage?

Please see commit b3a5ac42ab18 ("rtc: hctosys: Ensure system time
doesn't overflow time_t") and  https://github.com/systemd/systemd/issues/1143
for the problem that originally caused this to be added.

Removing this check would probably break systemd again for machines
that return a post-y2038 time with systemd built on 32-bit time_t.

The only reliable fix I can see would be to disable
CONFIG_RTC_HCTOSYS_DEVICE. I think this is Alexandre's plan
for the long run anyway, but I don't know if there has been any
progress in convincing distros to turn it off.

  Arnd
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel

2022-05-31 Thread Arnd Bergmann
(cc correct libc-alpha list, sorry for the typo)

On Tue, May 31, 2022 at 10:24 AM Arnd Bergmann  wrote:
> On 17/05/2022 09:51, Arnaud Panaïotis wrote:
> > I'm working for a client to generate embedded 32-bits Linux Kernel working 
> > after y2038 issue.
> >
> > I generated a 5.15 Kernel thought Buildroot with Coreutils 9.0, GCC 11.2.0, 
> > Binutils 2.37, Glibc 2.34-9 and CFLAGS  -D_LARGEFILE_SOURCE 
> > -D_FILE_OFFSET_BITS=64  -D_TIME_BITS=64.
> >
> > I encounter an issue while working with OpenSSH (I initially contacted them 
> > before).
>
> To clarify: did you build just openssh with  -D_TIME_BITS=64, or did
> you build the entire user space this way?
>
> > After 2038, /usr/sbin/sshd does not create an error but it child does 
> > generate this one:
> > daemon() failed: Value too large for defined data type
> >
> > This happend here in sshd.c:
> >
> > 2019 /*
> > 2020  * If not in debugging mode, not started from inetd and not 
> > already
> > 2021  * daemonized (eg re-exec via SIGHUP), disconnect from the 
> > controlling
> > 2022  * terminal, and fork.  The original process exits.
> > 2023  */
> > 2024 already_daemon = daemonized();
> > 2025 if (!(debug_flag || inetd_flag || no_daemon_flag || 
> > already_daemon)) {
> > 2026
> > 2027 if (daemon(0, 0) == -1)
> > 2028 fatal("daemon() failed: %.200s", 
> > strerror(errno));
>
> My guess is that there are parts of glibc that are not fully
> y2038-safe at the moment, but
> merely provide the interfaces for time64 applications.
>
>
> In the glibc code, I see
>
> int
> daemon (int nochdir, int noclose)
> {
> ...
> if ((fd = __open_nocancel(_PATH_DEVNULL, O_RDWR, 0)) != -1
> && (__builtin_expect (__fstat64 (fd, ), 0)
> == 0)) {
> ...
>  } else {
> __close_nocancel_nostatus (fd);
> return -1;
> }
>  return (0);
> }
>
> __fstatat64 (int fd, const char *file, struct stat64 *buf, int flags)
> {
>   struct __stat64_t64 st_t64;
>   return __fstatat64_time64 (fd, file, _t64, flags)
>  ?: __cp_stat64_t64_stat64 (_t64, buf);
> }
>
> If I'm reading this correctly, daemon() internally uses the time32
> version of 'stat', which fails for files with out-of-range timestamps.
> Are you able to rebuild the ssh binary (or your entire distro, if that's
> easier) against musl-1.2.x instead of glibc to see if the same thing
> happens there?
>
>Arnd
>
> > To reproduce:
> >
> > # date -s "2040-05-12"
> > # hwclock --systohc
> > # reboot
> > # /usr/sbin/sshd
> >
> > Note this error occurs only after the reboot, and setting a date before 
> > 2038 also require a reboot to remove the error.
> >
> > strace and gdb trace linked.
> >
> > Let me know if you need additional information.
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


[Y2038] Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel

2022-05-31 Thread Arnd Bergmann
On 17/05/2022 09:51, Arnaud Panaïotis wrote:
> Hello,
>
> I'm working for a client to generate embedded 32-bits Linux Kernel working 
> after y2038 issue.
>
> I generated a 5.15 Kernel thought Buildroot with Coreutils 9.0, GCC 11.2.0, 
> Binutils 2.37, Glibc 2.34-9 and CFLAGS  -D_LARGEFILE_SOURCE 
> -D_FILE_OFFSET_BITS=64  -D_TIME_BITS=64.
>
> I encounter an issue while working with OpenSSH (I initially contacted them 
> before).

To clarify: did you build just openssh with  -D_TIME_BITS=64, or did
you build the user space
this way?

> After 2038, /usr/sbin/sshd does not create an error but it child does 
> generate this one:
> daemon() failed: Value too large for defined data type
>
> This happend here in sshd.c:
>
> 2019 /*
> 2020  * If not in debugging mode, not started from inetd and not 
> already
> 2021  * daemonized (eg re-exec via SIGHUP), disconnect from the 
> controlling
> 2022  * terminal, and fork.  The original process exits.
> 2023  */
> 2024 already_daemon = daemonized();
> 2025 if (!(debug_flag || inetd_flag || no_daemon_flag || 
> already_daemon)) {
> 2026
> 2027 if (daemon(0, 0) == -1)
> 2028 fatal("daemon() failed: %.200s", 
> strerror(errno));

My guess is that there are parts of glibc that are not fully
y2038-safe at the moment, but
merely provide the interfaces for time64 applications.


In the glibc code, I see

int
daemon (int nochdir, int noclose)
{
...
if ((fd = __open_nocancel(_PATH_DEVNULL, O_RDWR, 0)) != -1
&& (__builtin_expect (__fstat64 (fd, ), 0)
== 0)) {
...
 } else {
__close_nocancel_nostatus (fd);
return -1;
}
 return (0);
}

__fstatat64 (int fd, const char *file, struct stat64 *buf, int flags)
{
  struct __stat64_t64 st_t64;
  return __fstatat64_time64 (fd, file, _t64, flags)
 ?: __cp_stat64_t64_stat64 (_t64, buf);
}

If I'm reading this correctly, daemon() internally uses the time32
version of 'stat', which
fails for files with out-of-range timestamps. Are you able to rebuild
the ssh binary
(or your entire distro, if that's easier) against musl-1.2.x instead
of glibc to see if the
same thing happens there?

   Arnd

> To reproduce:
>
> # date -s "2040-05-12"
> # hwclock --systohc
> # reboot
> # /usr/sbin/sshd
>
> Note this error occurs only after the reboot, and setting a date before 2038 
> also require a reboot to remove the error.
>
> strace and gdb trace linked.
>
> Let me know if you need additional information.
___
Y2038 mailing list -- y2038@lists.linaro.org
To unsubscribe send an email to y2038-le...@lists.linaro.org


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-19 Thread Arnd Bergmann
On Tue, Oct 19, 2021 at 4:16 PM Rich Felker  wrote:
> On Mon, Oct 18, 2021 at 04:42:04PM -0400, Rich Felker wrote:
> >
> > Well for little endian either would work (because adj is 0 :) but yes
> > there are 3 such paddings before the second member on big endian, so
> > it should be 3.
>
> How about this? It avoids open coding the logic and handles it as 2
> 4-byte substructures with endian-specific offsets.

Looks good to me.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-18 Thread Arnd Bergmann
On Mon, Oct 18, 2021 at 5:08 PM Rich Felker  wrote:
> On Mon, Oct 18, 2021 at 04:58:03PM +0200, Takashi Iwai wrote:
> > On Mon, 18 Oct 2021 16:43:00 +0200, Rich Felker wrote:
>
> No, I don't think so. The musl translator is to translate between the
> time64 ioctl structures and the old time32 ones for the sake of
> executing on an old kernel. Up til now, it has been broken comparably
> to how 32-bit binaries running in compat mode on a 64-bit kernel were
> broken: the code in musl translated the time64 structure to (and back
> from) the time32 one assuming the intended padding. But the
> application was using the actual kernel uapi struct where the padding
> was (and still is) illogical. Thus, nothing was built with the wrong
> ABI; it's only the musl-internal translation logic that was wrong (and
> only pre-time64 kernels are affected).
>
> The attached patch should fix it, I think.
>
> + int adj = BYTE_ORDER==BIG_ENDIAN ? 4 : 0;
> + if (dir==W) {
> + memcpy(old+68, new+72+adj, 4);
> + memcpy(old+72, new+72+4+2*adj, 4);

I think that should be "new+72+4+3*adj": the "2*adj" would
be what the code does already for the originally intended
format.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-08 Thread Arnd Bergmann
On Fri, Oct 8, 2021 at 2:06 PM Rich Felker  wrote:
> On Fri, Oct 08, 2021 at 11:24:39AM +0200, Arnd Bergmann wrote:
> >
> > I've tried to understand this part of musl's convert_ioctl_struct(), but I 
> > just
> > can't figure out whether it does the conversion based the on the layout that
> > is currently used in the kernel, or based on the layout we should have been
> > using, and would use with the above fix. Rich, can you help me here?
>
> If the attempted 64-bit ioctl is missing (ENOTTY), it does the
> conversion to the legacy 32-bit one and retries with that, then
> converts the results back to the 64-bit form.

I understand that it tries to do that.

The part that I'm not sure about is which of the two possible
64-bit forms it's using -- the broken one we have defined in the
kernel headers, or the one we were trying to define but failed.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-08 Thread Arnd Bergmann
On Fri, Oct 8, 2021 at 1:53 PM Takashi Iwai  wrote:
> On Fri, 08 Oct 2021 13:45:45 +0200, Arnd Bergmann wrote:
> > On Fri, Oct 8, 2021 at 1:11 PM Takashi Iwai  wrote:
> > > On Fri, 08 Oct 2021 11:24:39 +0200, Arnd Bergmann wrote:
> > > The below is a revised kernel patch (again untested), just correcting
> > > the behavior of 32bit compat mode.  32bit apps on 32bit kernel work
> > > fine as is, as well as 64bit apps on 64bit kernel.
> >
> > Right, this should cover all cases of the ioctl itself misbehaving.
> > In addition, we still need to disallow the mmap() interface on compat
> > kernels then. Strictly speaking, we could allow the snd_pcm_mmap_status
> > but not snd_pcm_mmap_control to be mapped, but I'm not sure if
> > that's better than disallowing both.
>
> IIRC, the compat mmap is already disallowed even for the
> SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW (in pcm_control_mmap_allowed()), so
> no need to change around that.

Ah, right. I think it was meant to become allowed as part of commit
80fe7430c708 ("ALSA: add new 32-bit layout for snd_pcm_mmap_status/control"),
which did allow the snd_pcm_mmap_status to be mmap()ed, but it appears
to be the rare case where two mistakes cancel out and we don't have to
change the mmap code.

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-08 Thread Arnd Bergmann
On Fri, Oct 8, 2021 at 1:11 PM Takashi Iwai  wrote:
> On Fri, 08 Oct 2021 11:24:39 +0200, Arnd Bergmann wrote:

> >
> > I've tried to understand this part of musl's convert_ioctl_struct(), but I 
> > just
> > can't figure out whether it does the conversion based the on the layout that
> > is currently used in the kernel, or based on the layout we should have been
> > using, and would use with the above fix. Rich, can you help me here?
>
> So, at this moment, I'm not sure whether we should correct the struct
> at all.  This will lead to yet more breakage, and basically the struct
> itself *works* -- the only bug is in 32bit compat handling in the
> kernel (again).

I'm still unsure if the musl fallback code is correct or not.

> The below is a revised kernel patch (again untested), just correcting
> the behavior of 32bit compat mode.  32bit apps on 32bit kernel work
> fine as is, as well as 64bit apps on 64bit kernel.

Right, this should cover all cases of the ioctl itself misbehaving.
In addition, we still need to disallow the mmap() interface on compat
kernels then. Strictly speaking, we could allow the snd_pcm_mmap_status
but not snd_pcm_mmap_control to be mapped, but I'm not sure if
that's better than disallowing both.

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [musl] Re: [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-08 Thread Arnd Bergmann
On Fri, Oct 8, 2021 at 10:43 AM Takashi Iwai  wrote:
> On Thu, 07 Oct 2021 18:51:58 +0200, Rich Felker wrote:
> > On Thu, Oct 07, 2021 at 06:18:52PM +0200, Takashi Iwai wrote:
>
> @@ -557,11 +558,15 @@ struct __snd_pcm_sync_ptr {
>  #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : 
> defined(__BIG_ENDIAN)
>  typedef char __pad_before_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
>  typedef char __pad_after_uframe[0];
> +typedef char __pad_before_u32[4];
> +typedef char __pad_after_u32[0];
>  #endif
>
>  #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : 
> defined(__LITTLE_ENDIAN)
>  typedef char __pad_before_uframe[0];
>  typedef char __pad_after_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
> +typedef char __pad_before_u32[0];
> +typedef char __pad_after_u32[4];
>  #endif

I think these should remain unchanged, the complex expression was intentionally
done so the structures are laid out the same way on 64-bit
architectures, so that
the kernel can use the __SND_STRUCT_TIME64 path internally on both 32-bit
and 64-bit architectures.

> @@ -2970,8 +2981,17 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream 
> *substream,
> memset(_ptr, 0, sizeof(sync_ptr));
> if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
> return -EFAULT;
> -   if (copy_from_user(_ptr.c.control, &(_sync_ptr->c.control), 
> sizeof(struct snd_pcm_mmap_control)))
> -   return -EFAULT;
> +   if (buggy_control) {
> +   if (copy_from_user(_ptr.c.control_api_2_0_15,
> +  &(_sync_ptr->c.control_api_2_0_15),
> +  sizeof(sync_ptr.c.control_api_2_0_15)))
> +   return -EFAULT;
> +   } else {
> +   if (copy_from_user(_ptr.c.control,
> +  &(_sync_ptr->c.control),
> +  sizeof(sync_ptr.c.control)))
> +   return -EFAULT;
> +   }

The problem I see with this is that it might break musl's ability to
emulate the new
interface on top of the old (time32) one for linux-4.x and older
kernels, as the conversion
function is no longer stateless but has to know the negotiated
interface version.

It's probably fine as long as we can be sure that the 2.0.16+ API
version only gets
negotiated if both the kernel and user sides support it, and musl only emulates
the 2.0.15 API version from the current kernels.

I've tried to understand this part of musl's convert_ioctl_struct(), but I just
can't figure out whether it does the conversion based the on the layout that
is currently used in the kernel, or based on the layout we should have been
using, and would use with the above fix. Rich, can you help me here?

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-07 Thread Arnd Bergmann
 On Thu, Oct 7, 2021 at 2:43 PM Takashi Iwai  wrote:
> On Thu, 07 Oct 2021 13:48:44 +0200, Arnd Bergmann wrote:
> > On Thu, Oct 7, 2021 at 12:53 PM Takashi Iwai  wrote:
> > > On Wed, 06 Oct 2021 19:49:17 +0200, Michael Forney wrote:
> >
> > As far as I can tell, the broken interface will always result in
> > user space seeing a zero value for "avail_min". Can you
> > make a prediction what that would mean for actual
> > applications? Will they have no audio output, run into
> > a crash, or be able to use recover and appear to work normally
> > here?
>
> No, fortunately it's only about control->avail_min, and fiddling this
> value can't break severely (otherwise it'd be a security problem ;)
>
> In the buggy condition, it's always zero, and the kernel treated as if
> 1, i.e. wake up as soon as data is available, which is OK-ish for most
> applications.   Apps usually don't care about the wake-up condition so
> much.  There are subtle difference and may influence on the stability
> of stream processing, but the stability usually depends more strongly
> on the hardware and software configurations.
>
> That being said, the impact by this bug (from the application behavior
> POV) is likely quite small, but the contamination is large; as you
> pointed out, it's much larger than I thought.

Ok, got it.

> The definition in uapi/sound/asound.h is a bit cryptic, but IIUC,
> __snd_pcm_mmap_control64 is used for 64bit archs, right?  If so, the
> problem rather hits more widely on 64bit archs silently.  Then, the
> influence by this bug must be almost negligible, as we've had no bug
> report about the behavior change.

While __snd_pcm_mmap_control64 is only used on 32-bit
architectures when 64-bit time_t is used. At the moment, this
means all users of musl-1.2.x libc, but not glibc.

On 64-bit architectures, __snd_pcm_mmap_control and
__snd_pcm_mmap_control64 are meant to be identical,
and this is actually true regardless of the bug, since
__pad_before_uframe and __pad_after_uframe both
end up as zero-length arrays here.

> We may just fix it in kernel and for new library with hoping that no
> one sees the actual problem.  Or, we may provide a complete new set of
> mmap offsets and ioctl to cover both broken and fixed interfaces...
> The decision depends on how perfectly we'd like to address the bug.
> As of now, I'm inclined to go for the former, but I'm open for more
> opinions.

Adding the musl list to Cc for additional testers, anyone interested
please see [1] for the original report.

It would be good to hear from musl users that are already using
audio support with 32-bit applications on 64-bit kernels, which
is the case that has the problem today. Have you noticed any
problems with audio support here? If not, we can probably
"fix" the kernel here and make the existing binaries behave
the same way on 32-bit kernels. If there are applications that
don't work in that environment today, I think we need to instead
change the kernel to accept the currently broken format on
both 32-bit and 64-bit kernels, possibly introducing yet another
format that works as originally intended but requires a newly
built kernel.

  Arnd

[1] https://lore.kernel.org/all/29qbmju8de71e.2yzsh8iht5...@mforney.org/
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [alsa-devel] [PATCH v7 8/9] ALSA: add new 32-bit layout for snd_pcm_mmap_status/control

2021-10-07 Thread Arnd Bergmann
On Thu, Oct 7, 2021 at 12:53 PM Takashi Iwai  wrote:
> On Wed, 06 Oct 2021 19:49:17 +0200, Michael Forney wrote:
> >
> > Arnd Bergmann  wrote:
> > > +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : 
> > > defined(__BIG_ENDIAN)
> > > +typedef char __pad_before_uframe[sizeof(__u64) - 
> > > sizeof(snd_pcm_uframes_t)];
> > > +typedef char __pad_after_uframe[0];
> > > +#endif
> > > +
> > > +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : 
> > > defined(__LITTLE_ENDIAN)
> > > +typedef char __pad_before_uframe[0];
> > > +typedef char __pad_after_uframe[sizeof(__u64) - 
> > > sizeof(snd_pcm_uframes_t)];
> > > +#endif
> > > +
> > > +struct __snd_pcm_mmap_status64 {
> > > +   __s32 state;/* RO: state - SNDRV_PCM_STATE_ */
> > > +   __u32 pad1; /* Needed for 64 bit alignment */
> > > +   __pad_before_uframe __pad1;
> > > +   snd_pcm_uframes_t hw_ptr;   /* RO: hw ptr (0...boundary-1) */
> > > +   __pad_after_uframe __pad2;
> > > +   struct __snd_timespec64 tstamp; /* Timestamp */
> > > +   __s32 suspended_state;  /* RO: suspended stream state */
> > > +   __u32 pad3; /* Needed for 64 bit alignment */
> > > +   struct __snd_timespec64 audio_tstamp; /* sample counter or wall clock 
> > > */
> > > +};
> > > +
> > > +struct __snd_pcm_mmap_control64 {
> > > +   __pad_before_uframe __pad1;
> > > +   snd_pcm_uframes_t appl_ptr;  /* RW: appl ptr (0...boundary-1) */
> > > +   __pad_before_uframe __pad2;
> >
> > I was looking through this header and happened to notice that this
> > padding is wrong. I believe it should be __pad_after_uframe here.
> >
> > I'm not sure of the implications of this typo, but I suspect it
> > breaks something on 32-bit systems with 64-bit time (regardless of
> > the endianness, since it changes the offset of avail_min).

Thanks a lot for the report! Yes, this is definitely broken in some ways.

> Right, that's the expected breakage.  It seems that the 64bit time on
> 32bit arch is still rare, so we haven't heard a regression by that, so
> far...

It might actually be worse: on a native 32-bit kernel, both user space
and kernel see the same broken definition with a 64-bit time_t, which
would end up actually making it work as expected. However, in
compat mode, the layout seen on the 32-bit user space is now
different from what the 64-bit kernel has, which would in turn not
work, in both the SNDRV_PCM_IOCTL_SYNC_PTR ioctl and in
the mmap() interface.

Fixing the layout to look like the way we had intended would make
newly compiled applications work in compat mode, but would break
applications built against the old header on new kernels and also
newly built applications on old kernels.

I still hope I missed something and it's not quite that bad, but I
fear the best we can do in this case make the broken interface
the normative one and fixing compat mode to write
mmap_control64->avail_min in the wrong location for
SNDRV_PCM_IOCTL_SYNC_PTR, as well as disabling
the mmap() interface again for compat tasks.

As far as I can tell, the broken interface will always result in
user space seeing a zero value for "avail_min". Can you
make a prediction what that would mean for actual
applications? Will they have no audio output, run into
a crash, or be able to use recover and appear to work normally
here?

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] ia32 signed long treated as x64 unsigned int by __ia32_sys*

2021-09-23 Thread Arnd Bergmann
On Thu, Sep 23, 2021 at 12:01 PM Richard Palethorpe  wrote:
> Arnd Bergmann  writes:
> > On Wed, Sep 22, 2021 at 10:46 AM Richard Palethorpe  
> > wrote:
> >> Richard Palethorpe  writes:
> >
> > I also noticed that only x86 and s390 even have separate entry
> > points for normal syscalls when called in compat mode, while
> > the others all just zero the upper halves of the registers in the
> > low-level entry code and then call the native entry point.
>
> It looks to me like aarch64 also has something similar? At any rate, I
> can try to fix it for x86 and investigate what else might be effected.

arm64 also has a custom asm/syscall_wrapper.h, but it only does
this for accessing pt_regs (as x86 does), not for doing any
argument conversion. x86 does the 32-to-64 widening in the
wrapper, arm64 relies on the pt_regs already having the upper
halves zeroed.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] ia32 signed long treated as x64 unsigned int by __ia32_sys*

2021-09-22 Thread Arnd Bergmann
On Wed, Sep 22, 2021 at 10:46 AM Richard Palethorpe  wrote:
> Richard Palethorpe  writes:

> >
> > Then the output is:
> >
> > [   11.252268] io_pgetevents(f7f19000, 4294967295, 1, ...)
> > [   11.252401] comparing 4294967295 <= 1
> > io_pgetevents02.c:114: TPASS: invalid min_nr: io_pgetevents() failed as 
> > expected: EINVAL (22)
> > [   11.252610] io_pgetevents(f7f19000, 1, 4294967295, ...)
> > [   11.252748] comparing 1 <= 4294967295
> > io_pgetevents02.c:103: TFAIL: invalid max_nr: io_pgetevents() passed 
> > unexpectedly
>
> and below is the macro expansion for the automatically generated 32bit to
> 64bit io_pgetevents. I believe it is casting u32 to s64, which appears
> to mean there is no sign extension. I don't know if this is the expected
> behaviour?

Thank you for digging through this, I meant to already reply once more yesterday
but didn't get around to that.

> __typeof(__builtin_choose_expr(
> (__builtin_types_compatible_p(typeof((long)0), typeof(0LL)) ||
>  __builtin_types_compatible_p(typeof((long)0), typeof(0ULL))),
> 0LL, 0L)) min_nr,
> __typeof(__builtin_choose_expr(
> (__builtin_types_compatible_p(typeof((long)0), typeof(0LL)) ||
>  __builtin_types_compatible_p(typeof((long)0), typeof(0ULL))),
> 0LL, 0L)) nr,

The part that I remembered is in arch/s390/include/asm/syscall_wrapper.h,
which uses this version instead:

#define __SC_COMPAT_CAST(t, a)  \
({  \
long __ReS = a; \
\
BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&  \
 !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&   \
 !__TYPE_IS_LL(t)); \
if (__TYPE_IS_L(t)) \
__ReS = (s32)a; \
if (__TYPE_IS_UL(t))\
__ReS = (u32)a; \
if (__TYPE_IS_PTR(t))   \
__ReS = a & 0x7fff; \
if (__TYPE_IS_LL(t))\
return -ENOSYS; \
(t)__ReS;   \
})

This also takes care of s390-specific pointer conversion, which is the
reason for needing an architecture-specific wrapper, but I suppose the
handling of signed arguments as done in s390 should also be done
everywhere else.

I also noticed that only x86 and s390 even have separate entry
points for normal syscalls when called in compat mode, while
the others all just zero the upper halves of the registers in the
low-level entry code and then call the native entry point.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH] aio: Wire up compat_sys_io_pgetevents_time64 for x86

2021-09-21 Thread Arnd Bergmann
On Tue, Sep 21, 2021 at 3:01 PM Richard Palethorpe  wrote:
>
> The LTP test io_pgetevents02 fails in 32bit compat mode because an
> nr_max of -1 appears to be treated as a large positive integer. This
> causes pgetevents_time64 to return an event. The test expects the call
> to fail and errno to be set to EINVAL.
>
> Using the compat syscall fixes the issue.
>
> Fixes: 7a35397f8c06 ("io_pgetevents: use __kernel_timespec")
> Signed-off-by: Richard Palethorpe 

Thanks a lot for finding this, indeed there is definitely a mistake that
this function is defined and not used, but I don't yet see how it would
get to the specific failure you report.

Between the two implementations, I can see a difference in the
handling of the signal mask, but that should only affect architectures
with incompatible compat_sigset_t, i.e. big-endian or
_COMPAT_NSIG_WORDS!=_NSIG_WORDS, and the latter is
never true for currently supported architectures. On x86, there is
no difference in the sigset at all.

The negative 'nr' and 'min_nr' arguments that you list as causing
the problem /should/ be converted by the magic
SYSCALL_DEFINE6() definition. If this is currently broken, I would
expect other syscalls to be affected as well.

Have you tried reproducing this on non-x86 architectures? If I
misremembered how the compat conversion in SYSCALL_DEFINE6()
works, then all architectures that support CONFIG_COMPAT have
to be fixed.

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-23 Thread Arnd Bergmann
On Mon, Mar 23, 2020 at 7:21 PM Steve McIntyre  wrote:
> On Wed, Mar 11, 2020 at 01:52:00PM +0100, Arnd Bergmann wrote:
> >* Adding a time64 armhf as a separate (incompatible) target in glibc
> >  that defines __TIMESIZE==64 and a 64-bit __time_t would avoid
> >  most of the remaining ABI issues and put armhf-time64 in the same
> >  category as riscv32 and arc, but this idea was so far rejected by the
> >  glibc maintainers. Depending on how hard this turns out to be,
> >  it could be used to get to the point of self-hosting though, and
> >  help find time64 related bugs in the rest of the distro.
>
> OK. I'm thinking it's probably not worth it?

This depends on the timeline of Lukasz' work. My feeling is that there is still
quite a bit to be done before it's worth trying the Debian bootstrap again.

If you or someone else wants to continue where I stopped with the Debian
rebuilding without waiting for the complete glibc port, adding a new armhf
target to glibc on top of the current glibc-y2038 tree is probably a quicker
way to get something that builds and boots. I don't know how much work
exactly there would be for this approach, but my feeling is that it's not that
much after looking at the kind of problems I ran into, and at the state of
the riscv32 port that uses the same approach.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-18 Thread Arnd Bergmann
On Mon, Mar 16, 2020 at 11:12 PM Lukasz Majewski  wrote:
> > On Fri, Mar 13, 2020 at 9:22 PM Rich Felker  wrote:
> > > >   - Removing the time32 symbols from the glibc shared object did
> > > > not work as they are still used (a lot) internally, and by the
> > > > testsuite.
> > >
> > > That they're used internally sounds like a major problem; anywhere
> > > they're being used internally potentially has hidden Y2038 bugs.
> > > This is also why I'm concerned about glibc's approach of not
> > > building itself with _TIME_BITS=64, and just undefining it or doing
> > > something else in the wrapper files for the legacy time32 symbols.
> >
> > I thought this was the long-term plan. Working on the ABI first and
> > then changing the implementation may help speed up the timeline
> > before distro-level work can start, but OTOH removing all the 32-bit
> > codepaths from the implementation first makes it more likely to find
> > all relevant bits.
>
> If I understood the question correctly - the problem is with having
> glibc ABI consistent. This requires having 64 bit types for relevant
> functions. For example the __clock_settime64 accepts struct
> __timespec64 parameter which:
>
> - Is aliased to "normal" struct timespec on machines with
>   __WORDSIZE==64 (x32 is a special case)
>
> - The struct __timespec64 is used on 32 bit machines
>
> As a result the glibc is ready to handle 64 bit time always (with
> clock_settime on __WORDSIZE==64 or clock_settime64 otherwise), as
> exported struct timespec fields size vary depending on the machine for
> which glibc is built.

I think we all understand the need to duplicate each interface that
passes a data type derived from time_t, and how the aliasing works,

The point above is purely for the internal implementation. The approach
that I have picked for the kernel and Rich did for musl was that
internal code never sees the old __time_t definition for any data
structure or function call, those are only used to define the wrappers
for 32-bit architectures that provide the legacy interfaces.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-16 Thread Arnd Bergmann
On Mon, Mar 16, 2020 at 3:47 PM Rich Felker  wrote:

> libtirpc is the replacement. I wasn't aware if uses libc-provided rpc
> headers (presumably only if they exist, since folks are using it fine
> on musl) but even if so I think the types will automatically update
> when time_t changes. Of course that leaves the libtirpc ABI dependent
> on which time_t is used.

Ok, makes sense. I suppose it just provides a header with the same
name then.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-16 Thread Arnd Bergmann
On Fri, Mar 13, 2020 at 9:22 PM Rich Felker  wrote:
>
> On Wed, 11 Mar 2020 13:52:00 +01000, Arnd Bergmann wrote:
> > As discussed before, I tried using the rebootstrap tool [1] to see what
> > problems come up once the entire distro gets rebuilt.  Based on Lukasz'
> > recommendation, I tried the 'y2038_edge' branch with his experimental
> > glibc  patches [2], using commit c2de7ee9461 dated 2020-02-17.
> >
> > Here is a rough summary of what I tried, what worked, and what problems
> > I ran into:
> >
> > [...]
> >
> > * Actually building a time64 version of glibc turned out to be
> >   harder, including some issues discussed on the libc mailing list[5]:
> >
> >   - Always setting -D_TIME_BITS=64 in the global compiler flags for
> > the distro breaks both the native 64-bit (x86_64) build and the
> > 32-bit build, as glibc itself expects to be built without this.
>
> This seems like a small issue, but glibc should probably either remove
> it from CFLAGS in the build system or at least catch it at configure
> time and error out, so that it's not confusing when it breaks.

Right, that would make sense. For the test suite though, I guess
it would actually need to run each test case that references
time_t both ways.

> >   - Removing the time32 symbols from the glibc shared object did not
> > work as they are still used (a lot) internally, and by the testsuite.
>
> That they're used internally sounds like a major problem; anywhere
> they're being used internally potentially has hidden Y2038 bugs. This
> is also why I'm concerned about glibc's approach of not building
> itself with _TIME_BITS=64, and just undefining it or doing something
> else in the wrapper files for the legacy time32 symbols.

I thought this was the long-term plan. Working on the ABI first and
then changing the implementation may help speed up the timeline
before distro-level work can start, but OTOH removing all the 32-bit
codepaths from the implementation first makes it more likely to find
all relevant bits.

> >   - The nptl and sunrpc portions have numerous interfaces with
> > 'timeval' or 'timespec' arguments that each cause an ABI break.
>
> nptl is essential but I think sunrpc is pure legacy ABI and not
> intended to be linkable in the future.

That would be helpful, but what does it mean for distro packages
that link against it today?
codesearch.debian.org e.g. finds nfs-utls, nis, libtirpc, ntirpc
and nfswatch including . Can these just use a
replacement that is built with 64-bit time_t then?

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-12 Thread Arnd Bergmann
[some mailing lists appear to have classified the earlier mail as spam,
 it was quite long and contained a lot of links. See
 https://lists.debian.org/debian-arm/2020/03/msg00032.html for the
 start of the thread if you did not get that]

On Wed, Mar 11, 2020 at 3:37 PM Lukasz Majewski  wrote:
> >   - stat()/fstat()/lstat(), nanosleep(), wait3()/wait4(), ppoll_chk()
> > are some of the other interfaces that take a time_t based
> > argument and need to grow a time64 version to avoid an ABI
> > mismatch.
>
> The stat() and friends will use statx internally, which supports 64 bit
> time from the outset.
> Unfortunately, it hasn't been yet converted.
>
> As statx was added in 4.1 (IIRC) - after the minimal supported Linux
> kernel version is bumped to this version (from 3.2 as now) it all will
> be fixed.

The problem I had with these was not on the kernel API side (I
still have CONFIG_COMPAT_32BIT_TIME enabled for now) but
on the application side. In particular, the 'struct stat' definition
(when __USE_XOPEN2K8 is defined) contains

 struct timespec st_atim;

and similar fields that are interpreted using 64-bit time_t in the
application including the header, but with 32-bit time_t inside of
the ___fxstat64() implementation in glibc. The problem is caused
by the mismatched ABI, not by the time_t overflow, in the same
way that happens in the nptl library callers and in the other interfaces
I mentioned.
This is also what seems to cause most of the testcase failures
when the tests are built with __TIME_BITS=64.

> >   - The timeval prototype appears to be broken, as it's missing
> > padding on architectures without native alignment of __time64
> > (e.g. i386) and on all big-endian architectures.
> >
>
> You mean the one "exported" to the system or one, which is internal to
> glibc (from ./include/time.h)?

I mean in the installed headers, where I get (after preprocessing)

typedef long long __time64_t;
typedef long __suseconds_t;
struct timeval
{
  __time64_t tv_sec;
  __suseconds_t tv_usec;
};

On i386 and m68k, this leads to a 12 byte structure when the kernel
interfaces expect a 16 byte structure. All other 32-bit architectures add
four byte padding at the end, so the size is correct, but on big-endian
systems, kernel also expects padding *before* tv_usec, in the same
way as the timespec definition does. IIRC the best way to handle this
is with a 64-bit suseconds_t, e.g.  by adding a __suseconds64_t
defined the same way as __time64_t.

> > I have spent more time on this now than I had planned, and don't
> > expect to do further work on it anytime soon, but I hope my summary
> > is useful to others that are going to need this later.  I can
> > obviously share my patches and build artifacts if anyone needs them.
>
> Could you upload them to any server? (kernel.org or github)?

I have uploaded the modified debian-glibc and rebootstrap
sources to https://git.linaro.org/people/arnd/ now, this should
be all that's needed to recreate the build, using these steps:

- build an x86-64 debian glibc-2.31 package (binary plus source)
  based on the glibc package data
- create a pbuilder instance with that available as a source to apt
- log into the pbuilder and run the modified bootstrap.sh according
  to information on the pbuilder web page.

The binary packages I created are not as useful, as they would
not work with any build of glibc, neither the version I built, nor
any fixed one. I could find a way to send that to you in private,
but it's hundreds of megabytes.

Unfortunately I lost the build logs during a crash yesterday.

> > There are two additional approaches that would likely get a Debian
> > bootstrap further, but that I have not tried as they were previously
> > dismissed:
> >
> > * Adding a time64 armhf as a separate (incompatible) target in glibc
> >   that defines __TIMESIZE==64 and a 64-bit __time_t would avoid
> >   most of the remaining ABI issues and put armhf-time64 in the same
> >   category as riscv32 and arc, but this idea was so far rejected by
> > the glibc maintainers.
>
> As fair as I know riscv32 and arc will use generic syscall interface.
> The arm32 bit doesn't support it - so the code from those two
> aforementioned ports will not be used.

The differences between the generic syscall interface and the arm
version are much smaller than ABI differences between the ABIs
for 32-bit __time_t and the __time_t == __time64_t version.

In particular, as such a new port could mandate a minimum kernel
of v5.1, it could just use all the time64 syscalls, the split sysvipc
and statx as a baseline.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] Trying Debian/armhf rebootstrap with time64

2020-03-11 Thread Arnd Bergmann
As discussed before, I tried using the rebootstrap tool [1] to see what
problems come up once the entire distro gets rebuilt.  Based on Lukasz'
recommendation, I tried the 'y2038_edge' branch with his experimental
glibc  patches [2], using commit c2de7ee9461 dated 2020-02-17.

Here is a rough summary of what I tried, what worked, and what problems
I ran into:

* Building a Debian package from this was fairly straightforward, using
  the 2.31 branch in the package git repository[3] after replacing the
  debian/patches/git-updates.diff file with one generated from [2] and
  disabling the hurd patches because of conflicts.

* After installing the modified x86 glibc package, I ran into a runtime
  bug in [4], which needs to pass AT_FDCWD instead of 0 to avoid
  ENOTDIR errors.

* Bootstrapping a regular time32 Debian armhf with this libc took me
  a few days to get right, but that was mostly for getting familiar
  with rebootstrap and running into known issues unrelated to time64
  or the glibc changes.

* Actually building a time64 version of glibc turned out to be
  harder, including some issues discussed on the libc mailing list[5]:

  - Always setting -D_TIME_BITS=64 in the global compiler flags for
the distro breaks both the native 64-bit (x86_64) build and the
32-bit build, as glibc itself expects to be built without this.

  - Removing the time32 symbols from the glibc shared object did not
work as they are still used (a lot) internally, and by the testsuite.

  - I tried converting all the internal symbols to use the time64
variants with the correct types (e.g. __clock_gettime64() instead
of __clock_gettime()), but then ran into a lot of APIs that take
timespec/timeval/... arguments and pass them down into internal
functions. These seem to all be bugs that require adding a time64
version of the external ABI.

  - After I abandoned that approach, I continued with a simple
patch to features.h that sets _TIME_BITS/_FILE_OFFSET_BITS based on
'#if !defined _LIBC && __TIMESIZE == 32', which ignores the bugs I
found earlier but got me a lot further.

  - Building the i386 glibc with that patch, I ran into over 150
testsuite failures [6]. This looked like there was a fundamental
mistake on my side, but after I looked into a few of the failures,
most seemed to be either glibc or testsuite bugs that have to be
addressed individually. I considered giving up at this point,
but as Lukasz has said that he had successfully built a working
system using Yocto, I kept going anyway and marked these all as
expected failures in the debian package.

* There are a couple of noteworthy issues in glibc-y2038 I'd like to
  point out in particular, though I'm sure these are not the only
  important ones:

  - The clock_nanosleep() prototype needed a '__THROW' annotation
to complete the build.

  - The nptl and sunrpc portions have numerous interfaces with
'timeval' or 'timespec' arguments that each cause an ABI break.

  - stat()/fstat()/lstat(), nanosleep(), wait3()/wait4(), ppoll_chk()
are some of the other interfaces that take a time_t based
argument and need to grow a time64 version to avoid an ABI mismatch.

  - The timeval prototype appears to be broken, as it's missing
padding on architectures without native alignment of __time64
(e.g. i386) and on all big-endian architectures.

  - some testcases hang in futex_wait() or clock_nanosleep()
because of incorrect timeout arguments, presumably from type
mismatches.

* There is an open question regarding the name of the Debian
  architecture. For my experiments, I kept using the 'armhf' name
  unmodified, though there seems to be a general feeling that using a
  different name would be required to address the broad incompatibilities
  between time32 and time64 versions of all the libraries in the
  distro. Gradually changing them won't work because of the timeline and
  the number of affected libraries. However, the new name of the distro
  also implies having a distinct target triplet, which must then be known
  by glibc along with everything else using config.guess/config.sub. I
  expect this topic to require a lot more discussion.

* Continuing with the rebootstrap build despite the known glibc issues
  and the open question on the architecture name went surprisingly
  well, only two out of the 152 source packages I built had
  compile-time problems:

  - building the final gcc failed in libsanitizer, which has
compile-time checks to ensure some libc data structures have the
expected layout. It noticed that 'struct timeb' and 'struct dirent'
are different based on _TIME_BITS and _FILE_OFFSET_BITS. I disabled
the checks to be able to continue. To this properly, the library
has to learn about the new data structures as well. I opened a
bug report against the library[7].

  - libpreludecpp12 failed to build because of checks for changes
in the 

[Y2038] [GIT PULL] compat-ioctl fix for v5.6

2020-02-08 Thread Arnd Bergmann
The following changes since commit 77b9040195dea3fcddf19e136c9e99a501351778:

  compat_ioctl: simplify the implementation (2020-01-03 09:42:52 +0100)

are available in the Git repository at:

  git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git
tags/compat-ioctl-fix

for you to fetch changes up to 0a061743af93f472687b8c69b0d539d1f12f3fd2:

  compat_ioctl: fix FIONREAD on devices (2020-02-08 18:02:54 +0100)


compat-ioctl fix for v5.6

One patch in the compat-ioctl series broke 32-bit rootfs for multiple
people testing on 64-bit kernels. Let's fix it in -rc1 before others
run into the same issue.


Arnd Bergmann (1):
  compat_ioctl: fix FIONREAD on devices

 fs/ioctl.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [GIT PULL] y2038: core, driver and file system changes

2020-01-29 Thread Arnd Bergmann
The following changes since commit e42617b825f8073569da76dc4510bfa019b1c35a:

  Linux 5.5-rc1 (2019-12-08 14:57:55 -0800)

are available in the Git repository at:

  git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git
tags/y2038-drivers-for-v5.6-signed

for you to fetch changes up to c4e71212a245017d2ab05f322f7722f0b87a55da:

  Revert "drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC"
(2020-01-28 23:24:23 +0100)


y2038: core, driver and file system changes

These are updates to device drivers and file systems that for some reason
or another were not included in the kernel in the previous y2038 series.

I've gone through all users of time_t again to make sure the kernel is
in a long-term maintainable state, replacing all remaining references
to time_t with safe alternatives.

Some related parts of the series were picked up into the nfsd, xfs,
alsa and v4l2 trees. A final set of patches in linux-mm removes the now
unused time_t/timeval/timespec types and helper functions after all five
branches are merged for linux-5.6, ensuring that no new users get merged.

As a result, linux-5.6, or my backport of the patches to 5.4 [1], should
be the first release that can serve as a base for a 32-bit system designed
to run beyond year 2038, with a few remaining caveats:

- All user space must be compiled with a 64-bit time_t, which will be
  supported in the coming musl-1.2 and glibc-2.32 releases, along with
  installed kernel headers from linux-5.6 or higher.

- Applications that use the system call interfaces directly need to be
  ported to use the time64 syscalls added in linux-5.1 in place of the
  existing system calls. This impacts most users of futex() and seccomp()
  as well as programming languages that have their own runtime environment
  not based on libc.

- Applications that use a private copy of kernel uapi header files or
  their contents may need to update to the linux-5.6 version, in
  particular for sound/asound.h, xfs/xfs_fs.h, linux/input.h,
  linux/elfcore.h, linux/sockios.h, linux/timex.h and linux/can/bcm.h.

- A few remaining interfaces cannot be changed to pass a 64-bit time_t
  in a compatible way, so they must be configured to use CLOCK_MONOTONIC
  times or (with a y2106 problem) unsigned 32-bit timestamps. Most
  importantly this impacts all users of 'struct input_event'.

- All y2038 problems that are present on 64-bit machines also apply to
  32-bit machines. In particular this affects file systems with on-disk
  timestamps using signed 32-bit seconds: ext4 with ext3-style small
  inodes, ext2, xfs (to be fixed soon) and ufs.

Changes since v1 [2]:

- Add Acks I received
- Rebase to v5.5-rc1, dropping patches that got merged already
- Add NFS, XFS and the final three patches from another series
- Rewrite etnaviv patches
- Add one late revert to avoid an etnaviv regression

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame
[2] https://lore.kernel.org/lkml/20191108213257.3097633-1-a...@arndb.de/

----
Arnd Bergmann (21):
  fat: use prandom_u32() for i_generation
  dlm: use SO_SNDTIMEO_NEW instead of SO_SNDTIMEO_OLD
  xtensa: ISS: avoid struct timeval
  um: ubd: use 64-bit time_t where possible
  acct: stop using get_seconds()
  tsacct: add 64-bit btime field
  packet: clarify timestamp overflow
  hostfs: pass 64-bit timestamps to/from user space
  hfs/hfsplus: use 64-bit inode timestamps
  drm/msm: avoid using 'timespec'
  drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC
  drm/etnaviv: avoid deprecated timespec
  sunrpc: convert to time64_t for expiry
  nfs: use time64_t internally
  nfs: fix timstamp debug prints
  nfs: fscache: use timespec64 in inode auxdata
  y2038: remove obsolete jiffies conversion functions
  y2038: rename itimerval to __kernel_old_itimerval
  y2038: sparc: remove use of struct timex
  y2038: sh: remove timeval/timespec usage from headers
  Revert "drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC"

 arch/sh/include/uapi/asm/sockios.h |  4 +-
 arch/sparc/kernel/sys_sparc_64.c   | 33 ++--
 arch/um/drivers/cow.h  |  2 +-
 arch/um/drivers/cow_user.c |  7 +--
 arch/um/drivers/ubd_kern.c | 10 ++--
 arch/um/include/shared/os.h|  2 +-
 arch/um/os-Linux/file.c|  2 +-
 .../platforms/iss/include/platform/simcall.h   |  4 +-
 drivers/gpu/drm/etnaviv/etnaviv_drv.c  | 11 ++--
 drivers/gpu/drm/etnaviv/etnaviv_drv.h  | 11 ++--
 drivers/gpu/drm/etnaviv/etnaviv_gem.c  |  4 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem.h  |  2 +-
 drivers/gpu/drm/etnaviv/et

Re: [Y2038] [PATCH] hcidump: add support for time64 based libc

2020-01-11 Thread Arnd Bergmann
 was On Sat, Jan 11, 2020 at 12:32 AM Guy Harris  wrote:
>
> On Jan 10, 2020, at 1:19 PM, Arnd Bergmann  wrote:
>
> > On Fri, Jan 10, 2020 at 10:05 PM Rich Felker  wrote:
> >>
> >> On Fri, Jan 10, 2020 at 09:49:03PM +0100, Arnd Bergmann wrote:
> >>> musl is moving to a default of 64-bit time_t on all architectures,
> >>> glibc will follow later. This breaks reading timestamps through cmsg
> >>> data with the HCI_TIME_STAMP socket option.
> >>>
> >>> Change both copies of hcidump to work on all architectures.  This also
> >>> fixes x32, which has never worked, and carefully avoids breaking sparc64,
> >>> which is another special case.
> >>
> >> Won't it be broken on rv32 though? Based on my (albeit perhaps
> >> incomplete) reading of the thread, I think use of HCI_TIME_STAMP
> >> should just be dropped entirely in favor of using SO_TIMESTAMPNS -- my
> >> understanding was that it works with bluetooth sockets too.
> >
> > All 32-bit architectures use old_timeval32 timestamps in the kernel
> > here, even rv32 and x32. As a rule, we keep the types bug-for-bug
> > compatible between architectures and fix them all at the same time.
> >
> > Changing hcidump to SO_TIMESTAMPNS would work as well, but
> > that is a much bigger change and I don't know how to test that.
>
> If so, maybe I'll just do that for libpcap.  Libpcap *does* have an API to 
> request
>capturing with nanoseconds in tv_usec (and I plan to give it pcapng-flavored 
>APIs
> to deliver higher-resolution time stamps, as well as metadata such as 
> "incoming"
> vs. "outgoing", as well).

Sounds good to me, just make sure that you no longer reference
HCI_TIME_STAMP and it should be fine with both old and new libc
versions.

SO_TIMESTAMPNS was first added to the kernel in linux-2.6.22, which
is probably older than anything you care about,  but I'm not sure what you
need to do to use it on bluetooth. It appears to have first been added along
with the monitor channel support in linux-3.4.

On a semi-related note, I see that there is a y2038 compatibility in the
libpcap definition of struct pcap_timeval, which uses a *signed* tv_sec
field. I assume the sizes of the fields cannot be changed, but it would
be good to investigate if you can just make it unsigned instead, changing
the supported time range from 1902...2038 to 1970...2106.
It probably makes sense to do this together with supporting nanosecond
timestamps. You could also consider changing the format to use a
64-bit nanosecond value starting at either 1970 or 1902 to give an
even larger range.

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH] hcidump: add support for time64 based libc

2020-01-10 Thread Arnd Bergmann
On Fri, Jan 10, 2020 at 10:05 PM Rich Felker  wrote:
>
> On Fri, Jan 10, 2020 at 09:49:03PM +0100, Arnd Bergmann wrote:
> > musl is moving to a default of 64-bit time_t on all architectures,
> > glibc will follow later. This breaks reading timestamps through cmsg
> > data with the HCI_TIME_STAMP socket option.
> >
> > Change both copies of hcidump to work on all architectures.  This also
> > fixes x32, which has never worked, and carefully avoids breaking sparc64,
> > which is another special case.
>
> Won't it be broken on rv32 though? Based on my (albeit perhaps
> incomplete) reading of the thread, I think use of HCI_TIME_STAMP
> should just be dropped entirely in favor of using SO_TIMESTAMPNS -- my
> understanding was that it works with bluetooth sockets too.

All 32-bit architectures use old_timeval32 timestamps in the kernel
here, even rv32 and x32. As a rule, we keep the types bug-for-bug
compatible between architectures and fix them all at the same time.

Changing hcidump to SO_TIMESTAMPNS would work as well, but
that is a much bigger change and I don't know how to test that.

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH] hcidump: add support for time64 based libc

2020-01-10 Thread Arnd Bergmann
musl is moving to a default of 64-bit time_t on all architectures,
glibc will follow later. This breaks reading timestamps through cmsg
data with the HCI_TIME_STAMP socket option.

Change both copies of hcidump to work on all architectures.  This also
fixes x32, which has never worked, and carefully avoids breaking sparc64,
which is another special case.

I have only compiled this on one architecture, please at least test
it to ensure there are no regressions. The toolchain binaries from
http://musl.cc/ should allow testing with a 64-bit time_t, but it may
be hard to build all the dependencies first.

libpcap has the same bug and needs a similar fix to work on future
32-bit Linux systems. Everything else apparently uses the generic
SO_TIMESTAMP timestamps, which work correctly when using new enough
kernels with a time64 libc.

Signed-off-by: Arnd Bergmann 
---
 monitor/hcidump.c | 32 +++-
 tools/hcidump.c   | 33 +++--
 2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/monitor/hcidump.c b/monitor/hcidump.c
index 8b6f846d3..6d2330287 100644
--- a/monitor/hcidump.c
+++ b/monitor/hcidump.c
@@ -107,6 +107,36 @@ static int open_hci_dev(uint16_t index)
return fd;
 }
 
+static struct timeval hci_tstamp_read(void *data)
+{
+   struct timeval tv;
+
+   /*
+* On 64-bit architectures, the data matches the timeval
+* format. Note that on sparc64 this is different from
+* all others.
+*/
+   if (sizeof(long) == 8) {
+   memcpy(, data, sizeof(tv));
+   }
+
+   /*
+* On 32-bit architectures, the timeval definition may
+* use 32-bit or 64-bit members depending on the C
+* library and architecture.
+* The cmsg data however always contains a pair of
+* 32-bit values. Interpret as unsigned to make it work
+* past y2038.
+*/
+   if (sizeof(long) == 4) {
+   unsigned int *stamp = data;
+   tv.tv_sec = stamp[0];
+   tv.tv_usec = stamp[1];
+   }
+
+   return tv;
+}
+
 static void device_callback(int fd, uint32_t events, void *user_data)
 {
struct hcidump_data *data = user_data;
@@ -150,7 +180,7 @@ static void device_callback(int fd, uint32_t events, void 
*user_data)
memcpy(, CMSG_DATA(cmsg), sizeof(dir));
break;
case HCI_CMSG_TSTAMP:
-   memcpy(, CMSG_DATA(cmsg), sizeof(ctv));
+   ctv = hci_tstamp_read(CMSG_DATA(cmsg));
tv = 
break;
}
diff --git a/tools/hcidump.c b/tools/hcidump.c
index 33d429b6c..be14d0930 100644
--- a/tools/hcidump.c
+++ b/tools/hcidump.c
@@ -136,6 +136,36 @@ static inline int write_n(int fd, char *buf, int len)
return t;
 }
 
+static struct timeval hci_tstamp_read(void *data)
+{
+   struct timeval tv;
+
+   /*
+* On 64-bit architectures, the data matches the timeval
+* format. Note that on sparc64 this is different from
+* all others.
+*/
+   if (sizeof(long) == 8) {
+   memcpy(, data, sizeof(tv));
+   }
+
+   /*
+* On 32-bit architectures, the timeval definition may
+* use 32-bit or 64-bit members depending on the C
+* library and architecture.
+* The cmsg data however always contains a pair of
+* 32-bit values. Interpret as unsigned to make it work
+* past y2038.
+*/
+   if (sizeof(long) == 4) {
+   unsigned int *stamp = data;
+   tv.tv_sec = stamp[0];
+   tv.tv_usec = stamp[1];
+   }
+
+   return tv;
+}
+
 static int process_frames(int dev, int sock, int fd, unsigned long flags)
 {
struct cmsghdr *cmsg;
@@ -230,8 +260,7 @@ static int process_frames(int dev, int sock, int fd, 
unsigned long flags)
frm.in = (uint8_t) dir;
break;
case HCI_CMSG_TSTAMP:
-   memcpy(, CMSG_DATA(cmsg),
-   sizeof(struct timeval));
+   frm.ts = hci_tstamp_read(CMSG_DATA(cmsg));
break;
}
cmsg = CMSG_NXTHDR(, cmsg);
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [RFC] y2038: HCI_TIME_STAMP with time64

2020-01-10 Thread Arnd Bergmann
On Fri, Jan 10, 2020 at 4:44 PM Marcel Holtmann  wrote:
> > I noticed earlier this week that the HCI_CMSG_TSTAMP/HCI_TIME_STAMP
> > interface has no time64 equivalent, as we apparently missed that when
> > converting the normal socket timestamps to support both time32 and time64
> > variants of the sockopt and cmsg data.
...
> > When using HCI_TIME_STAMP on a 32-bit system with a time64
> > libc, users will interpret the { s32 tv_sec; s32 tv_usec } layout of
> > the kernel as { s64 tv_sec; ... }, which puts complete garbage
> > into the timestamp regardless of whether this code runs before or
> > after y2038. From looking at codesearch.debian.org, I found two
> > users of this: libpcap and hcidump. There are probably others that
> > are not part of Debian.
...
> > 3. Add support for the normal SO_TIMESTAMPNS_NEW sockopt in
> >   HCI, providing timestamps in the unambiguous { long long tv_sec;
> >   long long tv_nsec; } format to user space, and change applications
> >   to use that if supported by the kernel.
>
> I have added SO_TIMESTAMP* to every Bluetooth socket a while back. And that 
> should be used by the majority of the tools. One exception might by hcidump 
> which has been replaced by btmon already anyway.
>
> So I would not bother with HCI_TIME_STAMP fixing. We can do 2) if someone 
> really still wants to use that socket option. However I am under the 
> impression that 3) should be already possible.

Ok, excellent, I had not realized this works already.

I have now also checked
https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-bt-monitor-linux.c
which uses SO_TIMESTAMP and then should work. I guess this is similar
to what btmon does.

For libpcap that leaves
https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-bt-linux.c#L358

which needs a fairly simply fix on 32-bit architectures to copy the
two 32-bit fields
into the longer pkth.ts fields individually rather than using a memcpy.
I've added Guy Harris to Cc, he seems to be the maintainer for this file
according to the git history.

The same change is needed for
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/hcidump.c#n233
if there are any remaining users. I can send you a patch if you want.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH 3/3] y2038: hide timeval/timespec/itimerval/itimerspec types

2020-01-10 Thread Arnd Bergmann
There are no in-kernel users remaining, but there may still
be users that include linux/time.h instead of sys/time.h
from user space, so leave the types available to user space
while hiding them from kernel space.

Only the __kernel_old_* versions of these types remain now.

Signed-off-by: Arnd Bergmann 
---
 include/uapi/asm-generic/posix_types.h |  2 ++
 include/uapi/linux/time.h  | 22 --
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/include/uapi/asm-generic/posix_types.h 
b/include/uapi/asm-generic/posix_types.h
index 2f9c80595ba7..b5f7594eee7a 100644
--- a/include/uapi/asm-generic/posix_types.h
+++ b/include/uapi/asm-generic/posix_types.h
@@ -87,7 +87,9 @@ typedef struct {
 typedef __kernel_long_t__kernel_off_t;
 typedef long long  __kernel_loff_t;
 typedef __kernel_long_t__kernel_old_time_t;
+#ifndef __KERNEL__
 typedef __kernel_long_t__kernel_time_t;
+#endif
 typedef long long __kernel_time64_t;
 typedef __kernel_long_t__kernel_clock_t;
 typedef int__kernel_timer_t;
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index a655aa28dc6e..4f4b6e48e01c 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -5,6 +5,7 @@
 #include 
 #include 
 
+#ifndef __KERNEL__
 #ifndef _STRUCT_TIMESPEC
 #define _STRUCT_TIMESPEC
 struct timespec {
@@ -18,6 +19,17 @@ struct timeval {
__kernel_suseconds_ttv_usec;/* microseconds */
 };
 
+struct itimerspec {
+   struct timespec it_interval;/* timer period */
+   struct timespec it_value;   /* timer expiration */
+};
+
+struct itimerval {
+   struct timeval it_interval;/* timer interval */
+   struct timeval it_value;/* current value */
+};
+#endif
+
 struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
@@ -31,16 +43,6 @@ struct timezone {
 #defineITIMER_VIRTUAL  1
 #defineITIMER_PROF 2
 
-struct itimerspec {
-   struct timespec it_interval;/* timer period */
-   struct timespec it_value;   /* timer expiration */
-};
-
-struct itimerval {
-   struct timeval it_interval; /* timer interval */
-   struct timeval it_value;/* current value */
-};
-
 /*
  * The IDs of the various system clocks (for POSIX.1b interval timers):
  */
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH 1/3] y2038: remove ktime to/from timespec/timeval conversion

2020-01-10 Thread Arnd Bergmann
A couple of helpers are now obsolete and can be removed, so drivers can
no longer start using them and instead use y2038-safe interfaces.

Signed-off-by: Arnd Bergmann 
---
 include/linux/ktime.h | 37 -
 1 file changed, 37 deletions(-)

diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index b2bb44f87f5a..d1fb05135665 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -66,33 +66,15 @@ static inline ktime_t ktime_set(const s64 secs, const 
unsigned long nsecs)
  */
 #define ktime_sub_ns(kt, nsval)((kt) - (nsval))
 
-/* convert a timespec to ktime_t format: */
-static inline ktime_t timespec_to_ktime(struct timespec ts)
-{
-   return ktime_set(ts.tv_sec, ts.tv_nsec);
-}
-
 /* convert a timespec64 to ktime_t format: */
 static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
 {
return ktime_set(ts.tv_sec, ts.tv_nsec);
 }
 
-/* convert a timeval to ktime_t format: */
-static inline ktime_t timeval_to_ktime(struct timeval tv)
-{
-   return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
-}
-
-/* Map the ktime_t to timespec conversion to ns_to_timespec function */
-#define ktime_to_timespec(kt)  ns_to_timespec((kt))
-
 /* Map the ktime_t to timespec conversion to ns_to_timespec function */
 #define ktime_to_timespec64(kt)ns_to_timespec64((kt))
 
-/* Map the ktime_t to timeval conversion to ns_to_timeval function */
-#define ktime_to_timeval(kt)   ns_to_timeval((kt))
-
 /* Convert ktime_t to nanoseconds */
 static inline s64 ktime_to_ns(const ktime_t kt)
 {
@@ -215,25 +197,6 @@ static inline ktime_t ktime_sub_ms(const ktime_t kt, const 
u64 msec)
 
 extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
 
-/**
- * ktime_to_timespec_cond - convert a ktime_t variable to timespec
- * format only if the variable contains data
- * @kt:the ktime_t variable to convert
- * @ts:the timespec variable to store the result in
- *
- * Return: %true if there was a successful conversion, %false if kt was 0.
- */
-static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
-  struct timespec *ts)
-{
-   if (kt) {
-   *ts = ktime_to_timespec(kt);
-   return true;
-   } else {
-   return false;
-   }
-}
-
 /**
  * ktime_to_timespec64_cond - convert a ktime_t variable to timespec64
  * format only if the variable contains data
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH 2/3] y2038: remove unused time32 interfaces

2020-01-10 Thread Arnd Bergmann
No users remain, so kill these off before we grow new ones.

Signed-off-by: Arnd Bergmann 
---
 include/linux/compat.h|  29 ---
 include/linux/time32.h| 154 +-
 include/linux/timekeeping32.h |  32 ---
 include/linux/types.h |   5 --
 kernel/compat.c   |  64 --
 kernel/time/time.c|  43 --
 6 files changed, 1 insertion(+), 326 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index 11083d84eb23..df2475be134a 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -248,15 +248,6 @@ typedef struct compat_siginfo {
} _sifields;
 } compat_siginfo_t;
 
-/*
- * These functions operate on 32- or 64-bit specs depending on
- * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments.
- */
-extern int compat_get_timespec(struct timespec *, const void __user *);
-extern int compat_put_timespec(const struct timespec *, void __user *);
-extern int compat_get_timeval(struct timeval *, const void __user *);
-extern int compat_put_timeval(const struct timeval *, void __user *);
-
 struct compat_iovec {
compat_uptr_t   iov_base;
compat_size_t   iov_len;
@@ -416,26 +407,6 @@ int copy_siginfo_to_user32(struct compat_siginfo __user 
*to, const kernel_siginf
 int get_compat_sigevent(struct sigevent *event,
const struct compat_sigevent __user *u_event);
 
-static inline int old_timeval32_compare(struct old_timeval32 *lhs,
-   struct old_timeval32 *rhs)
-{
-   if (lhs->tv_sec < rhs->tv_sec)
-   return -1;
-   if (lhs->tv_sec > rhs->tv_sec)
-   return 1;
-   return lhs->tv_usec - rhs->tv_usec;
-}
-
-static inline int old_timespec32_compare(struct old_timespec32 *lhs,
-   struct old_timespec32 *rhs)
-{
-   if (lhs->tv_sec < rhs->tv_sec)
-   return -1;
-   if (lhs->tv_sec > rhs->tv_sec)
-   return 1;
-   return lhs->tv_nsec - rhs->tv_nsec;
-}
-
 extern int get_compat_sigset(sigset_t *set, const compat_sigset_t __user 
*compat);
 
 /*
diff --git a/include/linux/time32.h b/include/linux/time32.h
index cad4c3186002..cf9320cd2d0b 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -12,8 +12,6 @@
 #include 
 #include 
 
-#define TIME_T_MAX (__kernel_old_time_t)((1UL << 
((sizeof(__kernel_old_time_t) << 3) - 1)) - 1)
-
 typedef s32old_time32_t;
 
 struct old_timespec32 {
@@ -73,162 +71,12 @@ struct __kernel_timex;
 int get_old_timex32(struct __kernel_timex *, const struct old_timex32 __user 
*);
 int put_old_timex32(struct old_timex32 __user *, const struct __kernel_timex 
*);
 
-#if __BITS_PER_LONG == 64
-
-/* timespec64 is defined as timespec here */
-static inline struct timespec timespec64_to_timespec(const struct timespec64 
ts64)
-{
-   return *(const struct timespec *)
-}
-
-static inline struct timespec64 timespec_to_timespec64(const struct timespec 
ts)
-{
-   return *(const struct timespec64 *)
-}
-
-#else
-static inline struct timespec timespec64_to_timespec(const struct timespec64 
ts64)
-{
-   struct timespec ret;
-
-   ret.tv_sec = (time_t)ts64.tv_sec;
-   ret.tv_nsec = ts64.tv_nsec;
-   return ret;
-}
-
-static inline struct timespec64 timespec_to_timespec64(const struct timespec 
ts)
-{
-   struct timespec64 ret;
-
-   ret.tv_sec = ts.tv_sec;
-   ret.tv_nsec = ts.tv_nsec;
-   return ret;
-}
-#endif
-
-static inline int timespec_equal(const struct timespec *a,
-const struct timespec *b)
-{
-   return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
-}
-
-/*
- * lhs < rhs:  return <0
- * lhs == rhs: return 0
- * lhs > rhs:  return >0
- */
-static inline int timespec_compare(const struct timespec *lhs, const struct 
timespec *rhs)
-{
-   if (lhs->tv_sec < rhs->tv_sec)
-   return -1;
-   if (lhs->tv_sec > rhs->tv_sec)
-   return 1;
-   return lhs->tv_nsec - rhs->tv_nsec;
-}
-
-/*
- * Returns true if the timespec is norm, false if denorm:
- */
-static inline bool timespec_valid(const struct timespec *ts)
-{
-   /* Dates before 1970 are bogus */
-   if (ts->tv_sec < 0)
-   return false;
-   /* Can't have more nanoseconds then a second */
-   if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
-   return false;
-   return true;
-}
-
-/**
- * timespec_to_ns - Convert timespec to nanoseconds
- * @ts:pointer to the timespec variable to be converted
- *
- * Returns the scalar nanosecond representation of the timespec
- * parameter.
- */
-static inline s64 timespec_to_ns(const struct timespec *ts)
-{
-   return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec

[Y2038] [PATCH 0/3] y2038: remove unused interfaces

2020-01-10 Thread Arnd Bergmann
Hi Andrew,

Can you add these to your patches for linux-5.6?

I have y2038 cleanups for sound, v4l, nfsd, scsi and xfs that are
merged in the respective subsystem trees, as well as another
series of individual patches queued up in my own y2038 tree.

With all that work merged, most of include/linux/time32.h
and some other related code can be removed from the kernel,
so it would be good to send these at the end of the coming
merge window, and to give them some more testing in linux-next
to make sure we don't gain any new users.

  Arnd

Arnd Bergmann (3):
  y2038: remove ktime to/from timespec/timeval conversion
  y2038: remove unused time32 interfaces
  y2038: hide timeval/timespec/itimerval/itimerspec types

 include/linux/compat.h |  29 -
 include/linux/ktime.h  |  37 --
 include/linux/time32.h | 154 +
 include/linux/timekeeping32.h  |  32 -
 include/linux/types.h  |   5 -
 include/uapi/asm-generic/posix_types.h |   2 +
 include/uapi/linux/time.h  |  22 ++--
 kernel/compat.c|  64 --
 kernel/time/time.c |  43 ---
 9 files changed, 15 insertions(+), 373 deletions(-)

-- 

Cc: y2038@lists.linaro.org
Cc: linux-ker...@vger.kernel.org
Cc: Thomas Gleixner 
Cc: Deepa Dinamani 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [RFC] y2038: HCI_TIME_STAMP with time64

2020-01-10 Thread Arnd Bergmann
I noticed earlier this week that the HCI_CMSG_TSTAMP/HCI_TIME_STAMP
interface has no time64 equivalent, as we apparently missed that when
converting the normal socket timestamps to support both time32 and time64
variants of the sockopt and cmsg data.

The interface was originally added back in 2002 by Maksim Krasnyanskiy
when bluetooth support first became non-experimental.

When using HCI_TIME_STAMP on a 32-bit system with a time64
libc, users will interpret the { s32 tv_sec; s32 tv_usec } layout of
the kernel as { s64 tv_sec; ... }, which puts complete garbage
into the timestamp regardless of whether this code runs before or
after y2038. From looking at codesearch.debian.org, I found two
users of this: libpcap and hcidump. There are probably others that
are not part of Debian.

Fixing this the same was as normal socket timestamps is not possible
because include/net/bluetooth/hci.h is not an exported UAPI header.
This means any changes to it for defining HCI_TIME_STAMP conditionally
would be ignored by applications that use a different copy of the
header.

I can see three possible ways forward:

1. move include/net/bluetooth/hci.h to include/uapi/, add a conditional
   definition of HCI_TIME_STAMP and make the kernel code support
   both formats. Then change applications to rely on that version of
   header file to get the correct definition but not change application code.

2. Leave the kernel completely unchanged and modify only the users
to not expect the output to be a 'struct timeval' but interpret as
as { uint32_t tv_sec; int32_t tv_usec; } structure on 32-bit architectures,
which will work until the unsigned time overflows 86 years from now
in 2106 (same as the libpcap on-disk format).

3. Add support for the normal SO_TIMESTAMPNS_NEW sockopt in
   HCI, providing timestamps in the unambiguous { long long tv_sec;
   long long tv_nsec; } format to user space, and change applications
   to use that if supported by the kernel.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [GIT PULL v3 00/27] block, scsi: final compat_ioctl cleanup

2020-01-03 Thread Arnd Bergmann
On Fri, Jan 3, 2020 at 1:22 AM Ben Hutchings
 wrote:
>
> On Thu, 2020-01-02 at 15:55 +0100, Arnd Bergmann wrote:
> [...]
> > Changes since v2:
> > - Rebase to v5.5-rc4, which contains the earlier bugfixes
> > - Fix sr_block_compat_ioctl() error handling bug found by
> >   Ben Hutchings
> [...]
>
> Unfortunately that fix was squashed into "compat_ioctl: move
> sys_compat_ioctl() to ioctl.c" whereas it belongs in "compat_ioctl:
> scsi: move ioctl handling into drivers".

Fixed now.

> If you decide to rebase again, you can add my Reviewed-by to all
> patches.

Done, and pushed out to the same tag as before

https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/
block-ioctl-cleanup-5.6

Thank you again for the careful review!

Martin, please pull the URL above to get the latest version, the top commit
is 8ce156deca718 ("Documentation: document ioctl interfaces better").

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v3 2/2] xfs: quota: move to time64_t interfaces

2020-01-02 Thread Arnd Bergmann
As a preparation for removing the 32-bit time_t type and
all associated interfaces, change xfs to use time64_t and
ktime_get_real_seconds() for the quota housekeeping.

This avoids one difference between 32-bit and 64-bit kernels,
raising the theoretical limit for the quota grace period
to year 2106 on 32-bit instead of year 2038.

Note that common user space tools using the XFS quotactl
interface instead of the generic one still use the y2038
dates.

To fix quotas properly, both the on-disk format and user
space still need to be changed.

Signed-off-by: Arnd Bergmann 
---
This has a small conflict against the series at
https://www.spinics.net/lists/linux-xfs/msg35409.html
("xfs: widen timestamps to deal with y2038") which needs
to be rebased on top of this.

All other changes to remove time_t and get_seconds()
are now in linux-next, this is one of the last patches
needed to remove their definitions for v5.6.

If the widened timestamps make it into v5.6, this patch
can be dropped.
---
 fs/xfs/xfs_dquot.c   | 6 +++---
 fs/xfs/xfs_qm.h  | 6 +++---
 fs/xfs/xfs_quotaops.c| 6 +++---
 fs/xfs/xfs_trans_dquot.c | 8 +---
 4 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 2bff21ca9d78..9cfd3209f52b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -137,7 +137,7 @@ xfs_qm_adjust_dqtimers(
(d->d_blk_hardlimit &&
 (be64_to_cpu(d->d_bcount) >
  be64_to_cpu(d->d_blk_hardlimit {
-   d->d_btimer = cpu_to_be32(get_seconds() +
+   d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_btimelimit);
} else {
d->d_bwarns = 0;
@@ -160,7 +160,7 @@ xfs_qm_adjust_dqtimers(
(d->d_ino_hardlimit &&
 (be64_to_cpu(d->d_icount) >
  be64_to_cpu(d->d_ino_hardlimit {
-   d->d_itimer = cpu_to_be32(get_seconds() +
+   d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_itimelimit);
} else {
d->d_iwarns = 0;
@@ -183,7 +183,7 @@ xfs_qm_adjust_dqtimers(
(d->d_rtb_hardlimit &&
 (be64_to_cpu(d->d_rtbcount) >
  be64_to_cpu(d->d_rtb_hardlimit {
-   d->d_rtbtimer = cpu_to_be32(get_seconds() +
+   d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_rtbtimelimit);
} else {
d->d_rtbwarns = 0;
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 7823af39008b..4e57edca8bce 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -64,9 +64,9 @@ struct xfs_quotainfo {
struct xfs_inode*qi_pquotaip;   /* project quota inode */
struct list_lru  qi_lru;
int  qi_dquots;
-   time_t   qi_btimelimit;  /* limit for blks timer */
-   time_t   qi_itimelimit;  /* limit for inodes timer */
-   time_t   qi_rtbtimelimit;/* limit for rt blks timer */
+   time64_t qi_btimelimit;  /* limit for blks timer */
+   time64_t qi_itimelimit;  /* limit for inodes timer */
+   time64_t qi_rtbtimelimit;/* limit for rt blks timer */
xfs_qwarncnt_t   qi_bwarnlimit;  /* limit for blks warnings */
xfs_qwarncnt_t   qi_iwarnlimit;  /* limit for inodes warnings */
xfs_qwarncnt_t   qi_rtbwarnlimit;/* limit for rt blks warnings */
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index c7de17deeae6..38669e827206 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -37,9 +37,9 @@ xfs_qm_fill_state(
tstate->flags |= QCI_SYSFILE;
tstate->blocks = ip->i_d.di_nblocks;
tstate->nextents = ip->i_d.di_nextents;
-   tstate->spc_timelimit = q->qi_btimelimit;
-   tstate->ino_timelimit = q->qi_itimelimit;
-   tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
+   tstate->spc_timelimit = (u32)q->qi_btimelimit;
+   tstate->ino_timelimit = (u32)q->qi_itimelimit;
+   tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit;
tstate->spc_warnlimit = q->qi_bwarnlimit;
tstate->ino_warnlimit = q->qi_iwarnlimit;
tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index a6fe2d8dc40f..d1b9869bc5fa 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -580,7 +580,7 @@ xfs_trans_dqresv(
 {
xfs_qcnt_t  hardlimit;
xfs_qcnt_

[Y2038] [PATCH v3 1/2] xfs: rename compat_time_t to old_time32_t

2020-01-02 Thread Arnd Bergmann
The compat_time_t type has been removed everywhere else,
as most users rely on old_time32_t for both native and
compat mode handling of 32-bit time_t.

Remove the last one in xfs.

Reviewed-by: Darrick J. Wong 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Arnd Bergmann 
---
As explained in https://www.spinics.net/lists/linux-xfs/msg35524.html
I've dropped the patch "xfs: disallow broken ioctls without
compat-32-bit-time" for this submission but will get to that later
when doing that as a treewide change.

Please apply these two for v5.6 in the meantime so we can kill off
compat_time_t, time_t and get_seconds() for good.

 fs/xfs/xfs_ioctl32.c | 2 +-
 fs/xfs/xfs_ioctl32.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index bd07a79ca3c0..9ab0263586da 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -108,7 +108,7 @@ xfs_ioctl32_bstime_copyin(
xfs_bstime_t*bstime,
compat_xfs_bstime_t __user *bstime32)
 {
-   compat_time_t   sec32;  /* tv_sec differs on 64 vs. 32 */
+   old_time32_tsec32;  /* tv_sec differs on 64 vs. 32 */
 
if (get_user(sec32, >tv_sec)  ||
get_user(bstime->tv_nsec,   >tv_nsec))
diff --git a/fs/xfs/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h
index 8c7743cd490e..053de7d894cd 100644
--- a/fs/xfs/xfs_ioctl32.h
+++ b/fs/xfs/xfs_ioctl32.h
@@ -32,7 +32,7 @@
 #endif
 
 typedef struct compat_xfs_bstime {
-   compat_time_t   tv_sec; /* seconds  */
+   old_time32_ttv_sec; /* seconds  */
__s32   tv_nsec;/* and nanoseconds  */
 } compat_xfs_bstime_t;
 
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH 2/3] xfs: disallow broken ioctls without compat-32-bit-time

2020-01-02 Thread Arnd Bergmann
On Thu, Jan 2, 2020 at 10:16 AM Arnd Bergmann  wrote:
> On Tue, Dec 24, 2019 at 9:45 AM Christoph Hellwig  wrote:
> > On Wed, Dec 18, 2019 at 05:39:29PM +0100, Arnd Bergmann wrote:
> > > +/* disallow y2038-unsafe ioctls with CONFIG_COMPAT_32BIT_TIME=n */
> > > +static bool xfs_have_compat_bstat_time32(unsigned int cmd)
> > > +{
> > > + if (IS_ENABLED(CONFIG_COMPAT_32BIT_TIME))
> > > + return true;
> > > +
> > > + if (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall())
> > > + return true;
> > > +
> > > + if (cmd == XFS_IOC_FSBULKSTAT_SINGLE ||
> > > + cmd == XFS_IOC_FSBULKSTAT ||
> > > + cmd == XFS_IOC_SWAPEXT)
> > > + return false;
> > > +
> > > + return true;
> >
> > I think the check for the individual command belongs into the callers,
> > which laves us with:
> >
> > static inline bool have_time32(void)
> > {
> > return IS_ENABLED(CONFIG_COMPAT_32BIT_TIME) ||
> > (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall());
> > }
> >
> > and that looks like it should be in a generic helper somewhere.
>
> Yes, makes sense.
>
> I was going for something XFS specific here because XFS is unique in the
> kernel in completely deprecating a set of ioctl commands (replacing
> the old interface with a v5) rather than allowing the user space to be
> compiled with 64-bit time_t.

I tried adding the helper now but ran into a stupid problem: the best
place to put it would be linux/time32.h, but then I have to include
linux/compat.h from there, which in turn pulls in tons of other
headers in any file using linux/time.h.

I considered making it a macro instead, but that's also really ugly.

I now think we should just defer this change until after v5.6, once I
have separated linux/time.h from linux/time32.h.
In the meantime I'll resend the other two patches that I know we
need in v5.6 in order to get there, so Darrick can apply them to his
tree.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [GIT PULL v3 00/27] block, scsi: final compat_ioctl cleanup

2020-01-02 Thread Arnd Bergmann
On Thu, Jan 2, 2020 at 3:56 PM Arnd Bergmann  wrote:
>
> Hi Martin, James,
>
> If this version seems ok to everyone, please pull into
> the scsi tree.

It seems I slightly messed up the Cc list here, in case some of you are
missing patches, the full series (22 patches, not 27) is mirrored at
https://lore.kernel.org/lkml/20200102145552.1853992-1-a...@arndb.de/T/
as well.

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [GIT PULL v3 00/27] block, scsi: final compat_ioctl cleanup

2020-01-02 Thread Arnd Bergmann
Hi Martin, James,

If this version seems ok to everyone, please pull into
the scsi tree.

The following changes since commit e42617b825f8073569da76dc4510bfa019b1c35a:

  Linux 5.5-rc4 (2019-12-08 14:57:55 -0800)

are available in the Git repository at:

  git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git 
tags/block-ioctl-cleanup-5.6

for you to fetch changes up to d1329555e914109846283e469b5077e7500ecfaf

  Documentation: document ioctl interfaces better (2019-12-17 22:45:18 +0100)


block, scsi: final compat_ioctl cleanup

This series concludes the work I did for linux-5.5 on the compat_ioctl()
cleanup, killing off fs/compat_ioctl.c and block/compat_ioctl.c by moving
everything into drivers.

Overall this would be a reduction both in complexity and line count, but
as I'm also adding documentation the overall number of lines increases
in the end.

My plan was originally to keep the SCSI and block parts separate.
This did not work easily because of interdependencies: I cannot
do the final SCSI cleanup in a good way without first addressing the
CDROM ioctls, so this is one series that I hope could be merged through
either the block or the scsi git trees, or possibly both if you can
pull in the same branch.

The series comes in these steps:

1. clean up the sg v3 interface as suggested by Linus. I have
   talked about this with Doug Gilbert as well, and he would
   rebase his sg v4 patches on top of "compat: scsi: sg: fix v3
   compat read/write interface"

2. Actually moving handlers out of block/compat_ioctl.c and
   block/scsi_ioctl.c into drivers, mixed in with cleanup
   patches

3. Document how to do this right. I keep getting asked about this,
   and it helps to point to some documentation file.

The branch is based on another one that fixes a couple of bugs found
during the creation of this series.

Changes since v2:
- Rebase to v5.5-rc4, which contains the earlier bugfixes
- Fix sr_block_compat_ioctl() error handling bug found by
  Ben Hutchings
- Fix idecd_locked_compat_ioctl() compat_ptr() bug
- Don't try to handle HDIO_DRIVE_TASKFILE in drivers/ide
- More documentation improvements

Changes since v1:
- move out the bugfixes into a branch for itself
- clean up scsi sg driver further as suggested by Christoph Hellwig
- avoid some ifdefs by moving compat_ptr() out of asm/compat.h
- split out the blkdev_compat_ptr_ioctl function; bug spotted by
  Ben Hutchings
- Improve formatting of documentation

[1] 
https://lore.kernel.org/linux-block/20191211204306.1207817-1-a...@arndb.de/T/#m9f89df30565fc66abbded5d01f4db553b16f129f

----

Arnd Bergmann (22):
  compat: ARM64: always include asm-generic/compat.h
  compat: provide compat_ptr() on all architectures
  compat: scsi: sg: fix v3 compat read/write interface
  compat_ioctl: block: add blkdev_compat_ptr_ioctl
  compat_ioctl: ubd, aoe: use blkdev_compat_ptr_ioctl
  compat_ioctl: move CDROM_SEND_PACKET handling into scsi
  compat_ioctl: move CDROMREADADIO to cdrom.c
  compat_ioctl: cdrom: handle CDROM_LAST_WRITTEN
  compat_ioctl: block: handle cdrom compat ioctl in non-cdrom drivers
  compat_ioctl: add scsi_compat_ioctl
  compat_ioctl: bsg: add handler
  compat_ioctl: ide: floppy: add handler
  compat_ioctl: scsi: move ioctl handling into drivers
  compat_ioctl: move sys_compat_ioctl() to ioctl.c
  compat_ioctl: simplify the implementation
  compat_ioctl: move cdrom commands into cdrom.c
  compat_ioctl: scsi: handle HDIO commands from drivers
  compat_ioctl: move HDIO ioctl handling into drivers/ide
  compat_ioctl: block: move blkdev_compat_ioctl() into ioctl.c
  compat_ioctl: block: simplify compat_blkpg_ioctl()
  compat_ioctl: simplify up block/ioctl.c
  Documentation: document ioctl interfaces better

 Documentation/core-api/index.rst   |   1 +
 Documentation/core-api/ioctl.rst   | 253 +++
 arch/arm64/include/asm/compat.h|  22 +-
 arch/mips/include/asm/compat.h |  18 --
 arch/parisc/include/asm/compat.h   |  17 -
 arch/powerpc/include/asm/compat.h  |  17 -
 arch/powerpc/oprofile/backtrace.c  |   2 +-
 arch/s390/include/asm/compat.h |   6 +-
 arch/sparc/include/asm/compat.h|  17 -
 arch/um/drivers/ubd_kern.c |   1 +
 arch/x86/include/asm/compat.h  |  17 -
 block/Makefile |   1 -
 block/bsg.c|   1 +
 block/compat_ioctl.c   | 427 -
 block/ioctl.c  | 319 ++
 block/scsi_ioctl.c | 214 -
 drivers/ata/libata-scsi.c  |   9 +
 drivers/block/aoe/aoeblk.c |   1 +
 drivers/block/floppy.c |   3 +
 drivers/block/paride/pcd.c |   3 +
 drivers/block/paride/pd.c  |   1 +
 drivers/block/paride/pf.c  |   1 

Re: [Y2038] [PATCH 2/3] xfs: disallow broken ioctls without compat-32-bit-time

2020-01-02 Thread Arnd Bergmann
On Tue, Dec 24, 2019 at 9:45 AM Christoph Hellwig  wrote:
> On Wed, Dec 18, 2019 at 05:39:29PM +0100, Arnd Bergmann wrote:
> > +/* disallow y2038-unsafe ioctls with CONFIG_COMPAT_32BIT_TIME=n */
> > +static bool xfs_have_compat_bstat_time32(unsigned int cmd)
> > +{
> > + if (IS_ENABLED(CONFIG_COMPAT_32BIT_TIME))
> > + return true;
> > +
> > + if (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall())
> > + return true;
> > +
> > + if (cmd == XFS_IOC_FSBULKSTAT_SINGLE ||
> > + cmd == XFS_IOC_FSBULKSTAT ||
> > + cmd == XFS_IOC_SWAPEXT)
> > + return false;
> > +
> > + return true;
>
> I think the check for the individual command belongs into the callers,
> which laves us with:
>
> static inline bool have_time32(void)
> {
> return IS_ENABLED(CONFIG_COMPAT_32BIT_TIME) ||
> (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall());
> }
>
> and that looks like it should be in a generic helper somewhere.

Yes, makes sense.

I was going for something XFS specific here because XFS is unique in the
kernel in completely deprecating a set of ioctl commands (replacing
the old interface with a v5) rather than allowing the user space to be
compiled with 64-bit time_t.

If we add a global helper for this, I'd be tempted to also stick a
WARN_RATELIMIT() in there to give users a better indication of
what broke after disabling CONFIG_COMPAT_32BIT_TIME.

The same warning would make sense in the system calls, but then
we have to decide which combinations we want to allow being
configured at runtime or compile-time.

a) unmodified behavior
b) just warn but allow
c) no warning but disallow
d) warn and disallow

> >   if (XFS_FORCED_SHUTDOWN(mp))
> >   return -EIO;
> >
> > @@ -1815,6 +1836,11 @@ xfs_ioc_swapext(
> >   struct fd   f, tmp;
> >   int error = 0;
> >
> > + if (!xfs_have_compat_bstat_time32(XFS_IOC_SWAPEXT)) {
> > + error = -EINVAL;
> > + goto out;
> > + }
>
> And for this one we just have one cmd anyway.  But I actually still
> disagree with the old_time check for this one entirely, as voiced on
> one of the last iterations.  For swapext the time stamp really is
> only used as a generation counter, so overflows are entirely harmless.

Sorry I missed that comment earlier. I've had a fresh look now, but
I think we still need to deprecate XFS_IOC_SWAPEXT and add a
v5 version of it, since the comparison will fail as soon as the range
of the inode timestamps is extended beyond 2038, otherwise the
comparison will always be false, or require comparing the truncated
time values which would add yet another representation.

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 27/27] Documentation: document ioctl interfaces better

2019-12-19 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 11:45 PM Ben Hutchings
 wrote:
> On Tue, 2019-12-17 at 23:17 +0100, Arnd Bergmann wrote:
> > --- /dev/null
> > +++ b/Documentation/core-api/ioctl.rst
> > +``include/uapi/asm-generic/ioctl.h`` provides four macros for defining
> > +ioctl commands that follow modern conventions: ``_IO``, ``_IOR``,
> > +``_IOW``, and ``_IORW``. These should be used for all new commands,
>
> Typo: "_IORW" should be "_IOWR".

Fixed now

> > +with the correct parameters:
> > +
> > +_IO/_IOR/_IOW/_IOWR
> > +   The macro name determines whether the argument is used for passing
> > +   data into kernel (_IOW), from the kernel (_IOR), both (_IOWR) or is
> > +   not a pointer (_IO). It is possible but not recommended to pass an
> > +   integer value instead of a pointer with _IO.
>
> I feel the explanation of _IO here could be confusing.  I think what
> you meant to say was that it is possible, but not recommended, to pass
> integers directly (arg is integer) rather than indirectly (arg is
> pointer to integer).  I suggest the alternate wording:
>
> The macro name specifies how the argument will be used.  It may be a
> pointer to data to be passed into the kernel (_IOW), out of the kernel
> (_IOR), or both (_IOWR).  The argument may also be an integer value
> instead of a pointer (_IO), but this is not recommended.

That's probably better than my version, but I find that misleading as well:
it sounds like _IO() is not recommended, but having no argument with
_IO() is actually fine. This is what I have now:

   The macro name specifies how the argument will be used.  It may be a
   pointer to data to be passed into the kernel (_IOW), out of the kernel
   (_IOR), or both (_IOWR).  _IO can indicate either commands with no
   argument or those passing an integer value instead of a pointer.
   It is recommended to only use _IO for commands without arguments,
   and use pointers for passing data.


> > +data_type
> > +  The name of the data type pointed to by the argument, the command number
> > +  encodes the ``sizeof(data_type)`` value in a 13-bit or 14-bit integer,
> > +  leading to a limit of 8191 bytes for the maximum size of the argument.
> > +  Note: do not pass sizeof(data_type) type into _IOR/IOW, as that will
> > +  lead to encoding sizeof(sizeof(data_type)), i.e. sizeof(size_t).
>
> You left out _IOWR here.  It might also be worth mentioning that _IO
> doesn't have this parameter.

Changed now.

> [...]
> > +Return code
> > +===
> > +
> > +ioctl commands can return negative error codes as documented in errno(3),
> > +these get turned into errno values in user space.
>
> Use a semi-colon instead of a comma, or change "these" to "which".

done

> > On success, the return
> > +code should be zero. It is also possible but not recommended to return
> > +a positive 'long' value.
> > +
> > +When the ioctl callback is called with an unknown command number, the
> > +handler returns either -ENOTTY or -ENOIOCTLCMD, which also results in
> > +-ENOTTY being returned from the system call. Some subsystems return
> > +-ENOSYS or -EINVAL here for historic reasons, but this is wrong.
> > +
> > +Prior to Linux-5.5, compat_ioctl handlers were required to return
>
> Space instead of hyphen.

done

> > +-ENOIOCTLCMD in order to use the fallback conversion into native
> > +commands. As all subsystems are now responsible for handling compat
> > +mode themselves, this is no longer needed, but it may be important to
> > +consider when backporting bug fixes to older kernels.
> > +
> > +Timestamps
> > +==
> > +
> > +Traditionally, timestamps and timeout values are passed as ``struct
> > +timespec`` or ``struct timeval``, but these are problematic because of
> > +incompatible definitions of these structures in user space after the
> > +move to 64-bit time_t.
> > +
> > +The __kernel_timespec type can be used instead to be embedded in other
>
> It's not a typedef, so ``struct __kernel_timespec``.

done

> [...]
> > +32-bit compat mode
> > +==
> > +
> > +In order to support 32-bit user space running on a 64-bit machine, each
> > +subsystem or driver that implements an ioctl callback handler must also
> > +implement the corresponding compat_ioctl handler.
> > +
> > +As long as all the rules for data structures are followed, this is as
> > +easy as setting the .compat_ioctl pointer to a helper function such as
> > +compat_ptr_ioctl() or blkdev_compat_ptr_ioctl().
> > +
> > +compat_ptr()
> > +
> > +
> >

Re: [Y2038] [PATCH v2 21/27] compat_ioctl: move cdrom commands into cdrom.c

2019-12-19 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 9:11 PM Ben Hutchings
 wrote:
>
> On Tue, 2019-12-17 at 23:17 +0100, Arnd Bergmann wrote:
> [...]
> > @@ -1710,6 +1711,38 @@ static int idecd_ioctl(struct block_device *bdev, 
> > fmode_t mode,
> >   return ret;
> >  }
> >
> > +#ifdef CONFIG_COMPAT
> > +static int idecd_locked_compat_ioctl(struct block_device *bdev, fmode_t 
> > mode,
> > + unsigned int cmd, unsigned long arg)
> > +{
> > + struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
> > + int err;
> > +
> > + switch (cmd) {
> > + case CDROMSETSPINDOWN:
> > + return idecd_set_spindown(>devinfo, arg);
> > + case CDROMGETSPINDOWN:
> > + return idecd_get_spindown(>devinfo, arg);
>
> compat_ptr() should also be applied to the argument for these two
> commands, though I'm fairly sure IDE drivers have never been useful on
> s390 so it doesn't matter in practice.

Agreed on both, fixed by folding in this change:

diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2de6e8ace957..e09b949a7c46 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1716,19 +1716,20 @@ static int idecd_locked_compat_ioctl(struct
block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
 {
struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
+   void __user *argp = compat_ptr(arg);
int err;

switch (cmd) {
case CDROMSETSPINDOWN:
-   return idecd_set_spindown(>devinfo, arg);
+   return idecd_set_spindown(>devinfo, (unsigned long)argp);
case CDROMGETSPINDOWN:
-   return idecd_get_spindown(>devinfo, arg);
+   return idecd_get_spindown(>devinfo, (unsigned long)argp);
default:
break;
}

return cdrom_ioctl(>devinfo, bdev, mode, cmd,
-  (unsigned long)compat_ptr(arg));
+  (unsigned long)argp);
 }

static int idecd_compat_ioctl(struct block_device *bdev, fmode_t mode,

Unfortunately the generic_ide_ioctl() call still needs an unconverted arg,
so I can't just use compat_ptr() to call the native idecd_locked_ioctl()
for all commands.

Thanks,

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 18/27] compat_ioctl: scsi: move ioctl handling into drivers

2019-12-19 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 8:57 PM Ben Hutchings
 wrote:
>
> On Tue, 2019-12-17 at 23:16 +0100, Arnd Bergmann wrote:
> > +
> > + /*
> > +  * CDROM ioctls are handled in the block layer, but
> > +  * do the scsi blk ioctls here.
> > +  */
> > + ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
> > + if (ret != -ENOTTY)
> > + return ret;
>
> This needs to be be "goto put;"

Fixed now, thanks!

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH] generic/402: fix for updated behavior of timestamp limits

2019-12-19 Thread Arnd Bergmann
On Thu, Dec 19, 2019 at 9:40 AM Greg KH  wrote:
> On Thu, Dec 19, 2019 at 09:28:23AM +0100, Arnd Bergmann wrote:
> > On Wed, Dec 18, 2019 at 9:46 PM Amir Goldstein  wrote:
> >
> > [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
>
> Ugh, that's a mess.  Why not just use 5.4 if people really care about
> this type of thing?
>
> But yes, on their own, each individual patch would be fine for stable,
> it's just that I would want someone to "own" the backport and testing of
> such a thing.  If for no other reason than to have someone to "blame"
> for when things go wrong and get them to fix up the fallout :)

I was going to volunteer Deepa and me, but I just tried out what a backport
would look like, and backporting to v4.14 or earlier would involve a
major rewrite unless we also backport Deepa's earlier y2038 patches that
are much more invasive. Backporting to v4.19 (across the mount API
change) would be possible, but this doesn't really help the cause of
getting xfstests to report correct behavior on all stable kernels.

> Who really really wants this in their older kernels?  And are those same
> people already taking all of the stable updates for those kernels as
> well?

I see two potential groups of people:

- the one that started this thread: xfstests correctly reports a failure on
  stable kernels that have a known problem with compliance. If you are
  aiming for 100% pass rate on a test suite, you can either mark a correct
  test case as "skip", or backport the fix. Neither one is super attractive
  here, but it seemed worth considering which one is more harmful. (I
  guess I answered that now -- backporting to v4.14 would be more
  harmful)

- Users of CIP SLTS kernels with extreme service life that may involve
  not upgrading until after y2038 (this is obviously not recommended if
  you connect to a public network, but I'm sure some people do this anyway).
  For running user space, this requires either a 32-bit kernel with the
  linux-5.1 syscall changes or a 64-bit kernel. If you run a 64-bit linux-4.9
  kernel in a deeply embedded non-networked machine, it still makes
  sense to have working inode timestamps and be able to test that.

It may still make sense to backport this to linux-4.19.y-cip or another
downstream version of 4.19, but let's not do it for the normal LTS
kernels then.

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH] generic/402: fix for updated behavior of timestamp limits

2019-12-19 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 9:46 PM Amir Goldstein  wrote:
>
> I don't think there is a clear policy about being friendly to testing
> less that master kernels in xfstest (Eryu?), but IMO we should try to
> accommodate
> this use case, because it is in the best interest of everyone that stable 
> kernel
> will be regularly tested with xfstests with as little noisy failures
> as possible.

I think what makes this one particularly hard is that there are most likely
people that do care about the failure on older kernels being reported and
would rather backport the kernel changes into their product kernels
to have them behave sanely.

I'm also not sure if we could just backport the changes to stable
kernels after all.

Greg, do you have an opinion on whether the 19 patches from
v5.3-rc6 to cba465b4f982 can be considered stable material?

The best argument that I have seen in favor of treating it as a bugfix
is that the posx man pages require that "The file's relevant timestamp shall
be set to the greatest value supported by the file system that is not greater
than the specified time"[1], and this is something that Linux has always
done wrong before the series (we overflow and underflow out-of-range
arguments to a value that is both file system and CPU architecture
specific).

The main argument against backporting would be that 19 patches
is too much, I think each patch in the series would qualify on its own.
Changing the layout of 'struct super_block' also breaks the module
binary interface, which will annoy some distros that care about this,
but I don't think it's stopping us from adding the patch to a stable
kernel.

   Arnd

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 23/27] compat_ioctl: move HDIO ioctl handling into drivers/ide

2019-12-18 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 10:11 PM Ben Hutchings
 wrote:
> On Tue, 2019-12-17 at 23:17 +0100, Arnd Bergmann wrote:
> > Most of the HDIO ioctls are only used by the obsolete drivers/ide
> > subsystem, these can be handled by changing ide_cmd_ioctl() to be aware
> > of compat mode and doing the correct transformations in place and using
> > it as both native and compat handlers for all drivers.
> >
> > The SCSI drivers implementing the same commands are already doing
> > this in the drivers, so the compat_blkdev_driver_ioctl() function
> > is no longer needed now.
> >
> > The BLKSECTSET and HDIO_GETGEO_BIG ioctls are not implemented
> > in any driver any more and no longer need any conversion.
> [...]
>
> I noticed that HDIO_DRIVE_TASKFILE, handled by ide_taskfile_ioctl() in
> drivers/ide/ide-taskfile.c, never had compat handling before.  After
> this patch it does, but its argument isn't passed through compat_ptr().
> Again, doesn't really matter because IDE isn't a thing on s390.

I checked again, and I think it's worse than that: ide_taskfile_ioctl()
takes an ide_task_request_t argument, which is not compatible
at all (it has two long members). I suspect what happened here
is that I confused it with ide_cmd_ioctl(), which takes a 'struct
ide_taskfile' argument that /is/ compatible.

I don't think there is a point in adding a handler now: most
users of drivers/ide are 32-bit only, and nobody complained
so far, but I would add this change if you agree:

diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index f6497c817493..83afee3983fe 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -270,6 +270,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct
block_device *bdev,
case HDIO_DRIVE_TASKFILE:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
+   /* missing compat handler for HDIO_DRIVE_TASKFILE */
+   if (in_compat_syscall())
+   return -ENOTTY;
if (drive->media == ide_disk)
return ide_taskfile_ioctl(drive, arg);
return -ENOMSG;



 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 17/27] compat_ioctl: ide: floppy: add handler

2019-12-18 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 7:45 PM Ben Hutchings
 wrote:
>
> On Tue, 2019-12-17 at 23:16 +0100, Arnd Bergmann wrote:
> > Rather than relying on fs/compat_ioctl.c, this adds support
> > for a compat_ioctl() callback in the ide-floppy driver directly,
> > which lets it translate the scsi commands.
> [...]
>
> After this, and before "compat_ioctl: move HDIO ioctl handling into
> drivers/ide", compat ioctls on an IDE hard drive will result in a null
> pointer dereference in ide_gd_compat_ioctl().  Not sure how much that
> really matters though.

I'm sure it makes no difference in the end, but you are of course right that
this is a bug. I've folded in a check now, and leaving that in place
even after it is no longer needed:

--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -348,6 +348,9 @@ static int ide_gd_compat_ioctl(struct block_device
*bdev, fmode_t mode,
struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;

+   if (!drive->disk_ops->compat_ioctl)
+   return -ENOIOCTLCMD;
+
return drive->disk_ops->compat_ioctl(drive, bdev, mode, cmd, arg);
 }
 #endif

I pushed out an updated signed tag with this change.

Thanks for the continued careful review!

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 00/12] nfsd: avoid 32-bit time_t

2019-12-18 Thread Arnd Bergmann
On Wed, Dec 18, 2019 at 6:25 PM J. Bruce Fields  wrote:
> On Wed, Dec 18, 2019 at 06:21:06PM +0100, Arnd Bergmann wrote:
> > On Fri, Dec 13, 2019 at 3:12 PM Arnd Bergmann  wrote:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git 
> > y2038-nfsd-v2
> >
> > in my y2038 branch now, so it should be part of linux-next from the coming
> > snapshot. My plan is to send a linux-5.6 pull request to the nfsd
> > maintainers for
> > this branch unless we find bugs in linux-next or I get more review comments.
>
> Sorry for the silence.  The patches look fine to me, so I took them from
> your git branch and applied them to my local tree (after fixing up some
> minor conflicts with the copy patches) and then saw some
> delegation-related test failures, which I haven't had the chance to
> investigate yet.  Hopefully before the end of the week.

Ok, I've taken the nfsd changes out of my y2038 branch again then, to
make sure we don't get these regressions in linux-next.

Thanks for taking care of the patches. I will not be in the office from
Friday to the end of the year, so probably won't be able to respin the
series quickly once you find the bug(s), but I should be able to reply
to emails about this.

  Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [GIT PULL v2 00/27] block, scsi: final compat_ioctl cleanup

2019-12-18 Thread Arnd Bergmann
On Tue, Dec 17, 2019 at 11:17 PM Arnd Bergmann  wrote:
> My plan was originally to keep the SCSI and block parts separate.
> This did not work easily because of interdependencies: I cannot
> do the final SCSI cleanup in a good way without first addressing the
> CDROM ioctls, so this is one series that I hope could be merged through
> either the block or the scsi git trees, or possibly both if you can
> pull in the same branch.

I have included the branch in my y2038 branch now, it should show up
in the following linux-next snapshots, but I'm still hoping for the block
or scsi maintainers to merge the pull request into their trees for v5.6

Jens, James, Martin:

Any suggestion for how this should be merged?

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 00/12] nfsd: avoid 32-bit time_t

2019-12-18 Thread Arnd Bergmann
On Fri, Dec 13, 2019 at 3:12 PM Arnd Bergmann  wrote:
>
> Hi Bruce, Chuck,
>
> NFSd is one of the last areas of the kernel that is not y2038 safe
> yet, this series addresses the remaining issues here.
>
> I did not get any comments for the first version I posted [1], and
> I hope this just means that everything was fine and you plan to
> merge this soon ;-)
>
> I uploaded a git branch to [2] for testing.
>
> Please review and merge for linux-5.6 so we can remove the 32-bit
> time handling from that release.

I've included the update y2038 nfsd branch from

git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git y2038-nfsd-v2

in my y2038 branch now, so it should be part of linux-next from the coming
snapshot. My plan is to send a linux-5.6 pull request to the nfsd
maintainers for
this branch unless we find bugs in linux-next or I get more review comments.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH 3/3] xfs: quota: move to time64_t interfaces

2019-12-18 Thread Arnd Bergmann
As a preparation for removing the 32-bit time_t type and
all associated interfaces, change xfs to use time64_t and
ktime_get_real_seconds() for the quota housekeeping.

This avoids one difference between 32-bit and 64-bit kernels,
raising the theoretical limit for the quota grace period
to year 2106 on 32-bit instead of year 2038.

Note that common user space tools using the XFS quotactl
interface instead of the generic one still use the y2038
dates.

To fix quotas properly, both the on-disk format and user
space still need to be changed.

Signed-off-by: Arnd Bergmann 
---
 fs/xfs/xfs_dquot.c   | 6 +++---
 fs/xfs/xfs_qm.h  | 6 +++---
 fs/xfs/xfs_quotaops.c| 6 +++---
 fs/xfs/xfs_trans_dquot.c | 8 +---
 4 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 2bff21ca9d78..9cfd3209f52b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -137,7 +137,7 @@ xfs_qm_adjust_dqtimers(
(d->d_blk_hardlimit &&
 (be64_to_cpu(d->d_bcount) >
  be64_to_cpu(d->d_blk_hardlimit {
-   d->d_btimer = cpu_to_be32(get_seconds() +
+   d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_btimelimit);
} else {
d->d_bwarns = 0;
@@ -160,7 +160,7 @@ xfs_qm_adjust_dqtimers(
(d->d_ino_hardlimit &&
 (be64_to_cpu(d->d_icount) >
  be64_to_cpu(d->d_ino_hardlimit {
-   d->d_itimer = cpu_to_be32(get_seconds() +
+   d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_itimelimit);
} else {
d->d_iwarns = 0;
@@ -183,7 +183,7 @@ xfs_qm_adjust_dqtimers(
(d->d_rtb_hardlimit &&
 (be64_to_cpu(d->d_rtbcount) >
  be64_to_cpu(d->d_rtb_hardlimit {
-   d->d_rtbtimer = cpu_to_be32(get_seconds() +
+   d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
mp->m_quotainfo->qi_rtbtimelimit);
} else {
d->d_rtbwarns = 0;
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 7823af39008b..4e57edca8bce 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -64,9 +64,9 @@ struct xfs_quotainfo {
struct xfs_inode*qi_pquotaip;   /* project quota inode */
struct list_lru  qi_lru;
int  qi_dquots;
-   time_t   qi_btimelimit;  /* limit for blks timer */
-   time_t   qi_itimelimit;  /* limit for inodes timer */
-   time_t   qi_rtbtimelimit;/* limit for rt blks timer */
+   time64_t qi_btimelimit;  /* limit for blks timer */
+   time64_t qi_itimelimit;  /* limit for inodes timer */
+   time64_t qi_rtbtimelimit;/* limit for rt blks timer */
xfs_qwarncnt_t   qi_bwarnlimit;  /* limit for blks warnings */
xfs_qwarncnt_t   qi_iwarnlimit;  /* limit for inodes warnings */
xfs_qwarncnt_t   qi_rtbwarnlimit;/* limit for rt blks warnings */
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index c7de17deeae6..38669e827206 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -37,9 +37,9 @@ xfs_qm_fill_state(
tstate->flags |= QCI_SYSFILE;
tstate->blocks = ip->i_d.di_nblocks;
tstate->nextents = ip->i_d.di_nextents;
-   tstate->spc_timelimit = q->qi_btimelimit;
-   tstate->ino_timelimit = q->qi_itimelimit;
-   tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
+   tstate->spc_timelimit = (u32)q->qi_btimelimit;
+   tstate->ino_timelimit = (u32)q->qi_itimelimit;
+   tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit;
tstate->spc_warnlimit = q->qi_bwarnlimit;
tstate->ino_warnlimit = q->qi_iwarnlimit;
tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index a6fe2d8dc40f..d1b9869bc5fa 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -580,7 +580,7 @@ xfs_trans_dqresv(
 {
xfs_qcnt_t  hardlimit;
xfs_qcnt_t  softlimit;
-   time_t  timer;
+   time64_ttimer;
xfs_qwarncnt_t  warns;
xfs_qwarncnt_t  warnlimit;
xfs_qcnt_t  total_count;
@@ -635,7 +635,8 @@ xfs_trans_dqresv(
goto error_return;
}
if (softlimit && total_count > softlimit) {
- 

[Y2038] [PATCH 1/3] xfs: rename compat_time_t to old_time32_t

2019-12-18 Thread Arnd Bergmann
The compat_time_t type has been removed everywhere else,
as most users rely on old_time32_t for both native and
compat mode handling of 32-bit time_t.

Remove the last one in xfs.

Reviewed-by: Darrick J. Wong 
Signed-off-by: Arnd Bergmann 
---
 fs/xfs/xfs_ioctl32.c | 2 +-
 fs/xfs/xfs_ioctl32.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index c4c4f09113d3..a49bd80b2c3b 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -107,7 +107,7 @@ xfs_ioctl32_bstime_copyin(
xfs_bstime_t*bstime,
compat_xfs_bstime_t __user *bstime32)
 {
-   compat_time_t   sec32;  /* tv_sec differs on 64 vs. 32 */
+   old_time32_tsec32;  /* tv_sec differs on 64 vs. 32 */
 
if (get_user(sec32, >tv_sec)  ||
get_user(bstime->tv_nsec,   >tv_nsec))
diff --git a/fs/xfs/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h
index 8c7743cd490e..053de7d894cd 100644
--- a/fs/xfs/xfs_ioctl32.h
+++ b/fs/xfs/xfs_ioctl32.h
@@ -32,7 +32,7 @@
 #endif
 
 typedef struct compat_xfs_bstime {
-   compat_time_t   tv_sec; /* seconds  */
+   old_time32_ttv_sec; /* seconds  */
__s32   tv_nsec;/* and nanoseconds  */
 } compat_xfs_bstime_t;
 
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH 2/3] xfs: disallow broken ioctls without compat-32-bit-time

2019-12-18 Thread Arnd Bergmann
When building a kernel that disables support for 32-bit time_t
system calls, it also makes sense to disable the old xfs_bstat
ioctls completely, as they truncate the timestamps to 32-bit
values once the extended times are supported.

Any application using these needs to be updated to use the v5
interfaces.

Signed-off-by: Arnd Bergmann 
---
 fs/xfs/xfs_ioctl.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 7b35d62ede9f..d43582e933a0 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -36,6 +36,7 @@
 #include "xfs_reflink.h"
 #include "xfs_ioctl.h"
 
+#include 
 #include 
 #include 
 
@@ -617,6 +618,23 @@ xfs_fsinumbers_fmt(
return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
 }
 
+/* disallow y2038-unsafe ioctls with CONFIG_COMPAT_32BIT_TIME=n */
+static bool xfs_have_compat_bstat_time32(unsigned int cmd)
+{
+   if (IS_ENABLED(CONFIG_COMPAT_32BIT_TIME))
+   return true;
+
+   if (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall())
+   return true;
+
+   if (cmd == XFS_IOC_FSBULKSTAT_SINGLE ||
+   cmd == XFS_IOC_FSBULKSTAT ||
+   cmd == XFS_IOC_SWAPEXT)
+   return false;
+
+   return true;
+}
+
 STATIC int
 xfs_ioc_fsbulkstat(
xfs_mount_t *mp,
@@ -637,6 +655,9 @@ xfs_ioc_fsbulkstat(
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
 
+   if (!xfs_have_compat_bstat_time32(cmd))
+   return -EINVAL;
+
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
 
@@ -1815,6 +1836,11 @@ xfs_ioc_swapext(
struct fd   f, tmp;
int error = 0;
 
+   if (!xfs_have_compat_bstat_time32(XFS_IOC_SWAPEXT)) {
+   error = -EINVAL;
+   goto out;
+   }
+
/* Pull information for the target fd */
f = fdget((int)sxp->sx_fdtarget);
if (!f.file) {
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 11/27] compat_ioctl: move CDROM_SEND_PACKET handling into scsi

2019-12-17 Thread Arnd Bergmann
There is only one implementation of this ioctl, so move the handling out
of the common block layer code into the place where it's actually needed.

It also gets called indirectly through pktcdvd, which needs to be aware
of this change.

As I noticed, the old implementation of the compat handler failed to
convert the structure on the way out, so the updated fields never got
written back to user space. This is either not important, or it has
never worked and should be fixed now.

Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c|  47 +-
 block/scsi_ioctl.c  | 185 
 drivers/block/pktcdvd.c |   6 +-
 3 files changed, 135 insertions(+), 103 deletions(-)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f16ae92065d7..578e04f94619 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -102,18 +102,6 @@ struct compat_cdrom_read_audio {
compat_caddr_t  buf;
 };
 
-struct compat_cdrom_generic_command {
-   unsigned char   cmd[CDROM_PACKET_SIZE];
-   compat_caddr_t  buffer;
-   compat_uint_t   buflen;
-   compat_int_tstat;
-   compat_caddr_t  sense;
-   unsigned char   data_direction;
-   compat_int_tquiet;
-   compat_int_ttimeout;
-   compat_caddr_t  reserved[1];
-};
-
 static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
 {
@@ -141,38 +129,6 @@ static int compat_cdrom_read_audio(struct block_device 
*bdev, fmode_t mode,
(unsigned long)cdread_audio);
 }
 
-static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t 
mode,
-   unsigned int cmd, unsigned long arg)
-{
-   struct cdrom_generic_command __user *cgc;
-   struct compat_cdrom_generic_command __user *cgc32;
-   u32 data;
-   unsigned char dir;
-   int itmp;
-
-   cgc = compat_alloc_user_space(sizeof(*cgc));
-   cgc32 = compat_ptr(arg);
-
-   if (copy_in_user(>cmd, >cmd, sizeof(cgc->cmd)) ||
-   get_user(data, >buffer) ||
-   put_user(compat_ptr(data), >buffer) ||
-   copy_in_user(>buflen, >buflen,
-(sizeof(unsigned int) + sizeof(int))) ||
-   get_user(data, >sense) ||
-   put_user(compat_ptr(data), >sense) ||
-   get_user(dir, >data_direction) ||
-   put_user(dir, >data_direction) ||
-   get_user(itmp, >quiet) ||
-   put_user(itmp, >quiet) ||
-   get_user(itmp, >timeout) ||
-   put_user(itmp, >timeout) ||
-   get_user(data, >reserved[0]) ||
-   put_user(compat_ptr(data), >reserved[0]))
-   return -EFAULT;
-
-   return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
-}
-
 struct compat_blkpg_ioctl_arg {
compat_int_t op;
compat_int_t flags;
@@ -224,8 +180,6 @@ static int compat_blkdev_driver_ioctl(struct block_device 
*bdev, fmode_t mode,
return compat_hdio_ioctl(bdev, mode, cmd, arg);
case CDROMREADAUDIO:
return compat_cdrom_read_audio(bdev, mode, cmd, arg);
-   case CDROM_SEND_PACKET:
-   return compat_cdrom_generic_command(bdev, mode, cmd, arg);
 
/*
 * No handler required for the ones below, we just need to
@@ -263,6 +217,7 @@ static int compat_blkdev_driver_ioctl(struct block_device 
*bdev, fmode_t mode,
case CDROM_DISC_STATUS:
case CDROM_CHANGER_NSLOTS:
case CDROM_GET_CAPABILITY:
+   case CDROM_SEND_PACKET:
/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
 * not take a struct cdrom_read, instead they take a struct cdrom_msf
 * which is compatible.
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index b61dbf4d8443..b4e73d5dd5c2 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -639,6 +639,136 @@ int get_sg_io_hdr(struct sg_io_hdr *hdr, const void 
__user *argp)
 }
 EXPORT_SYMBOL(get_sg_io_hdr);
 
+#ifdef CONFIG_COMPAT
+struct compat_cdrom_generic_command {
+   unsigned char   cmd[CDROM_PACKET_SIZE];
+   compat_caddr_t  buffer;
+   compat_uint_t   buflen;
+   compat_int_tstat;
+   compat_caddr_t  sense;
+   unsigned char   data_direction;
+   compat_int_tquiet;
+   compat_int_ttimeout;
+   compat_caddr_t  reserved[1];
+};
+#endif
+
+static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc,
+ const void __user *arg)
+{
+#ifdef CONFIG_COMPAT
+   if (in_compat_syscall()) {
+   struct compat_cdrom_generic_command cgc32;
+
+   if (copy_from_user(, arg, sizeof(cgc32)))
+   return -EFAULT;
+
+   *cgc = (struct cdrom_generic_command) {
+   .buffer = compat_ptr(cgc32.buffer),
+   .buflen   

[Y2038] [PATCH v2 04/27] compat_ioctl: block: handle add zone open, close and finish ioctl

2019-12-17 Thread Arnd Bergmann
These were added to blkdev_ioctl() in linux-5.5 but not
blkdev_compat_ioctl, so add them now.

Fixes: e876df1fe0ad ("block: add zone open, close and finish ioctl support")
Reviewed-by: Damien Le Moal 
Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f5c1140b8624..5b13e344229c 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -356,6 +356,9 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
case BLKRRPART:
case BLKREPORTZONE:
case BLKRESETZONE:
+   case BLKOPENZONE:
+   case BLKCLOSEZONE:
+   case BLKFINISHZONE:
case BLKGETZONESZ:
case BLKGETNRZONES:
return blkdev_ioctl(bdev, mode, cmd,
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 24/27] compat_ioctl: block: move blkdev_compat_ioctl() into ioctl.c

2019-12-17 Thread Arnd Bergmann
Having both in the same file allows a number of simplifications
to the compat path, and makes it more likely that changes to
the native path get applied to the compat version as well.

Signed-off-by: Arnd Bergmann 
---
 block/Makefile   |   1 -
 block/compat_ioctl.c | 225 ---
 block/ioctl.c| 219 +
 3 files changed, 219 insertions(+), 226 deletions(-)
 delete mode 100644 block/compat_ioctl.c

diff --git a/block/Makefile b/block/Makefile
index 205a5f2fef17..1f70c73ea83d 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_MQ_IOSCHED_KYBER)+= kyber-iosched.o
 bfq-y  := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o
 obj-$(CONFIG_IOSCHED_BFQ)  += bfq.o
 
-obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
 obj-$(CONFIG_BLK_CMDLINE_PARSER)   += cmdline-parser.o
 obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
 obj-$(CONFIG_BLK_MQ_PCI)   += blk-mq-pci.o
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
deleted file mode 100644
index 765aa5357655..
--- a/block/compat_ioctl.c
+++ /dev/null
@@ -1,225 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-static int compat_put_ushort(unsigned long arg, unsigned short val)
-{
-   return put_user(val, (unsigned short __user *)compat_ptr(arg));
-}
-
-static int compat_put_int(unsigned long arg, int val)
-{
-   return put_user(val, (compat_int_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_uint(unsigned long arg, unsigned int val)
-{
-   return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_long(unsigned long arg, long val)
-{
-   return put_user(val, (compat_long_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_ulong(unsigned long arg, compat_ulong_t val)
-{
-   return put_user(val, (compat_ulong_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_u64(unsigned long arg, u64 val)
-{
-   return put_user(val, (compat_u64 __user *)compat_ptr(arg));
-}
-
-struct compat_hd_geometry {
-   unsigned char heads;
-   unsigned char sectors;
-   unsigned short cylinders;
-   u32 start;
-};
-
-static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
-   struct compat_hd_geometry __user *ugeo)
-{
-   struct hd_geometry geo;
-   int ret;
-
-   if (!ugeo)
-   return -EINVAL;
-   if (!disk->fops->getgeo)
-   return -ENOTTY;
-
-   memset(, 0, sizeof(geo));
-   /*
-* We need to set the startsect first, the driver may
-* want to override it.
-*/
-   geo.start = get_start_sect(bdev);
-   ret = disk->fops->getgeo(bdev, );
-   if (ret)
-   return ret;
-
-   ret = copy_to_user(ugeo, , 4);
-   ret |= put_user(geo.start, >start);
-   if (ret)
-   ret = -EFAULT;
-
-   return ret;
-}
-
-struct compat_blkpg_ioctl_arg {
-   compat_int_t op;
-   compat_int_t flags;
-   compat_int_t datalen;
-   compat_caddr_t data;
-};
-
-static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
-   unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
-{
-   struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
-   compat_caddr_t udata;
-   compat_int_t n;
-   int err;
-
-   err = get_user(n, >op);
-   err |= put_user(n, >op);
-   err |= get_user(n, >flags);
-   err |= put_user(n, >flags);
-   err |= get_user(n, >datalen);
-   err |= put_user(n, >datalen);
-   err |= get_user(udata, >data);
-   err |= put_user(compat_ptr(udata), >data);
-   if (err)
-   return err;
-
-   return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
-}
-
-#define BLKBSZGET_32   _IOR(0x12, 112, int)
-#define BLKBSZSET_32   _IOW(0x12, 113, int)
-#define BLKGETSIZE64_32_IOR(0x12, 114, int)
-
-/* Most of the generic ioctls are handled in the normal fallback path.
-   This assumes the blkdev's low level compat_ioctl always returns
-   ENOIOCTLCMD for unknown ioctls. */
-long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
-{
-   int ret = -ENOIOCTLCMD;
-   struct inode *inode = file->f_mapping->host;
-   struct block_device *bdev = inode->i_bdev;
-   struct gendisk *disk = bdev->bd_disk;
-   fmode_t mode = file->f_mode;
-   loff_t size;
-   unsigned int max_sectors;
-
-   /*
-* O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
-* to updated it before every ioctl.
-*/
-   if (file->f_flags & O_NDELAY)
-   mode |= FMODE_NDELAY;
-   else

[Y2038] [PATCH v2 18/27] compat_ioctl: scsi: move ioctl handling into drivers

2019-12-17 Thread Arnd Bergmann
Each driver calling scsi_ioctl() gets an equivalent compat_ioctl()
handler that implements the same commands by calling scsi_compat_ioctl().

The scsi_cmd_ioctl() and scsi_cmd_blk_ioctl() functions are compatible
at this point, so any driver that calls those can do so for both native
and compat mode, with the argument passed through compat_ptr().

With this, we can remove the entries from fs/compat_ioctl.c.  The new
code is larger, but should be easier to maintain and keep updated with
newly added commands.

Signed-off-by: Arnd Bergmann 
---
 drivers/block/virtio_blk.c |   3 +
 drivers/scsi/ch.c  |   9 ++-
 drivers/scsi/sd.c  |  50 ++
 drivers/scsi/sg.c  |  44 -
 drivers/scsi/sr.c  |  57 ++--
 drivers/scsi/st.c  |  51 --
 fs/compat_ioctl.c  | 132 +
 7 files changed, 142 insertions(+), 204 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 7ffd719d89de..fbbf18ac1d5d 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -405,6 +405,9 @@ static int virtblk_getgeo(struct block_device *bd, struct 
hd_geometry *geo)
 
 static const struct block_device_operations virtblk_fops = {
.ioctl  = virtblk_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl = blkdev_compat_ptr_ioctl,
+#endif
.owner  = THIS_MODULE,
.getgeo = virtblk_getgeo,
 };
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 76751d6c7f0d..ed5f4a6ae270 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -872,6 +872,10 @@ static long ch_ioctl_compat(struct file * file,
unsigned int cmd, unsigned long arg)
 {
scsi_changer *ch = file->private_data;
+   int retval = scsi_ioctl_block_when_processing_errors(ch->device, cmd,
+   file->f_flags & 
O_NDELAY);
+   if (retval)
+   return retval;
 
switch (cmd) {
case CHIOGPARAMS:
@@ -883,7 +887,7 @@ static long ch_ioctl_compat(struct file * file,
case CHIOINITELEM:
case CHIOSVOLTAG:
/* compatible */
-   return ch_ioctl(file, cmd, arg);
+   return ch_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
case CHIOGSTATUS32:
{
struct changer_element_status32 ces32;
@@ -898,8 +902,7 @@ static long ch_ioctl_compat(struct file * file,
return ch_gstatus(ch, ces32.ces_type, data);
}
default:
-   // return scsi_ioctl_compat(ch->device, cmd, (void*)arg);
-   return -ENOIOCTLCMD;
+   return scsi_compat_ioctl(ch->device, cmd, compat_ptr(arg));
 
}
 }
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index cea625906440..5afb0046b12a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1465,13 +1465,12 @@ static int sd_getgeo(struct block_device *bdev, struct 
hd_geometry *geo)
  * Note: most ioctls are forward onto the block subsystem or further
  * down in the scsi subsystem.
  **/
-static int sd_ioctl(struct block_device *bdev, fmode_t mode,
-   unsigned int cmd, unsigned long arg)
+static int sd_ioctl_common(struct block_device *bdev, fmode_t mode,
+  unsigned int cmd, void __user *p)
 {
struct gendisk *disk = bdev->bd_disk;
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
-   void __user *p = (void __user *)arg;
int error;
 
SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, "
@@ -1507,9 +1506,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t 
mode,
break;
default:
error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p);
-   if (error != -ENOTTY)
-   break;
-   error = scsi_ioctl(sdp, cmd, p);
break;
}
 out:
@@ -1691,39 +1687,31 @@ static void sd_rescan(struct device *dev)
revalidate_disk(sdkp->disk);
 }
 
+static int sd_ioctl(struct block_device *bdev, fmode_t mode,
+   unsigned int cmd, unsigned long arg)
+{
+   void __user *p = (void __user *)arg;
+   int ret;
+
+   ret = sd_ioctl_common(bdev, mode, cmd, p);
+   if (ret != -ENOTTY)
+   return ret;
+
+   return scsi_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p);
+}
 
 #ifdef CONFIG_COMPAT
-/* 
- * This gets directly called from VFS. When the ioctl 
- * is not recognized we go back to the other translation paths. 
- */
 static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
   unsigned int cmd, unsigned long arg)
 {
-   struct gendisk *disk = bdev->bd_disk;
-   struct scsi_disk *sdkp = scsi_disk(disk);

[Y2038] [PATCH v2 16/27] compat_ioctl: bsg: add handler

2019-12-17 Thread Arnd Bergmann
bsg_ioctl() calls into scsi_cmd_ioctl() for a couple of generic commands
and relies on fs/compat_ioctl.c to handle it correctly in compat mode.

Adding a private compat_ioctl() handler avoids that round-trip and lets
us get rid of the generic emulation once this is done.

Note that bsg implements an SG_IO command that is different from the
other drivers and does not need emulation.

Signed-off-by: Arnd Bergmann 
---
 block/bsg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/bsg.c b/block/bsg.c
index 833c44b3d458..d7bae94b64d9 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -382,6 +382,7 @@ static const struct file_operations bsg_fops = {
.open   =   bsg_open,
.release=   bsg_release,
.unlocked_ioctl =   bsg_ioctl,
+   .compat_ioctl   =   compat_ptr_ioctl,
.owner  =   THIS_MODULE,
.llseek =   default_llseek,
 };
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 21/27] compat_ioctl: move cdrom commands into cdrom.c

2019-12-17 Thread Arnd Bergmann
There is no need for the special cases for the cdrom ioctls any more now,
so make sure that each cdrom driver has a .compat_ioctl() callback and
calls cdrom_compat_ioctl() directly there.

Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c   | 45 --
 drivers/block/paride/pcd.c |  3 +++
 drivers/cdrom/gdrom.c  |  3 +++
 drivers/ide/ide-cd.c   | 36 ++
 drivers/scsi/sr.c  | 10 +++--
 5 files changed, 45 insertions(+), 52 deletions(-)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index cf136bc2c9fc..7cb534d6e767 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -159,42 +159,6 @@ static int compat_blkdev_driver_ioctl(struct block_device 
*bdev, fmode_t mode,
case HDIO_DRIVE_CMD:
/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
case 0x330:
-   /* CDROM stuff */
-   case CDROMPAUSE:
-   case CDROMRESUME:
-   case CDROMPLAYMSF:
-   case CDROMPLAYTRKIND:
-   case CDROMREADTOCHDR:
-   case CDROMREADTOCENTRY:
-   case CDROMSTOP:
-   case CDROMSTART:
-   case CDROMEJECT:
-   case CDROMVOLCTRL:
-   case CDROMSUBCHNL:
-   case CDROMMULTISESSION:
-   case CDROM_GET_MCN:
-   case CDROMRESET:
-   case CDROMVOLREAD:
-   case CDROMSEEK:
-   case CDROMPLAYBLK:
-   case CDROMCLOSETRAY:
-   case CDROM_DISC_STATUS:
-   case CDROM_CHANGER_NSLOTS:
-   case CDROM_GET_CAPABILITY:
-   case CDROM_SEND_PACKET:
-   /* Ignore cdrom.h about these next 5 ioctls, they absolutely do
-* not take a struct cdrom_read, instead they take a struct cdrom_msf
-* which is compatible.
-*/
-   case CDROMREADMODE2:
-   case CDROMREADMODE1:
-   case CDROMREADRAW:
-   case CDROMREADCOOKED:
-   case CDROMREADALL:
-   /* DVD ioctls */
-   case DVD_READ_STRUCT:
-   case DVD_WRITE_STRUCT:
-   case DVD_AUTH:
arg = (unsigned long)compat_ptr(arg);
/* These intepret arg as an unsigned long, not as a pointer,
 * so we must not do compat_ptr() conversion. */
@@ -210,15 +174,6 @@ static int compat_blkdev_driver_ioctl(struct block_device 
*bdev, fmode_t mode,
case HDIO_SET_ACOUSTIC:
case HDIO_SET_BUSSTATE:
case HDIO_SET_ADDRESS:
-   case CDROMEJECT_SW:
-   case CDROM_SET_OPTIONS:
-   case CDROM_CLEAR_OPTIONS:
-   case CDROM_SELECT_SPEED:
-   case CDROM_SELECT_DISC:
-   case CDROM_MEDIA_CHANGED:
-   case CDROM_DRIVE_STATUS:
-   case CDROM_LOCKDOOR:
-   case CDROM_DEBUG:
break;
default:
/* unknown ioctl number */
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 636bfea2de6f..117cfc8cd05a 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -275,6 +275,9 @@ static const struct block_device_operations pcd_bdops = {
.open   = pcd_block_open,
.release= pcd_block_release,
.ioctl  = pcd_block_ioctl,
+#ifdef CONFIG_COMPAT
+   .ioctl  = blkdev_compat_ptr_ioctl,
+#endif
.check_events   = pcd_block_check_events,
 };
 
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 5b21dc421c94..886b2638c730 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -518,6 +518,9 @@ static const struct block_device_operations gdrom_bdops = {
.release= gdrom_bdops_release,
.check_events   = gdrom_bdops_check_events,
.ioctl  = gdrom_bdops_ioctl,
+#ifdef CONFIG_COMPAT
+   .ioctl  = blkdev_compat_ptr_ioctl,
+#endif
 };
 
 static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id)
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 9d117936bee1..2de6e8ace957 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -25,6 +25,7 @@
 
 #define IDECD_VERSION "5.00"
 
+#include 
 #include 
 #include 
 #include 
@@ -1710,6 +1711,38 @@ static int idecd_ioctl(struct block_device *bdev, 
fmode_t mode,
return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static int idecd_locked_compat_ioctl(struct block_device *bdev, fmode_t mode,
+   unsigned int cmd, unsigned long arg)
+{
+   struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
+   int err;
+
+   switch (cmd) {
+   case CDROMSETSPINDOWN:
+   return idecd_set_spindown(>devinfo, arg);
+   case CDROMGETSPINDOWN:
+   return idecd_get_spindown(>devinfo, arg);
+   default:
+   break;
+   }
+
+   return cdrom_ioctl(>devinfo, bdev, mode, cmd,
+  (unsigned long)compat_ptr(arg));
+}
+
+static int idecd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+unsigned int cmd, unsigned long arg)
+{
+   int ret;
+
+ 

[Y2038] [PATCH v2 27/27] Documentation: document ioctl interfaces better

2019-12-17 Thread Arnd Bergmann
Documentation/process/botching-up-ioctls.rst was orignally
written as a blog post for DRM driver writers, so it it misses
some points while going into a lot of detail on others.

Try to provide a replacement that addresses typical issues
across a wider range of subsystems, and follows the style of
the core-api documentation better.

Signed-off-by: Arnd Bergmann 
---
 Documentation/core-api/index.rst |   1 +
 Documentation/core-api/ioctl.rst | 248 +++
 2 files changed, 249 insertions(+)
 create mode 100644 Documentation/core-api/ioctl.rst

diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index ab0eae1c153a..3f28b2f668be 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -39,6 +39,7 @@ Core utilities
../RCU/index
gcc-plugins
symbol-namespaces
+   ioctl
 
 
 Interfaces for kernel debugging
diff --git a/Documentation/core-api/ioctl.rst b/Documentation/core-api/ioctl.rst
new file mode 100644
index ..99892f96c5cb
--- /dev/null
+++ b/Documentation/core-api/ioctl.rst
@@ -0,0 +1,248 @@
+==
+ioctl based interfaces
+==
+
+ioctl() is the most common way for applications to interface
+with device drivers. It is flexible and easily extended by adding new
+commands and can be passed through character devices, block devices as
+well as sockets and other special file descriptors.
+
+However, it is also very easy to get ioctl command definitions wrong,
+and hard to fix them later without breaking existing applications,
+so this documentation tries to help developers get it right.
+
+Command number definitions
+==
+
+The command number, or request number, is the second argument passed to
+the ioctl system call. While this can be any 32-bit number that uniquely
+identifies an action for a particular driver, there are a number of
+conventions around defining them.
+
+``include/uapi/asm-generic/ioctl.h`` provides four macros for defining
+ioctl commands that follow modern conventions: ``_IO``, ``_IOR``,
+``_IOW``, and ``_IORW``. These should be used for all new commands,
+with the correct parameters:
+
+_IO/_IOR/_IOW/_IOWR
+   The macro name determines whether the argument is used for passing
+   data into kernel (_IOW), from the kernel (_IOR), both (_IOWR) or is
+   not a pointer (_IO). It is possible but not recommended to pass an
+   integer value instead of a pointer with _IO.
+
+type
+   An 8-bit number, often a character literal, specific to a subsystem
+   or driver, and listed in :doc:`../userspace-api/ioctl/ioctl-number`
+
+nr
+  An 8-bit number identifying the specific command, unique for a give
+  value of 'type'
+
+data_type
+  The name of the data type pointed to by the argument, the command number
+  encodes the ``sizeof(data_type)`` value in a 13-bit or 14-bit integer,
+  leading to a limit of 8191 bytes for the maximum size of the argument.
+  Note: do not pass sizeof(data_type) type into _IOR/IOW, as that will
+  lead to encoding sizeof(sizeof(data_type)), i.e. sizeof(size_t).
+
+
+Interface versions
+==
+
+Some subsystems use version numbers in data structures to overload
+commands with different interpretations of the argument.
+
+This is generally a bad idea, since changes to existing commands tend
+to break existing applications.
+
+A better approach is to add a new ioctl command with a new number. The
+old command still needs to be implemented in the kernel for compatibility,
+but this can be a wrapper around the new implementation.
+
+Return code
+===
+
+ioctl commands can return negative error codes as documented in errno(3),
+these get turned into errno values in user space. On success, the return
+code should be zero. It is also possible but not recommended to return
+a positive 'long' value.
+
+When the ioctl callback is called with an unknown command number, the
+handler returns either -ENOTTY or -ENOIOCTLCMD, which also results in
+-ENOTTY being returned from the system call. Some subsystems return
+-ENOSYS or -EINVAL here for historic reasons, but this is wrong.
+
+Prior to Linux-5.5, compat_ioctl handlers were required to return
+-ENOIOCTLCMD in order to use the fallback conversion into native
+commands. As all subsystems are now responsible for handling compat
+mode themselves, this is no longer needed, but it may be important to
+consider when backporting bug fixes to older kernels.
+
+Timestamps
+==
+
+Traditionally, timestamps and timeout values are passed as ``struct
+timespec`` or ``struct timeval``, but these are problematic because of
+incompatible definitions of these structures in user space after the
+move to 64-bit time_t.
+
+The __kernel_timespec type can be used instead to be embedded in other
+data structures when separate second/nanosecond values are desired,
+or passed to user space directly. This is still not ideal though,
+as the structure matches neither

[Y2038] [PATCH v2 23/27] compat_ioctl: move HDIO ioctl handling into drivers/ide

2019-12-17 Thread Arnd Bergmann
Most of the HDIO ioctls are only used by the obsolete drivers/ide
subsystem, these can be handled by changing ide_cmd_ioctl() to be aware
of compat mode and doing the correct transformations in place and using
it as both native and compat handlers for all drivers.

The SCSI drivers implementing the same commands are already doing
this in the drivers, so the compat_blkdev_driver_ioctl() function
is no longer needed now.

The BLKSECTSET and HDIO_GETGEO_BIG ioctls are not implemented
in any driver any more and no longer need any conversion.

Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c   | 75 --
 drivers/ide/ide-cd.c   | 15 +++
 drivers/ide/ide-disk.c |  1 +
 drivers/ide/ide-floppy_ioctl.c |  7 ++--
 drivers/ide/ide-ioctls.c   | 44 
 drivers/ide/ide-tape.c | 11 +
 6 files changed, 51 insertions(+), 102 deletions(-)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 7cb534d6e767..765aa5357655 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -77,24 +77,6 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct 
block_device *bdev,
return ret;
 }
 
-static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
-   unsigned int cmd, unsigned long arg)
-{
-   unsigned long __user *p;
-   int error;
-
-   p = compat_alloc_user_space(sizeof(unsigned long));
-   error = __blkdev_driver_ioctl(bdev, mode,
-   cmd, (unsigned long)p);
-   if (error == 0) {
-   unsigned int __user *uvp = compat_ptr(arg);
-   unsigned long v;
-   if (get_user(v, p) || put_user(v, uvp))
-   error = -EFAULT;
-   }
-   return error;
-}
-
 struct compat_blkpg_ioctl_arg {
compat_int_t op;
compat_int_t flags;
@@ -128,61 +110,6 @@ static int compat_blkpg_ioctl(struct block_device *bdev, 
fmode_t mode,
 #define BLKBSZSET_32   _IOW(0x12, 113, int)
 #define BLKGETSIZE64_32_IOR(0x12, 114, int)
 
-static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
-   unsigned cmd, unsigned long arg)
-{
-   switch (cmd) {
-   case HDIO_GET_UNMASKINTR:
-   case HDIO_GET_MULTCOUNT:
-   case HDIO_GET_KEEPSETTINGS:
-   case HDIO_GET_32BIT:
-   case HDIO_GET_NOWERR:
-   case HDIO_GET_DMA:
-   case HDIO_GET_NICE:
-   case HDIO_GET_WCACHE:
-   case HDIO_GET_ACOUSTIC:
-   case HDIO_GET_ADDRESS:
-   case HDIO_GET_BUSSTATE:
-   return compat_hdio_ioctl(bdev, mode, cmd, arg);
-
-   /*
-* No handler required for the ones below, we just need to
-* convert arg to a 64 bit pointer.
-*/
-   case BLKSECTSET:
-   /*
-* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
-* Some need translations, these do not.
-*/
-   case HDIO_GET_IDENTITY:
-   case HDIO_DRIVE_TASK:
-   case HDIO_DRIVE_CMD:
-   /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
-   case 0x330:
-   arg = (unsigned long)compat_ptr(arg);
-   /* These intepret arg as an unsigned long, not as a pointer,
-* so we must not do compat_ptr() conversion. */
-   case HDIO_SET_MULTCOUNT:
-   case HDIO_SET_UNMASKINTR:
-   case HDIO_SET_KEEPSETTINGS:
-   case HDIO_SET_32BIT:
-   case HDIO_SET_NOWERR:
-   case HDIO_SET_DMA:
-   case HDIO_SET_PIO_MODE:
-   case HDIO_SET_NICE:
-   case HDIO_SET_WCACHE:
-   case HDIO_SET_ACOUSTIC:
-   case HDIO_SET_BUSSTATE:
-   case HDIO_SET_ADDRESS:
-   break;
-   default:
-   /* unknown ioctl number */
-   return -ENOIOCTLCMD;
-   }
-
-   return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-}
-
 /* Most of the generic ioctls are handled in the normal fallback path.
This assumes the blkdev's low level compat_ioctl always returns
ENOIOCTLCMD for unknown ioctls. */
@@ -293,8 +220,6 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
default:
if (disk->fops->compat_ioctl)
ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
-   if (ret == -ENOIOCTLCMD)
-   ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
return ret;
}
 }
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2de6e8ace957..284a7a5bad54 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1711,7 +1711,6 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t 
mode,
return ret;
 }
 
-#ifdef CONFIG_COMPAT
 static int idecd_locked_compat_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
 {
@@ -1727,8 +1726,12 @@ static int idecd_locked_compat_ioctl(struct block_d

[Y2038] [PATCH v2 22/27] compat_ioctl: scsi: handle HDIO commands from drivers

2019-12-17 Thread Arnd Bergmann
The ata_sas_scsi_ioctl() function implements a number of HDIO_* commands
for SCSI devices, it is used by all libata drivers as well as a few
drivers that support SAS attached SATA drives.

The only command that is not safe for compat ioctls here is
HDIO_GET_32BIT. Change the implementation to check for in_compat_syscall()
in order to do both cases correctly, and change all callers to use it
as both native and compat callback pointers, including the indirect
callers through sas_ioctl and ata_scsi_ioctl.

Signed-off-by: Arnd Bergmann 
---
 drivers/ata/libata-scsi.c  | 9 +
 drivers/scsi/aic94xx/aic94xx_init.c| 3 +++
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 +++
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 +++
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++
 drivers/scsi/ipr.c | 3 +++
 drivers/scsi/isci/init.c   | 3 +++
 drivers/scsi/mvsas/mv_init.c   | 3 +++
 drivers/scsi/pm8001/pm8001_init.c  | 3 +++
 include/linux/libata.h | 6 ++
 10 files changed, 39 insertions(+)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 58e09ffe8b9c..eb2eb599e602 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -17,6 +17,7 @@
  *  - http://www.t13.org/
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -761,6 +762,10 @@ static int ata_ioc32(struct ata_port *ap)
return 0;
 }
 
+/*
+ * This handles both native and compat commands, so anything added
+ * here must have a compatible argument, or check in_compat_syscall()
+ */
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
 unsigned int cmd, void __user *arg)
 {
@@ -773,6 +778,10 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct 
scsi_device *scsidev,
spin_lock_irqsave(ap->lock, flags);
val = ata_ioc32(ap);
spin_unlock_irqrestore(ap->lock, flags);
+#ifdef CONFIG_COMPAT
+   if (in_compat_syscall())
+   return put_user(val, (compat_ulong_t __user *)arg);
+#endif
return put_user(val, (unsigned long __user *)arg);
 
case HDIO_SET_32BIT:
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c 
b/drivers/scsi/aic94xx/aic94xx_init.c
index f5781e31f57c..d022407e5645 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -54,6 +54,9 @@ static struct scsi_host_template aic94xx_sht = {
.eh_target_reset_handler= sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy,
.ioctl  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = sas_ioctl,
+#endif
.track_queue_depth  = 1,
 };
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 3af53cc42bd6..fa25766502a2 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -1772,6 +1772,9 @@ static struct scsi_host_template sht_v1_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy,
.ioctl  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = sas_ioctl,
+#endif
.shost_attrs= host_attrs_v1_hw,
.host_reset = hisi_sas_host_reset,
 };
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 61b1e2693b08..545eaff5f3ee 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -3551,6 +3551,9 @@ static struct scsi_host_template sht_v2_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy,
.ioctl  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = sas_ioctl,
+#endif
.shost_attrs= host_attrs_v2_hw,
.host_reset = hisi_sas_host_reset,
 };
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index bf5d5f138437..fa05e612d85a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -3075,6 +3075,9 @@ static struct scsi_host_template sht_v3_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy,
.ioctl  = sas_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = sas_ioctl,
+#endif
.shost_attrs= host_attrs_v3_hw,
.tag_alloc_policy   = BLK_TAG_ALLOC_RR,
.host_reset = hisi_sas_host_reset,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 079c04bc448a..ae45cbe98ae2 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6727,6 +6727,9 @@ static struct scsi_host_template driver_template = {
.name = "IPR"

[Y2038] [PATCH v2 20/27] compat_ioctl: simplify the implementation

2019-12-17 Thread Arnd Bergmann
Now that both native and compat ioctl syscalls are
in the same file, a couple of simplifications can
be made, bringing the implementation closer together:

- do_vfs_ioctl(), ioctl_preallocate(), and compat_ioctl_preallocate()
  can become static, allowing the compiler to optimize better

- slightly update the coding style for consistency between
  the functions.

- rather than listing each command in two switch statements
  for the compat case, just call a single function that has
  all the common commands.

As a side-effect, FS_IOC_RESVSP/FS_IOC_RESVSP64 are now available
to x86 compat tasks, along with FS_IOC_RESVSP_32/FS_IOC_RESVSP64_32.
This is harmless for i386 emulation, and can be considered a bugfix
for x32 emulation, which never supported these in the past.

Signed-off-by: Arnd Bergmann 
---
 fs/internal.h  |   6 --
 fs/ioctl.c | 157 +
 include/linux/falloc.h |   2 -
 include/linux/fs.h |   4 --
 4 files changed, 64 insertions(+), 105 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 4a7da1df573d..d46247850ad7 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -180,11 +180,5 @@ extern void mnt_pin_kill(struct mount *m);
  */
 extern const struct dentry_operations ns_dentry_operations;
 
-/*
- * fs/ioctl.c
- */
-extern int do_vfs_ioctl(struct file *file, unsigned int fd, unsigned int cmd,
-   unsigned long arg);
-
 /* direct-io.c: */
 int sb_init_dio_done_wq(struct super_block *sb);
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 8f22f7817edb..7c9a5df5a597 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -467,7 +467,7 @@ EXPORT_SYMBOL(generic_block_fiemap);
  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
  * are used here, rest are ignored.
  */
-int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
+static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
 {
struct inode *inode = file_inode(filp);
struct space_resv sr;
@@ -495,8 +495,8 @@ int ioctl_preallocate(struct file *filp, int mode, void 
__user *argp)
 /* on ia32 l_start is on a 32-bit boundary */
 #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
 /* just account for different alignment */
-int compat_ioctl_preallocate(struct file *file, int mode,
-   struct space_resv_32 __user *argp)
+static int compat_ioctl_preallocate(struct file *file, int mode,
+   struct space_resv_32 __user *argp)
 {
struct inode *inode = file_inode(file);
struct space_resv_32 sr;
@@ -521,11 +521,9 @@ int compat_ioctl_preallocate(struct file *file, int mode,
 }
 #endif
 
-static int file_ioctl(struct file *filp, unsigned int cmd,
-   unsigned long arg)
+static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
 {
struct inode *inode = file_inode(filp);
-   int __user *p = (int __user *)arg;
 
switch (cmd) {
case FIBMAP:
@@ -542,7 +540,7 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
}
 
-   return vfs_ioctl(filp, cmd, arg);
+   return -ENOIOCTLCMD;
 }
 
 static int ioctl_fionbio(struct file *filp, int __user *argp)
@@ -661,53 +659,48 @@ static int ioctl_file_dedupe_range(struct file *file,
 }
 
 /*
- * When you add any new common ioctls to the switches above and below
- * please update compat_sys_ioctl() too.
- *
  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
+ *
+ * When you add any new common ioctls to the switches above and below,
+ * please ensure they have compatible arguments in compat mode.
  */
-int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
-unsigned long arg)
+static int do_vfs_ioctl(struct file *filp, unsigned int fd,
+   unsigned int cmd, unsigned long arg)
 {
-   int error = 0;
void __user *argp = (void __user *)arg;
struct inode *inode = file_inode(filp);
 
switch (cmd) {
case FIOCLEX:
set_close_on_exec(fd, 1);
-   break;
+   return 0;
 
case FIONCLEX:
set_close_on_exec(fd, 0);
-   break;
+   return 0;
 
case FIONBIO:
-   error = ioctl_fionbio(filp, argp);
-   break;
+   return ioctl_fionbio(filp, argp);
 
case FIOASYNC:
-   error = ioctl_fioasync(fd, filp, argp);
-   break;
+   return ioctl_fioasync(fd, filp, argp);
 
case FIOQSIZE:
if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
S_ISLNK(inode->i_mode)) {
loff_t res = inode_get_bytes(inode);
-   error = copy_to_user(a

[Y2038] [PATCH v2 15/27] compat_ioctl: add scsi_compat_ioctl

2019-12-17 Thread Arnd Bergmann
In order to move the compat handling for SCSI ioctl commands out of
fs/compat_ioctl.c into the individual drivers, we need a helper function
first to match the native ioctl handler called by sd, sr, st, etc.

Signed-off-by: Arnd Bergmann 
---
 drivers/scsi/scsi_ioctl.c | 54 +--
 include/scsi/scsi_ioctl.h |  1 +
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 57bcd05605bf..8f3af87b6bb0 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -189,17 +189,7 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, 
void __user *arg)
 }
 
 
-/**
- * scsi_ioctl - Dispatch ioctl to scsi device
- * @sdev: scsi device receiving ioctl
- * @cmd: which ioctl is it
- * @arg: data associated with ioctl
- *
- * Description: The scsi_ioctl() function differs from most ioctls in that it
- * does not take a major/minor number as the dev field.  Rather, it takes
- * a pointer to a  scsi_device.
- */
-int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user 
*arg)
 {
char scsi_cmd[MAX_COMMAND_SIZE];
struct scsi_sense_hdr sense_hdr;
@@ -266,14 +256,50 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void 
__user *arg)
 return scsi_ioctl_get_pci(sdev, arg);
case SG_SCSI_RESET:
return scsi_ioctl_reset(sdev, arg);
-   default:
-   if (sdev->host->hostt->ioctl)
-   return sdev->host->hostt->ioctl(sdev, cmd, arg);
}
+   return -ENOIOCTLCMD;
+}
+
+/**
+ * scsi_ioctl - Dispatch ioctl to scsi device
+ * @sdev: scsi device receiving ioctl
+ * @cmd: which ioctl is it
+ * @arg: data associated with ioctl
+ *
+ * Description: The scsi_ioctl() function differs from most ioctls in that it
+ * does not take a major/minor number as the dev field.  Rather, it takes
+ * a pointer to a  scsi_device.
+ */
+int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+{
+   int ret = scsi_ioctl_common(sdev, cmd, arg);
+
+   if (ret != -ENOIOCTLCMD)
+   return ret;
+
+   if (sdev->host->hostt->ioctl)
+   return sdev->host->hostt->ioctl(sdev, cmd, arg);
+
return -EINVAL;
 }
 EXPORT_SYMBOL(scsi_ioctl);
 
+#ifdef CONFIG_COMPAT
+int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+{
+   int ret = scsi_ioctl_common(sdev, cmd, arg);
+
+   if (ret != -ENOIOCTLCMD)
+   return ret;
+
+   if (sdev->host->hostt->compat_ioctl)
+   return sdev->host->hostt->compat_ioctl(sdev, cmd, arg);
+
+   return ret;
+}
+EXPORT_SYMBOL(scsi_compat_ioctl);
+#endif
+
 /*
  * We can process a reset even when a device isn't fully operable.
  */
diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h
index 5101e987c0ef..4fe69d863b5d 100644
--- a/include/scsi/scsi_ioctl.h
+++ b/include/scsi/scsi_ioctl.h
@@ -44,6 +44,7 @@ typedef struct scsi_fctargaddress {
 int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
int cmd, bool ndelay);
 extern int scsi_ioctl(struct scsi_device *, int, void __user *);
+extern int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user 
*arg);
 
 #endif /* __KERNEL__ */
 #endif /* _SCSI_IOCTL_H */
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 17/27] compat_ioctl: ide: floppy: add handler

2019-12-17 Thread Arnd Bergmann
Rather than relying on fs/compat_ioctl.c, this adds support
for a compat_ioctl() callback in the ide-floppy driver directly,
which lets it translate the scsi commands.

Signed-off-by: Arnd Bergmann 
---
 drivers/ide/ide-floppy.c   |  4 
 drivers/ide/ide-floppy.h   |  2 ++
 drivers/ide/ide-floppy_ioctl.c | 36 ++
 drivers/ide/ide-gd.c   | 14 +
 include/linux/ide.h|  2 ++
 5 files changed, 58 insertions(+)

diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 1ea2f9e82bf8..1fe1f9d37a51 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -546,4 +547,7 @@ const struct ide_disk_ops ide_atapi_disk_ops = {
.set_doorlock   = ide_set_media_lock,
.do_request = ide_floppy_do_request,
.ioctl  = ide_floppy_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = ide_floppy_compat_ioctl,
+#endif
 };
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h
index 13c9b4b6d75e..8505a5f58f4e 100644
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -26,6 +26,8 @@ void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc 
*);
 /* ide-floppy_ioctl.c */
 int ide_floppy_ioctl(ide_drive_t *, struct block_device *, fmode_t,
 unsigned int, unsigned long);
+int ide_floppy_compat_ioctl(ide_drive_t *, struct block_device *, fmode_t,
+   unsigned int, unsigned long);
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-floppy_proc.c */
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 40a2ebe34e1d..4fd70f804d6f 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -302,3 +303,38 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct 
block_device *bdev,
mutex_unlock(_floppy_ioctl_mutex);
return err;
 }
+
+#ifdef CONFIG_COMPAT
+int ide_floppy_compat_ioctl(ide_drive_t *drive, struct block_device *bdev,
+   fmode_t mode, unsigned int cmd, unsigned long arg)
+{
+   struct ide_atapi_pc pc;
+   void __user *argp = compat_ptr(arg);
+   int err;
+
+   mutex_lock(_floppy_ioctl_mutex);
+   if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) {
+   err = ide_floppy_lockdoor(drive, , arg, cmd);
+   goto out;
+   }
+
+   err = ide_floppy_format_ioctl(drive, , mode, cmd, argp);
+   if (err != -ENOTTY)
+   goto out;
+
+   /*
+* skip SCSI_IOCTL_SEND_COMMAND (deprecated)
+* and CDROM_SEND_PACKET (legacy) ioctls
+*/
+   if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
+   err = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
+
+   /*
+* there is no generic_ide_compat_ioctl(), that is handled
+* through compat_blkdev_ioctl().
+*/
+out:
+   mutex_unlock(_floppy_ioctl_mutex);
+   return err;
+}
+#endif
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index dba9ad5c97b3..1b0270efcce2 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -341,11 +341,25 @@ static int ide_gd_ioctl(struct block_device *bdev, 
fmode_t mode,
return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
 }
 
+#ifdef CONFIG_COMPAT
+static int ide_gd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+  unsigned int cmd, unsigned long arg)
+{
+   struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+   ide_drive_t *drive = idkp->drive;
+
+   return drive->disk_ops->compat_ioctl(drive, bdev, mode, cmd, arg);
+}
+#endif
+
 static const struct block_device_operations ide_gd_ops = {
.owner  = THIS_MODULE,
.open   = ide_gd_unlocked_open,
.release= ide_gd_release,
.ioctl  = ide_gd_ioctl,
+#ifdef CONFIG_COMPAT
+   .ioctl  = ide_gd_compat_ioctl,
+#endif
.getgeo = ide_gd_getgeo,
.check_events   = ide_gd_check_events,
.unlock_native_capacity = ide_gd_unlock_native_capacity,
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 46b771d6999e..06dae6438557 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -413,6 +413,8 @@ struct ide_disk_ops {
  sector_t);
int (*ioctl)(struct ide_drive_s *, struct block_device *,
 fmode_t, unsigned int, unsigned long);
+   int (*compat_ioctl)(struct ide_drive_s *, struct 
block_device *,
+   fmode_t, unsigned int, unsigned long);
 };
 
 /* ATAPI device flags */
-- 
2.20.0

__

[Y2038] [PATCH v2 26/27] compat_ioctl: simplify up block/ioctl.c

2019-12-17 Thread Arnd Bergmann
Having separate implementations of blkdev_ioctl() often leads to these
getting out of sync, despite the comment at the top.

Since most of the ioctl commands are compatible, and we try very hard
not to add any new incompatible ones, move all the common bits into a
shared function and leave only the ones that are historically different
in separate functions for native/compat mode.

To deal with the compat_ptr() conversion, pass both the integer
argument and the pointer argument into the new blkdev_common_ioctl()
and make sure to always use the correct one of these.

blkdev_ioctl() is now only kept as a separate exported interfact
for drivers/char/raw.c, which lacks a compat_ioctl variant.
We should probably either move raw.c to staging if there are no
more users, or export blkdev_compat_ioctl() as well.

Signed-off-by: Arnd Bergmann 
---
 block/ioctl.c | 269 ++
 1 file changed, 117 insertions(+), 152 deletions(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index d6911a1149f5..127194b9f9bd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -270,65 +270,45 @@ static int blk_ioctl_zeroout(struct block_device *bdev, 
fmode_t mode,
BLKDEV_ZERO_NOUNMAP);
 }
 
-static int put_ushort(unsigned long arg, unsigned short val)
+static int put_ushort(unsigned short __user *argp, unsigned short val)
 {
-   return put_user(val, (unsigned short __user *)arg);
+   return put_user(val, argp);
 }
 
-static int put_int(unsigned long arg, int val)
+static int put_int(int __user *argp, int val)
 {
-   return put_user(val, (int __user *)arg);
+   return put_user(val, argp);
 }
 
-static int put_uint(unsigned long arg, unsigned int val)
+static int put_uint(unsigned int __user *argp, unsigned int val)
 {
-   return put_user(val, (unsigned int __user *)arg);
+   return put_user(val, argp);
 }
 
-static int put_long(unsigned long arg, long val)
+static int put_long(long __user *argp, long val)
 {
-   return put_user(val, (long __user *)arg);
+   return put_user(val, argp);
 }
 
-static int put_ulong(unsigned long arg, unsigned long val)
+static int put_ulong(unsigned long __user *argp, unsigned long val)
 {
-   return put_user(val, (unsigned long __user *)arg);
+   return put_user(val, argp);
 }
 
-static int put_u64(unsigned long arg, u64 val)
+static int put_u64(u64 __user *argp, u64 val)
 {
-   return put_user(val, (u64 __user *)arg);
+   return put_user(val, argp);
 }
 
 #ifdef CONFIG_COMPAT
-static int compat_put_ushort(unsigned long arg, unsigned short val)
+static int compat_put_long(compat_long_t *argp, long val)
 {
-   return put_user(val, (unsigned short __user *)compat_ptr(arg));
+   return put_user(val, argp);
 }
 
-static int compat_put_int(unsigned long arg, int val)
+static int compat_put_ulong(compat_ulong_t *argp, compat_ulong_t val)
 {
-   return put_user(val, (compat_int_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_uint(unsigned long arg, unsigned int val)
-{
-   return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_long(unsigned long arg, long val)
-{
-   return put_user(val, (compat_long_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_ulong(unsigned long arg, compat_ulong_t val)
-{
-   return put_user(val, (compat_ulong_t __user *)compat_ptr(arg));
-}
-
-static int compat_put_u64(unsigned long arg, u64 val)
-{
-   return put_user(val, (compat_u64 __user *)compat_ptr(arg));
+   return put_user(val, argp);
 }
 #endif
 
@@ -547,9 +527,10 @@ struct compat_hd_geometry {
u32 start;
 };
 
-static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
-   struct compat_hd_geometry __user *ugeo)
+static int compat_hdio_getgeo(struct block_device *bdev,
+ struct compat_hd_geometry __user *ugeo)
 {
+   struct gendisk *disk = bdev->bd_disk;
struct hd_geometry geo;
int ret;
 
@@ -603,13 +584,13 @@ static int blkdev_bszset(struct block_device *bdev, 
fmode_t mode,
 }
 
 /*
- * always keep this in sync with compat_blkdev_ioctl()
+ * Common commands that are handled the same way on native and compat
+ * user space. Note the separate arg/argp parameters that are needed
+ * to deal with the compat_ptr() conversion.
  */
-int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
-   unsigned long arg)
+static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
+   unsigned cmd, unsigned long arg, void __user 
*argp)
 {
-   void __user *argp = (void __user *)arg;
-   loff_t size;
unsigned int max_sectors;
 
switch (cmd) {
@@ -632,60 +613,39 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, 
unsigned cmd,
case BLKFINISHZONE:
return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg);
case BLKGETZON

[Y2038] [PATCH v2 14/27] compat_ioctl: block: handle cdrom compat ioctl in non-cdrom drivers

2019-12-17 Thread Arnd Bergmann
Various block drivers implement the CDROMMULTISESSION,
CDROM_GET_CAPABILITY, and CDROMEJECT ioctl commands, relying on the
block layer to handle compat_ioctl mode for them.

Move this into the drivers directly as a preparation for simplifying
the block layer later.

When only integer arguments or no arguments are passed, the
same handler can be used for .ioctl and .compat_ioctl, and
when only pointer arguments are passed, the newly added
blkdev_compat_ptr_ioctl can be used.

Signed-off-by: Arnd Bergmann 
---
 drivers/block/floppy.c   | 3 +++
 drivers/block/paride/pd.c| 1 +
 drivers/block/paride/pf.c| 1 +
 drivers/block/sunvdc.c   | 1 +
 drivers/block/xen-blkfront.c | 1 +
 5 files changed, 7 insertions(+)

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 485865fd0412..cd3612e4e2e1 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3879,6 +3879,9 @@ static int fd_compat_ioctl(struct block_device *bdev, 
fmode_t mode, unsigned int
 {
int drive = (long)bdev->bd_disk->private_data;
switch (cmd) {
+   case CDROMEJECT: /* CD-ROM eject */
+   case 0x6470: /* SunOS floppy eject */
+
case FDMSGON:
case FDMSGOFF:
case FDSETEMSGTRESH:
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 6f9ad3fc716f..c0967507d085 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -874,6 +874,7 @@ static const struct block_device_operations pd_fops = {
.open   = pd_open,
.release= pd_release,
.ioctl  = pd_ioctl,
+   .compat_ioctl   = pd_ioctl,
.getgeo = pd_getgeo,
.check_events   = pd_check_events,
.revalidate_disk= pd_revalidate
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 6b7d4cab3687..bb09f21ce21a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -276,6 +276,7 @@ static const struct block_device_operations pf_fops = {
.open   = pf_open,
.release= pf_release,
.ioctl  = pf_ioctl,
+   .compat_ioctl   = pf_ioctl,
.getgeo = pf_getgeo,
.check_events   = pf_check_events,
 };
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 571612e233fe..39aeebc6837d 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -171,6 +171,7 @@ static const struct block_device_operations vdc_fops = {
.owner  = THIS_MODULE,
.getgeo = vdc_getgeo,
.ioctl  = vdc_ioctl,
+   .compat_ioctl   = blkdev_compat_ptr_ioctl,
 };
 
 static void vdc_blk_queue_start(struct vdc_port *port)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index a74d03913822..23c86350a5ab 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -2632,6 +2632,7 @@ static const struct block_device_operations 
xlvbd_block_fops =
.release = blkif_release,
.getgeo = blkif_getgeo,
.ioctl = blkif_ioctl,
+   .compat_ioctl = blkdev_compat_ptr_ioctl,
 };
 
 
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 07/27] compat: provide compat_ptr() on all architectures

2019-12-17 Thread Arnd Bergmann
In order to avoid needless #ifdef CONFIG_COMPAT checks,
move the compat_ptr() definition to linux/compat.h
where it can be seen by any file regardless of the
architecture.

Only s390 needs a special definition, this can use the
self-#define trick we have elsewhere.

Signed-off-by: Arnd Bergmann 
---
 arch/arm64/include/asm/compat.h   | 17 -
 arch/mips/include/asm/compat.h| 18 --
 arch/parisc/include/asm/compat.h  | 17 -
 arch/powerpc/include/asm/compat.h | 17 -
 arch/powerpc/oprofile/backtrace.c |  2 +-
 arch/s390/include/asm/compat.h|  6 +-
 arch/sparc/include/asm/compat.h   | 17 -
 arch/x86/include/asm/compat.h | 17 -
 include/linux/compat.h| 18 ++
 9 files changed, 20 insertions(+), 109 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 7b4172ce497c..935d2aa231bf 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -114,23 +114,6 @@ typedef u32compat_sigset_word;
 
 #define COMPAT_OFF_T_MAX   0x7fff
 
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately converted them already.
- */
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-   return (void __user *)(unsigned long)uptr;
-}
-
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
-{
-   return (u32)(unsigned long)uptr;
-}
-
 #define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
 #define COMPAT_MINSIGSTKSZ 2048
 
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index c99166eadbde..255afcdd79c9 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -100,24 +100,6 @@ typedef u32compat_sigset_word;
 
 #define COMPAT_OFF_T_MAX   0x7fff
 
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately converted them already.
- */
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-   /* cast to a __user pointer via "unsigned long" makes sparse happy */
-   return (void __user *)(unsigned long)(long)uptr;
-}
-
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
-{
-   return (u32)(unsigned long)uptr;
-}
-
 static inline void __user *arch_compat_alloc_user_space(long len)
 {
struct pt_regs *regs = (struct pt_regs *)
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index e03e3c849f40..2f4f66a3bac0 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -173,23 +173,6 @@ struct compat_shmid64_ds {
 #define COMPAT_ELF_NGREG 80
 typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
 
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately converted them already.
- */
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-   return (void __user *)(unsigned long)uptr;
-}
-
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
-{
-   return (u32)(unsigned long)uptr;
-}
-
 static __inline__ void __user *arch_compat_alloc_user_space(long len)
 {
struct pt_regs *regs = >thread.regs;
diff --git a/arch/powerpc/include/asm/compat.h 
b/arch/powerpc/include/asm/compat.h
index 74d0db511099..3e3cdfaa76c6 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -96,23 +96,6 @@ typedef u32  compat_sigset_word;
 
 #define COMPAT_OFF_T_MAX   0x7fff
 
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately converted them already.
- */
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-   return (void __user *)(unsigned long)uptr;
-}
-
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
-{
-   return (u32)(unsigned long)uptr;
-}
-
 static inline void __user *arch_compat_alloc_user_space(long len)
 {
struct pt_regs *regs = current->thread.regs;
diff --git a/arch/powerpc/oprofile/backtrace.c 
b/arch/powerpc/oprofile/backtrace.c
index 43245f4a9bcb..6ffcb80cf844 100644
--- a/arch/powerpc/oprofile/backtrace.c
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -9,7 +9,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #define STACK_SP(STACK)*(STACK)
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 63b46e30b2c3..9547cd5d6cdc 100644
--- a/arch/s390/include/asm/compat.h
+++ b/a

[Y2038] [PATCH v2 25/27] compat_ioctl: block: simplify compat_blkpg_ioctl()

2019-12-17 Thread Arnd Bergmann
There is no need to go through a compat_alloc_user_space()
copy any more, just wrap the function in a small helper that
works the same way for native and compat mode.

Signed-off-by: Arnd Bergmann 
---
 block/ioctl.c | 74 ++-
 1 file changed, 38 insertions(+), 36 deletions(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index f8c4e2649335..d6911a1149f5 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -12,12 +12,12 @@
 #include 
 #include 
 
-static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg 
__user *arg)
+static int blkpg_do_ioctl(struct block_device *bdev,
+ struct blkpg_partition __user *upart, int op)
 {
struct block_device *bdevp;
struct gendisk *disk;
struct hd_struct *part, *lpart;
-   struct blkpg_ioctl_arg a;
struct blkpg_partition p;
struct disk_part_iter piter;
long long start, length;
@@ -25,9 +25,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct 
blkpg_ioctl_arg __user
 
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
-   if (copy_from_user(, arg, sizeof(struct blkpg_ioctl_arg)))
-   return -EFAULT;
-   if (copy_from_user(, a.data, sizeof(struct blkpg_partition)))
+   if (copy_from_user(, upart, sizeof(struct blkpg_partition)))
return -EFAULT;
disk = bdev->bd_disk;
if (bdev != bdev->bd_contains)
@@ -35,7 +33,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct 
blkpg_ioctl_arg __user
partno = p.pno;
if (partno <= 0)
return -EINVAL;
-   switch (a.op) {
+   switch (op) {
case BLKPG_ADD_PARTITION:
start = p.start >> 9;
length = p.length >> 9;
@@ -156,6 +154,39 @@ static int blkpg_ioctl(struct block_device *bdev, struct 
blkpg_ioctl_arg __user
}
 }
 
+static int blkpg_ioctl(struct block_device *bdev,
+  struct blkpg_ioctl_arg __user *arg)
+{
+   struct blkpg_partition __user *udata;
+   int op;
+
+   if (get_user(op, >op) || get_user(udata, >data))
+   return -EFAULT;
+
+   return blkpg_do_ioctl(bdev, udata, op);
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_blkpg_ioctl_arg {
+   compat_int_t op;
+   compat_int_t flags;
+   compat_int_t datalen;
+   compat_caddr_t data;
+};
+
+static int compat_blkpg_ioctl(struct block_device *bdev,
+ struct compat_blkpg_ioctl_arg __user *arg)
+{
+   compat_caddr_t udata;
+   int op;
+
+   if (get_user(op, >op) || get_user(udata, >data))
+   return -EFAULT;
+
+   return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
+}
+#endif
+
 static int blkdev_reread_part(struct block_device *bdev)
 {
int ret;
@@ -676,35 +707,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, 
unsigned cmd,
 EXPORT_SYMBOL_GPL(blkdev_ioctl);
 
 #ifdef CONFIG_COMPAT
-struct compat_blkpg_ioctl_arg {
-   compat_int_t op;
-   compat_int_t flags;
-   compat_int_t datalen;
-   compat_caddr_t data;
-};
-
-static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
-   unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
-{
-   struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
-   compat_caddr_t udata;
-   compat_int_t n;
-   int err;
-
-   err = get_user(n, >op);
-   err |= put_user(n, >op);
-   err |= get_user(n, >flags);
-   err |= put_user(n, >flags);
-   err |= get_user(n, >datalen);
-   err |= put_user(n, >datalen);
-   err |= get_user(udata, >data);
-   err |= put_user(compat_ptr(udata), >data);
-   if (err)
-   return err;
-
-   return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
-}
-
 #define BLKBSZGET_32   _IOR(0x12, 112, int)
 #define BLKBSZSET_32   _IOW(0x12, 113, int)
 #define BLKGETSIZE64_32_IOR(0x12, 114, int)
@@ -767,7 +769,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
return blkdev_ioctl(bdev, mode, BLKBSZSET,
(unsigned long)compat_ptr(arg));
case BLKPG:
-   return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
+   return compat_blkpg_ioctl(bdev, compat_ptr(arg));
case BLKRAGET:
case BLKFRAGET:
if (!arg)
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 19/27] compat_ioctl: move sys_compat_ioctl() to ioctl.c

2019-12-17 Thread Arnd Bergmann
The rest of the fs/compat_ioctl.c file is no longer useful now,
so move the actual syscall as planned.

Signed-off-by: Arnd Bergmann 
---
 fs/Makefile   |   2 +-
 fs/compat_ioctl.c | 133 --
 fs/ioctl.c|  90 +++
 3 files changed, 91 insertions(+), 134 deletions(-)
 delete mode 100644 fs/compat_ioctl.c

diff --git a/fs/Makefile b/fs/Makefile
index 1148c555c4d3..98be354fdb61 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_FS_DAX)  += dax.o
 obj-$(CONFIG_FS_ENCRYPTION)+= crypto/
 obj-$(CONFIG_FS_VERITY)+= verity/
 obj-$(CONFIG_FILE_LOCKING)  += locks.o
-obj-$(CONFIG_COMPAT)   += compat.o compat_ioctl.o
+obj-$(CONFIG_COMPAT)   += compat.o
 obj-$(CONFIG_BINFMT_AOUT)  += binfmt_aout.o
 obj-$(CONFIG_BINFMT_EM86)  += binfmt_em86.o
 obj-$(CONFIG_BINFMT_MISC)  += binfmt_misc.o
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
deleted file mode 100644
index ab4471f469e6..
--- a/fs/compat_ioctl.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (ja...@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (e...@skynet.be)
- * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
- * Copyright (C) 2003   Pavel Machek (pa...@ucw.cz)
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "internal.h"
-
-#include 
-#include 
-
-#include 
-
-COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
-  compat_ulong_t, arg32)
-{
-   unsigned long arg = arg32;
-   struct fd f = fdget(fd);
-   int error = -EBADF;
-   if (!f.file)
-   goto out;
-
-   /* RED-PEN how should LSM module know it's handling 32bit? */
-   error = security_file_ioctl(f.file, cmd, arg);
-   if (error)
-   goto out_fput;
-
-   switch (cmd) {
-   /* these are never seen by ->ioctl(), no argument or int argument */
-   case FIOCLEX:
-   case FIONCLEX:
-   case FIFREEZE:
-   case FITHAW:
-   case FICLONE:
-   goto do_ioctl;
-   /* these are never seen by ->ioctl(), pointer argument */
-   case FIONBIO:
-   case FIOASYNC:
-   case FIOQSIZE:
-   case FS_IOC_FIEMAP:
-   case FIGETBSZ:
-   case FICLONERANGE:
-   case FIDEDUPERANGE:
-   goto found_handler;
-   /*
-* The next group is the stuff handled inside file_ioctl().
-* For regular files these never reach ->ioctl(); for
-* devices, sockets, etc. they do and one (FIONREAD) is
-* even accepted in some cases.  In all those cases
-* argument has the same type, so we can handle these
-* here, shunting them towards do_vfs_ioctl().
-* ->compat_ioctl() will never see any of those.
-*/
-   /* pointer argument, never actually handled by ->ioctl() */
-   case FIBMAP:
-   goto found_handler;
-   /* handled by some ->ioctl(); always a pointer to int */
-   case FIONREAD:
-   goto found_handler;
-   /* these get messy on amd64 due to alignment differences */
-#if defined(CONFIG_X86_64)
-   case FS_IOC_RESVSP_32:
-   case FS_IOC_RESVSP64_32:
-   error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
-   goto out_fput;
-   case FS_IOC_UNRESVSP_32:
-   case FS_IOC_UNRESVSP64_32:
-   error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
-   compat_ptr(arg));
-   goto out_fput;
-   case FS_IOC_ZERO_RANGE_32:
-   error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
-   compat_ptr(arg));
-   goto out_fput;
-#else
-   case FS_IOC_RESVSP:
-   case FS_IOC_RESVSP64:
-   case FS_IOC_UNRESVSP:
-   case FS_IOC_UNRESVSP64:
-   case FS_IOC_ZERO_RANGE:
-   goto found_handler;
-#endif
-
-   default:
-   if (f.file->f_op->compat_ioctl) {
-   error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
-   if (error != -ENOIOCTLCMD)
-   goto out_fput;
-   }
-
-   error = -ENOTTY;
-   goto out_fput;
-   }
-
- found_handler:
-   arg = (unsigned long)compat_ptr(arg);
- do_ioctl:
-   error = do_vfs_ioctl(f.file, fd, cmd, arg);
- out_fput:
-   fdput(f);
- out:
-   return error;
-}
diff --git a/fs

[Y2038] [PATCH v2 02/27] compat_ioctl: block: handle BLKREPORTZONE/BLKRESETZONE

2019-12-17 Thread Arnd Bergmann
These were added to blkdev_ioctl() but not blkdev_compat_ioctl,
so add them now.

Cc:  # v4.10+
Fixes: 3ed05a987e0f ("blk-zoned: implement ioctls")
Reviewed-by: Damien Le Moal 
Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 6ca015f92766..830f91e05fe3 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -354,6 +354,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
 * but we call blkdev_ioctl, which gets the lock for us
 */
case BLKRRPART:
+   case BLKREPORTZONE:
+   case BLKRESETZONE:
return blkdev_ioctl(bdev, mode, cmd,
(unsigned long)compat_ptr(arg));
case BLKBSZSET_32:
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 13/27] compat_ioctl: cdrom: handle CDROM_LAST_WRITTEN

2019-12-17 Thread Arnd Bergmann
This is the only ioctl command that does not have a proper
compat handler. Making the normal implementation do the
right thing is actually very simply, so just do that by
using an in_compat_syscall() check to avoid the special
case in the pkcdvd driver.

Signed-off-by: Arnd Bergmann 
---
 drivers/block/pktcdvd.c | 24 +---
 drivers/cdrom/cdrom.c   |  7 ---
 2 files changed, 5 insertions(+), 26 deletions(-)

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index ab4d3be4b646..5f970a7d32c0 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2663,26 +2663,6 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t 
mode, unsigned int cmd,
return ret;
 }
 
-#ifdef CONFIG_COMPAT
-static int pkt_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned 
int cmd, unsigned long arg)
-{
-   switch (cmd) {
-   /* compatible */
-   case CDROMEJECT:
-   case CDROMMULTISESSION:
-   case CDROMREADTOCENTRY:
-   case CDROM_SEND_PACKET: /* compat mode handled in scsi_cmd_ioctl */
-   case SCSI_IOCTL_SEND_COMMAND:
-   return pkt_ioctl(bdev, mode, cmd, (unsigned 
long)compat_ptr(arg));
-
-   /* FIXME: no handler so far */
-   default:
-   case CDROM_LAST_WRITTEN:
-   return -ENOIOCTLCMD;
-   }
-}
-#endif
-
 static unsigned int pkt_check_events(struct gendisk *disk,
 unsigned int clearing)
 {
@@ -2704,9 +2684,7 @@ static const struct block_device_operations pktcdvd_ops = 
{
.open = pkt_open,
.release =  pkt_close,
.ioctl =pkt_ioctl,
-#ifdef CONFIG_COMPAT
-   .compat_ioctl = pkt_compat_ioctl,
-#endif
+   .compat_ioctl = blkdev_compat_ptr_ioctl,
.check_events = pkt_check_events,
 };
 
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 48095025e588..faca0f346fff 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3293,9 +3293,10 @@ static noinline int mmc_ioctl_cdrom_last_written(struct 
cdrom_device_info *cdi,
ret = cdrom_get_last_written(cdi, );
if (ret)
return ret;
-   if (copy_to_user((long __user *)arg, , sizeof(last)))
-   return -EFAULT;
-   return 0;
+   if (in_compat_syscall())
+   return put_user(last, (__s32 __user *)arg);
+
+   return put_user(last, (long __user *)arg);
 }
 
 static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 12/27] compat_ioctl: move CDROMREADADIO to cdrom.c

2019-12-17 Thread Arnd Bergmann
Again, there is only one file that needs this, so move the conversion
handler into the native implementation.

Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c  | 36 
 drivers/cdrom/cdrom.c | 28 +---
 2 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 578e04f94619..cf136bc2c9fc 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -95,40 +95,6 @@ static int compat_hdio_ioctl(struct block_device *bdev, 
fmode_t mode,
return error;
 }
 
-struct compat_cdrom_read_audio {
-   union cdrom_addraddr;
-   u8  addr_format;
-   compat_int_tnframes;
-   compat_caddr_t  buf;
-};
-
-static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
-   unsigned int cmd, unsigned long arg)
-{
-   struct cdrom_read_audio __user *cdread_audio;
-   struct compat_cdrom_read_audio __user *cdread_audio32;
-   __u32 data;
-   void __user *datap;
-
-   cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio));
-   cdread_audio32 = compat_ptr(arg);
-
-   if (copy_in_user(_audio->addr,
-_audio32->addr,
-(sizeof(*cdread_audio32) -
- sizeof(compat_caddr_t
-   return -EFAULT;
-
-   if (get_user(data, _audio32->buf))
-   return -EFAULT;
-   datap = compat_ptr(data);
-   if (put_user(datap, _audio->buf))
-   return -EFAULT;
-
-   return __blkdev_driver_ioctl(bdev, mode, cmd,
-   (unsigned long)cdread_audio);
-}
-
 struct compat_blkpg_ioctl_arg {
compat_int_t op;
compat_int_t flags;
@@ -178,8 +144,6 @@ static int compat_blkdev_driver_ioctl(struct block_device 
*bdev, fmode_t mode,
case HDIO_GET_ADDRESS:
case HDIO_GET_BUSSTATE:
return compat_hdio_ioctl(bdev, mode, cmd, arg);
-   case CDROMREADAUDIO:
-   return compat_cdrom_read_audio(bdev, mode, cmd, arg);
 
/*
 * No handler required for the ones below, we just need to
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index eebdcbef0578..48095025e588 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3017,9 +3017,31 @@ static noinline int mmc_ioctl_cdrom_read_audio(struct 
cdrom_device_info *cdi,
struct cdrom_read_audio ra;
int lba;
 
-   if (copy_from_user(, (struct cdrom_read_audio __user *)arg,
-  sizeof(ra)))
-   return -EFAULT;
+#ifdef CONFIG_COMPAT
+   if (in_compat_syscall()) {
+   struct compat_cdrom_read_audio {
+   union cdrom_addraddr;
+   u8  addr_format;
+   compat_int_tnframes;
+   compat_caddr_t  buf;
+   } ra32;
+
+   if (copy_from_user(, arg, sizeof(ra32)))
+   return -EFAULT;
+
+   ra = (struct cdrom_read_audio) {
+   .addr   = ra32.addr,
+   .addr_format= ra32.addr_format,
+   .nframes= ra32.nframes,
+   .buf= compat_ptr(ra32.buf),
+   };
+   } else
+#endif
+   {
+   if (copy_from_user(, (struct cdrom_read_audio __user *)arg,
+  sizeof(ra)))
+   return -EFAULT;
+   }
 
if (ra.addr_format == CDROM_MSF)
lba = msf_to_lba(ra.addr.msf.minute,
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 08/27] compat: scsi: sg: fix v3 compat read/write interface

2019-12-17 Thread Arnd Bergmann
In the v5.4 merge window, a cleanup patch from Al Viro conflicted
with my rework of the compat handling for sg.c read(). Linus Torvalds
did a correct merge but pointed out that the resulting code is still
unsatisfactory.

I later noticed that the sg_new_read() function still gets the compat
mode wrong, when the 'count' argument is large enough to pass a
compat_sg_io_hdr object, but not a nativ sg_io_hdr.

To address both of these, move the definition of compat_sg_io_hdr
into a scsi/sg.h to make it visible to sg.c and rewrite the logic
for reading req_pack_id as well as the size check to a simpler
version that gets the expected results.

Fixes: c35a5cfb4150 ("scsi: sg: sg_read(): simplify reading ->pack_id of 
userland sg_io_hdr_t")
Fixes: 98aaaec4a150 ("compat_ioctl: reimplement SG_IO handling")
Signed-off-by: Arnd Bergmann 
---
 block/scsi_ioctl.c |  29 +--
 drivers/scsi/sg.c  | 126 +
 include/scsi/sg.h  |  30 +++
 3 files changed, 90 insertions(+), 95 deletions(-)

diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 650bade5ea5a..b61dbf4d8443 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct blk_cmd_filter {
unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
@@ -550,34 +551,6 @@ static inline int blk_send_start_stop(struct request_queue 
*q,
return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_sg_io_hdr {
-   compat_int_t interface_id;  /* [i] 'S' for SCSI generic (required) 
*/
-   compat_int_t dxfer_direction;   /* [i] data transfer direction  */
-   unsigned char cmd_len;  /* [i] SCSI command length ( <= 16 
bytes) */
-   unsigned char mx_sb_len;/* [i] max length to write to sbp */
-   unsigned short iovec_count; /* [i] 0 implies no scatter gather */
-   compat_uint_t dxfer_len;/* [i] byte count of data transfer */
-   compat_uint_t dxferp;   /* [i], [*io] points to data transfer 
memory
-   or scatter gather list */
-   compat_uptr_t cmdp; /* [i], [*i] points to command to 
perform */
-   compat_uptr_t sbp;  /* [i], [*o] points to sense_buffer 
memory */
-   compat_uint_t timeout;  /* [i] MAX_UINT->no timeout (unit: 
millisec) */
-   compat_uint_t flags;/* [i] 0 -> default, see SG_FLAG... */
-   compat_int_t pack_id;   /* [i->o] unused internally (normally) 
*/
-   compat_uptr_t usr_ptr;  /* [i->o] unused internally */
-   unsigned char status;   /* [o] scsi status */
-   unsigned char masked_status;/* [o] shifted, masked scsi status */
-   unsigned char msg_status;   /* [o] messaging level data (optional) 
*/
-   unsigned char sb_len_wr;/* [o] byte count actually written to 
sbp */
-   unsigned short host_status; /* [o] errors from host adapter */
-   unsigned short driver_status;   /* [o] errors from software driver */
-   compat_int_t resid; /* [o] dxfer_len - actual_transferred */
-   compat_uint_t duration; /* [o] time taken by cmd (unit: 
millisec) */
-   compat_uint_t info; /* [o] auxiliary information */
-};
-#endif
-
 int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp)
 {
 #ifdef CONFIG_COMPAT
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 160748ad9c0f..eace8886d95a 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -405,6 +405,38 @@ sg_release(struct inode *inode, struct file *filp)
return 0;
 }
 
+static int get_sg_io_pack_id(int *pack_id, void __user *buf, size_t count)
+{
+   struct sg_header __user *old_hdr = buf;
+   int reply_len;
+
+   if (count >= SZ_SG_HEADER) {
+   /* negative reply_len means v3 format, otherwise v1/v2 */
+   if (get_user(reply_len, _hdr->reply_len))
+   return -EFAULT;
+
+   if (reply_len >= 0)
+   return get_user(*pack_id, _hdr->pack_id);
+
+   if (in_compat_syscall() &&
+   count >= sizeof(struct compat_sg_io_hdr)) {
+   struct compat_sg_io_hdr __user *hp = buf;
+
+   return get_user(*pack_id, >pack_id);
+   }
+
+   if (count >= sizeof(struct sg_io_hdr)) {
+   struct sg_io_hdr __user *hp = buf;
+
+   return get_user(*pack_id, >pack_id);
+   }
+   }
+
+   /* no valid header was passed, so ignore the pack_id */
+   *pack_id = -1;
+   return 0;
+}
+
 static ssize_t
 sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
@@ -413,8 +445,8 @@ sg_read(struct file *filp, char __user *buf, size_t c

[Y2038] [PATCH v2 06/27] compat: ARM64: always include asm-generic/compat.h

2019-12-17 Thread Arnd Bergmann
In order to use compat_* type defininitions in device drivers
outside of CONFIG_COMPAT, move the inclusion of asm-generic/compat.h
ahead of the #ifdef.

All other architectures already do this.

Acked-by: Will Deacon 
Signed-off-by: Arnd Bergmann 
---
 arch/arm64/include/asm/compat.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index b0d53a265f1d..7b4172ce497c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -4,6 +4,9 @@
  */
 #ifndef __ASM_COMPAT_H
 #define __ASM_COMPAT_H
+
+#include 
+
 #ifdef CONFIG_COMPAT
 
 /*
@@ -13,8 +16,6 @@
 #include 
 #include 
 
-#include 
-
 #define COMPAT_USER_HZ 100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE "armv8b\0\0"
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 03/27] compat_ioctl: block: handle BLKGETZONESZ/BLKGETNRZONES

2019-12-17 Thread Arnd Bergmann
These were added to blkdev_ioctl() in v4.20 but not blkdev_compat_ioctl,
so add them now.

Cc:  # v4.20+
Fixes: 72cd87576d1d ("block: Introduce BLKGETZONESZ ioctl")
Fixes: 65e4e3eee83d ("block: Introduce BLKGETNRZONES ioctl")
Reviewed-by: Damien Le Moal 
Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 830f91e05fe3..f5c1140b8624 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -356,6 +356,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
case BLKRRPART:
case BLKREPORTZONE:
case BLKRESETZONE:
+   case BLKGETZONESZ:
+   case BLKGETNRZONES:
return blkdev_ioctl(bdev, mode, cmd,
(unsigned long)compat_ptr(arg));
case BLKBSZSET_32:
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 10/27] compat_ioctl: ubd, aoe: use blkdev_compat_ptr_ioctl

2019-12-17 Thread Arnd Bergmann
These drivers implement the HDIO_GET_IDENTITY and CDROMVOLREAD ioctl
commands, which are compatible between 32-bit and 64-bit user space and
traditionally handled by compat_blkdev_driver_ioctl().

As a prerequisite to removing that function, make both drivers use
blkdev_compat_ptr_ioctl() as their .compat_ioctl callback.

Signed-off-by: Arnd Bergmann 
---
 arch/um/drivers/ubd_kern.c | 1 +
 drivers/block/aoe/aoeblk.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 6627d7c30f37..582eb5b1f09b 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -113,6 +113,7 @@ static const struct block_device_operations ubd_blops = {
 .open  = ubd_open,
 .release   = ubd_release,
 .ioctl = ubd_ioctl,
+.compat_ioctl  = blkdev_compat_ptr_ioctl,
.getgeo = ubd_getgeo,
 };
 
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index bd19f8af950b..7b32fb673375 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -329,6 +329,7 @@ static const struct block_device_operations aoe_bdops = {
.open = aoeblk_open,
.release = aoeblk_release,
.ioctl = aoeblk_ioctl,
+   .compat_ioctl = blkdev_compat_ptr_ioctl,
.getgeo = aoeblk_getgeo,
.owner = THIS_MODULE,
 };
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 09/27] compat_ioctl: block: add blkdev_compat_ptr_ioctl

2019-12-17 Thread Arnd Bergmann
A lot of block drivers need only a trivial .compat_ioctl callback.

Add a helper function that can be set as the callback pointer
to only convert the argument using the compat_ptr() conversion
and otherwise assume all input and output data is compatible,
or handled using in_compat_syscall() checks.

This mirrors the compat_ptr_ioctl() helper function used in
character devices.

Signed-off-by: Arnd Bergmann 
---
 block/ioctl.c  | 21 +
 include/linux/blkdev.h |  7 +++
 2 files changed, 28 insertions(+)

diff --git a/block/ioctl.c b/block/ioctl.c
index 5de98b97af2a..e728331d1a5b 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -285,6 +286,26 @@ int __blkdev_driver_ioctl(struct block_device *bdev, 
fmode_t mode,
  */
 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
 
+#ifdef CONFIG_COMPAT
+/*
+ * This is the equivalent of compat_ptr_ioctl(), to be used by block
+ * drivers that implement only commands that are completely compatible
+ * between 32-bit and 64-bit user space
+ */
+int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode,
+   unsigned cmd, unsigned long arg)
+{
+   struct gendisk *disk = bdev->bd_disk;
+
+   if (disk->fops->ioctl)
+   return disk->fops->ioctl(bdev, mode, cmd,
+(unsigned long)compat_ptr(arg));
+
+   return -ENOIOCTLCMD;
+}
+EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
+#endif
+
 static int blkdev_pr_register(struct block_device *bdev,
struct pr_registration __user *arg)
 {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 47eb22a3b7f9..3e0408618da7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1711,6 +1711,13 @@ struct block_device_operations {
const struct pr_ops *pr_ops;
 };
 
+#ifdef CONFIG_COMPAT
+extern int blkdev_compat_ptr_ioctl(struct block_device *, fmode_t,
+ unsigned int, unsigned long);
+#else
+#define blkdev_compat_ptr_ioctl NULL
+#endif
+
 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
 unsigned long);
 extern int bdev_read_page(struct block_device *, sector_t, struct page *);
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 05/27] compat_ioctl: block: handle Persistent Reservations

2019-12-17 Thread Arnd Bergmann
These were added to blkdev_ioctl() in linux-5.5 but not
blkdev_compat_ioctl, so add them now.

Cc:  # v4.4+
Fixes: bbd3e064362e ("block: add an API for Persistent Reservations")
Signed-off-by: Arnd Bergmann 
---
 block/compat_ioctl.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 5b13e344229c..f16ae92065d7 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -408,6 +408,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
case BLKTRACETEARDOWN: /* compatible */
ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
return ret;
+   case IOC_PR_REGISTER:
+   case IOC_PR_RESERVE:
+   case IOC_PR_RELEASE:
+   case IOC_PR_PREEMPT:
+   case IOC_PR_PREEMPT_ABORT:
+   case IOC_PR_CLEAR:
+   return blkdev_ioctl(bdev, mode, cmd,
+   (unsigned long)compat_ptr(arg));
default:
if (disk->fops->compat_ioctl)
ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v2 01/27] pktcdvd: fix regression on 64-bit architectures

2019-12-17 Thread Arnd Bergmann
The support for the compat ioctl did not actually do what it was
supposed to do because of a typo, instead it broke native support for
CDROM_LAST_WRITTEN and CDROM_SEND_PACKET on all architectures with
CONFIG_COMPAT enabled.

Fixes: 1b114b0817cc ("pktcdvd: add compat_ioctl handler")
Signed-off-by: Arnd Bergmann 

Please apply for v5.5, I just noticed the regression while
rebasing some of the patches I created on top.
---
 drivers/block/pktcdvd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index ee67bf929fac..861fc65a1b75 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2707,7 +2707,7 @@ static const struct block_device_operations pktcdvd_ops = 
{
.release =  pkt_close,
.ioctl =pkt_ioctl,
 #ifdef CONFIG_COMPAT
-   .ioctl =pkt_compat_ioctl,
+   .compat_ioctl = pkt_compat_ioctl,
 #endif
.check_events = pkt_check_events,
 };
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [GIT PULL v2 00/27] block, scsi: final compat_ioctl cleanup

2019-12-17 Thread Arnd Bergmann
The following changes since commit e42617b825f8073569da76dc4510bfa019b1c35a:

  Linux 5.5-rc1 (2019-12-08 14:57:55 -0800)

are available in the Git repository at:

  git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git 
tags/block-ioctl-cleanup-5.6

for you to fetch changes up to 3462d5c19dac7c062c5a2db727775116e6d2b28e:

  Documentation: document ioctl interfaces better (2019-12-17 22:45:18 +0100)


block, scsi: final compat_ioctl cleanup

This series concludes the work I did for linux-5.5 on the compat_ioctl()
cleanup, killing off fs/compat_ioctl.c and block/compat_ioctl.c by moving
everything into drivers.

Overall this would be a reduction both in complexity and line count, but
as I'm also adding documentation the overall number of lines increases
in the end.

My plan was originally to keep the SCSI and block parts separate.
This did not work easily because of interdependencies: I cannot
do the final SCSI cleanup in a good way without first addressing the
CDROM ioctls, so this is one series that I hope could be merged through
either the block or the scsi git trees, or possibly both if you can
pull in the same branch.

The series comes in these steps:

1. clean up the sg v3 interface as suggested by Linus. I have
   talked about this with Doug Gilbert as well, and he would
   rebase his sg v4 patches on top of "compat: scsi: sg: fix v3
   compat read/write interface"

2. Actually moving handlers out of block/compat_ioctl.c and
   block/scsi_ioctl.c into drivers, mixed in with cleanup
   patches

3. Document how to do this right. I keep getting asked about this,
   and it helps to point to some documentation file.

The branch is based on another one that fixes a couple of bugs found
during the creation of this series.

Changes since the original version [1]:

- move out the bugfixes into a branch for itself
- clean up scsi sg driver further as suggested by Christoph Hellwig
- avoid some ifdefs by moving compat_ptr() out of asm/compat.h
- split out the blkdev_compat_ptr_ioctl function; bug spotted by
  Ben Hutchings
- Improve formatting of documentation

[1] 
https://lore.kernel.org/linux-block/20191211204306.1207817-1-a...@arndb.de/T/#m9f89df30565fc66abbded5d01f4db553b16f129f

----

Arnd Bergmann (22): (plus five from the first pull request)
  compat: ARM64: always include asm-generic/compat.h
  compat: provide compat_ptr() on all architectures
  compat: scsi: sg: fix v3 compat read/write interface
  compat_ioctl: block: add blkdev_compat_ptr_ioctl
  compat_ioctl: ubd, aoe: use blkdev_compat_ptr_ioctl
  compat_ioctl: move CDROM_SEND_PACKET handling into scsi
  compat_ioctl: move CDROMREADADIO to cdrom.c
  compat_ioctl: cdrom: handle CDROM_LAST_WRITTEN
  compat_ioctl: block: handle cdrom compat ioctl in non-cdrom drivers
  compat_ioctl: add scsi_compat_ioctl
  compat_ioctl: bsg: add handler
  compat_ioctl: ide: floppy: add handler
  compat_ioctl: scsi: move ioctl handling into drivers
  compat_ioctl: move sys_compat_ioctl() to ioctl.c
  compat_ioctl: simplify the implementation
  compat_ioctl: move cdrom commands into cdrom.c
  compat_ioctl: scsi: handle HDIO commands from drivers
  compat_ioctl: move HDIO ioctl handling into drivers/ide
  compat_ioctl: block: move blkdev_compat_ioctl() into ioctl.c
  compat_ioctl: block: simplify compat_blkpg_ioctl()
  compat_ioctl: simplify up block/ioctl.c
  Documentation: document ioctl interfaces better

 Documentation/core-api/index.rst   |   1 +
 Documentation/core-api/ioctl.rst   | 248 +++
 arch/arm64/include/asm/compat.h|  22 +-
 arch/mips/include/asm/compat.h |  18 --
 arch/parisc/include/asm/compat.h   |  17 -
 arch/powerpc/include/asm/compat.h  |  17 -
 arch/powerpc/oprofile/backtrace.c  |   2 +-
 arch/s390/include/asm/compat.h |   6 +-
 arch/sparc/include/asm/compat.h|  17 -
 arch/um/drivers/ubd_kern.c |   1 +
 arch/x86/include/asm/compat.h  |  17 -
 block/Makefile |   1 -
 block/bsg.c|   1 +
 block/compat_ioctl.c   | 411 -
 block/ioctl.c  | 319 +++
 block/scsi_ioctl.c | 214 -
 drivers/ata/libata-scsi.c  |   9 +
 drivers/block/aoe/aoeblk.c |   1 +
 drivers/block/floppy.c |   3 +
 drivers/block/paride/pcd.c |   3 +
 drivers/block/paride/pd.c  |   1 +
 drivers/block/paride/pf.c  |   1 +
 drivers/block/pktcdvd.c|  26 +-
 drivers/block/sunvdc.c |   1 +
 drivers/block/virtio_blk.c |   3 +
 drivers/block/xen-blkfront.c   |   1 +
 drivers/cdrom/cdrom.c  |  35 ++-
 drivers/cdrom/gdrom.c  |   3 +
 drivers/id

Re: [Y2038] [PATCH 10/24] compat_ioctl: cdrom: handle CDROM_LAST_WRITTEN

2019-12-17 Thread Arnd Bergmann
On Tue, Dec 17, 2019 at 4:20 PM Ben Hutchings
 wrote:
>
> On Wed, 2019-12-11 at 21:42 +0100, Arnd Bergmann wrote:
> > This is the only ioctl command that does not have a proper
> > compat handler. Making the normal implementation do the
> > right thing is actually very simply, so just do that by
> > using an in_compat_syscall() check to avoid the special
> > case in the pkcdvd driver.
> [...]
>
> Since this uses blkdev_compat_ptr_ioctl() it needs to be moved after
> the following patch.
>

Ah right, I obviously reshuffled my patches too much to end up
with the most reasonable order and avoid introducing something
that would be removed again later.

I'll split out the addition of blkdev_compat_ptr_ioctl() into a separate
patch and move that all in front, as I'm no longer sure if there
was another dependency in the other way.

Thanks!

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [GIT PULL, v8] Fix year 2038 issue for sound subsystem

2019-12-17 Thread Arnd Bergmann
The following changes since commit e42617b825f8073569da76dc4510bfa019b1c35a:

  Linux 5.5-rc1 (2019-12-08 14:57:55 -0800)

are available in the Git repository at:

  git://git.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git
tags/y2038-alsa-v8-signed

for you to fetch changes up to 1cfaef9617033f38eba9cc725809ed32bcdb3dc5:

  ALSA: bump uapi version numbers (2019-12-13 11:25:58 +0100)


ALSA: Fix year 2038 issue for sound subsystem

This is a series I worked on with Baolin in 2017 and 2018, but we
never quite managed to finish up the last pieces. During the
ALSA developer meetup at ELC-E 2018 in Edinburgh, a decision was
made to go with this approach for keeping best compatibility
with existing source code, and then I failed to follow up by
resending the patches.

Now I have patches for all remaining time_t uses in the kernel,
so it's absolutely time to revisit them. I have done more
review of the patches myself and found a couple of minor issues
that I have fixed up, otherwise the series is still the same as
before.

Conceptually, the idea of these patches is:

- 64-bit applications should see no changes at all, neither
  compile-time nor run-time.

- 32-bit code compiled with a 64-bit time_t currently
  does not work with ALSA, and requires kernel changes and/or
  sound/asound.h changes

- Most 32-bit code using these interfaces will work correctly
  on a modified kernel, with or without the uapi header changes.

- 32-bit code using SNDRV_TIMER_IOCTL_TREAD requires the
  updated header file for 64-bit time_t support

- 32-bit i386 user space with 64-bit time_t is broken for
  SNDRV_PCM_IOCTL_STATUS, SNDRV_RAWMIDI_IOCTL_STATUS and
  SNDRV_PCM_IOCTL_SYNC_PTR because of i386 alignment. This is also
  addressed by the updated uapi header.

- PCM mmap is currently supported on native x86 kernels
  (both 32-bit and 64-bit) but not for compat mode. This series breaks
  the 32-bit native mmap support for 32-bit time_t, but instead allows
  it for 64-bit time_t on both native and compat kernels. This seems to
  be the best trade-off, as mmap support is optional already, and most
  32-bit code runs in compat mode anyway.

- I've tried to avoid breaking compilation of 32-bit code
  as much as possible. Anything that does break however is likely code
  that is already broken on 64-bit time_t and needs source changes to
  fix them.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git
y2038-alsa-v8
[2] 
https://lore.kernel.org/lkml/cak8p3a2os66+iwqyf97qh05w2jp8rmwao8zmkohixqvhvyy...@mail.gmail.com/T/#m6519cb07cfda08adf1dedea6596bb98892b4d5dc

Signed-off-by: Arnd Bergmann 

Changes since v7: (Arnd):
 - Fix a typo found by Ben Hutchings

Changes since v6: (Arnd):
 - Add a patch to update the API versions
 - Hide a timespec reference in #ifndef __KERNEL__ to remove the
   last reference to time_t
 - Use a more readable way to do padding and describe it in the
   changelog
 - Rebase to linux-5.5-rc1, changing include/sound/soc-component.h
   and sound/drivers/aloop.c as needed.

Changes since v5 (Arnd):
 - Rebased to linux-5.4-rc4
 - Updated to completely remove timespec and time_t references from alsa
 - found and fixed a few bugs

Changes since v4 (Baolin):
 - Add patch 5 to change trigger_tstamp member of struct snd_pcm_runtime.
 - Add patch 8 to change internal timespec.
 - Add more explanation in commit message.
 - Use ktime_get_real_ts64() in patch 6.
 - Split common code out into a separate function in patch 6.
 - Fix tu->tread bug in patch 6 and remove #if __BITS_PER_LONG == 64 macro.

Changes since v3:
 - Move struct snd_pcm_status32 to pcm.h file.
 - Modify comments and commit message.
 - Add new patch2 ~ patch6.

Changes since v2:
 - Renamed all structures to make clear.
 - Remove CONFIG_X86_X32 macro and introduced new
compat_snd_pcm_status64_x86_32.

Changes since v1:
 - Add one macro for struct snd_pcm_status_32 which only active in
32bits kernel.
 - Convert pcm_compat.c to use struct snd_pcm_status_64.
 - Convert pcm_native.c to use struct snd_pcm_status_64.

----
Arnd Bergmann (3):
  ALSA: move snd_pcm_ioctl_sync_ptr_compat into pcm_native.c
  ALSA: add new 32-bit layout for snd_pcm_mmap_status/control
  ALSA: bump uapi version numbers

Baolin Wang (6):
  ALSA: Replace timespec with timespec64
  ALSA: Avoid using timespec for struct snd_timer_status
  ALSA: Avoid using timespec for struct snd_ctl_elem_value
  ALSA: Avoid using timespec for struct snd_pcm_status
  ALSA: Avoid using timespec for struct snd_rawmidi_status
  ALSA: Avoid using timespec for struct snd_timer_tread

 include/sound/pcm.h   |  74 +
 include/sound/soc-component.h |   4 +-
 include/sound/timer.h |   4 +-
 include/uapi/sound/asound.h   | 145
-
 sound/c

Re: [Y2038] [PATCH v7 0/8] Fix year 2038 issue for sound subsystem

2019-12-17 Thread Arnd Bergmann
On Tue, Dec 17, 2019 at 11:42 AM Takashi Iwai  wrote:
> On Wed, 11 Dec 2019 22:20:16 +0100,
> Arnd Bergmann wrote:

> >
> > I hope I addressed all review comments by now, so please pull this
> > for linux-5.6.
> >
> > A git branch with the same contents is available for testing at [1].
> >
> >  Arnd
>
> I see no issue other than the timer API patch Ben pointed.
>
> Could you resubmit that patch?  Or just submit the whole as v8, I
> don't mind either way.  Then we'll get this done for 5.6.

Can you take this as a pull request? That would be ideal for me,
as I can then use it as a parent for a shared branch with additional
cleanups on top (removing time_t etc) in linux-next. It also provides
a nice place to preserve the series cover letter.

I'm sending you the pull request now, and the last modified patch,
in case you prefer the patch over a git tag.

Thanks,

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 20/24] xfs: disallow broken ioctls without compat-32-bit-time

2019-12-17 Thread Arnd Bergmann
On Mon, Dec 16, 2019 at 5:52 PM Darrick J. Wong  wrote:
> On Mon, Dec 16, 2019 at 05:45:29PM +0100, Arnd Bergmann wrote:
> > On Fri, Dec 13, 2019 at 10:05 PM Darrick J. Wong  
> > wrote:
> > What is the timeline for that work now? I'm mainly interested in
> > getting the removal of 'time_t/timeval/timespec' and 'get_seconds()'
> > from the kernel done for v5.6, but it would be good to also have
> > this patch and the extended timestamps in the same version
> > just so we can claim that "all known y2038 issues" are addressed
> > in that release (I'm sure we will run into bugs we don't know yet).
>
> Personally, I think you should push this whenever it's ready.  Are you
> aiming to send all 24 patches as a treewide pull request directly to
> Linus, or would you rather the 2-3 xfs patches go through the xfs tree?

My plan is get as much of the remaining 60 patches into maintainer
trees for v5.6 and then send a pull request for whatever remains that
has not been picked up by anyone.

The 24 patches are the ones that didn't seem worth splitting into a
separate series, aside from these I also have v4l2, alsa and nfsd
pending, plus a final cleanup that removes the then-unused
interfaces.

So if you can pick up the xfs patches, that would help me.

> The y2038 format changes are going to take a while to push through
> review.  If somehow it all gets through review for 5.6 I can always
> apply both and fix the merge damage, but more likely y2038 timestamps is
> a  5.8 EXPERIMENTAL thing.
>
> Or later, given that Dave and I both have years worth of unreviewed
> patch backlog. :(

Ok, I see.

Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 21/24] xfs: quota: move to time64_t interfaces

2019-12-17 Thread Arnd Bergmann
On Mon, Dec 16, 2019 at 5:52 PM Arnd Bergmann  wrote:
> On Fri, Dec 13, 2019 at 10:17 PM Darrick J. Wong  
> wrote:
>>
>> Hmm, so one thing that I clean up on the way to bigtime is the total
>> lack of clamping here.  If (for example) it's September 2105 and
>> rtbtimelimit is set to 1 year, this will cause an integer overflow.  The
>> quota timer will be set to 1970 and expire immediately, rather than what
>> I'd consider the best effort of February 2106.

One more hing to note (I will add this to the changelog text) is that on
32-bit architectures, the limit here is y2038, while on 64-bit
architectures it's y2106:

int xfs_trans_dqresv(...)
{
   time_t  timer; /* signed 'long' */
   timer = be32_to_cpu(dqp->q_core.d_btimer);
   /* get_seconds() returns unsigned long */
  if ((timer != 0 && get_seconds() > timer))
return -EDQUOT;
}

> I don't think clamping would be good here, that just replaces
> one bug with another at the overflow time. If you would like to
> have something better before this gets extended, I could try to
> come up with a version that converts it to the nearest 64-bit
> timestamp, similar to the way that time_before32() in the kernel
> or the NTP protocol work.
>
> If you think it can get extended properly soon, I'd just leave the
> patch as it is today in order to remove the get_seconds()
> interface for v5.6.

I've tried this now, and but this feels wrong: it adds lots of complexity
for corner cases and is still fragile, e.g. when the time is wrong
during boot before ntp runs. See that patch below for reference.

I also see that quotatool on xfs always uses the old xfs quota
interface, so it already overflows on the user space side. Fixing
this properly seems to be a bigger effort than I was planning for
(on an unpatched 64-bit kernel):

$ sudo quotatool -b-u  -t 220month  /mnt/tmp -r
$ rm file ; fallocate -l 11M file
$ sudo quotatool -d /mnt/tmp -u arnd
1000 /mnt/tmp 11264 10240 20480 570239975 2 0 00
$ sudo quotatool -b-u  -t 222month  /mnt/tmp -r
$ rm file ; fallocate -l 11M file
$ sudo quotatool -d /mnt/tmp -u arnd
1000 /mnt/tmp 11264 10240 20480 18446744069990008316 2 0 00

   Arnd

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 9cfd3209f52b..6c9128bb607b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -98,6 +98,23 @@ xfs_qm_adjust_dqlimits(
xfs_dquot_set_prealloc_limits(dq);
 }

+static __be32 xfs_quota_timeout32(s64 limit)
+{
+   time64_t now = ktime_get_real_seconds();
+   u32 timeout;
+
+   /* avoid overflows in out-of-range limits */
+   if ((u64)limit > S32_MAX)
+   limit = S32_MAX;
+   timeout = now + limit;
+
+   /* avoid timeout of zero */
+   if (lower_32_bits(timeout) == 0)
+   return cpu_to_be32(1);
+
+   return cpu_to_be32(lower_32_bits(timeout));
+}
+
 /*
  * Check the limits and timers of a dquot and start or reset timers
  * if necessary.
@@ -137,7 +154,7 @@ xfs_qm_adjust_dqtimers(
(d->d_blk_hardlimit &&
 (be64_to_cpu(d->d_bcount) >
  be64_to_cpu(d->d_blk_hardlimit {
-   d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
+   d->d_btimer = xfs_quota_timeout32(
mp->m_quotainfo->qi_btimelimit);
} else {
d->d_bwarns = 0;
@@ -160,7 +177,7 @@ xfs_qm_adjust_dqtimers(
(d->d_ino_hardlimit &&
 (be64_to_cpu(d->d_icount) >
  be64_to_cpu(d->d_ino_hardlimit {
-   d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
+   d->d_itimer = xfs_quota_timeout32(
mp->m_quotainfo->qi_itimelimit);
} else {
d->d_iwarns = 0;
@@ -183,7 +200,7 @@ xfs_qm_adjust_dqtimers(
(d->d_rtb_hardlimit &&
 (be64_to_cpu(d->d_rtbcount) >
  be64_to_cpu(d->d_rtb_hardlimit {
-   d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
+   d->d_rtbtimer = xfs_quota_timeout32(
mp->m_quotainfo->qi_rtbtimelimit);
} else {
d->d_rtbwarns = 0;
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 1ea82764bf89..2087626b4bee 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -601,6 +601,14 @@ xfs_qm_scall_setqlim(
return error;
 }

+/* Assume timers are within +/- 68 years of current wall clock */
+static time64_t xfs_quota_time32_to_time64(time64_t now, __be32 timer)

Re: [Y2038] [PATCH v2 21/24] xfs: quota: move to time64_t interfaces

2019-12-16 Thread Arnd Bergmann
On Fri, Dec 13, 2019 at 10:17 PM Darrick J. Wong
 wrote:
>
> On Fri, Dec 13, 2019 at 09:53:49PM +0100, Arnd Bergmann wrote:
> > As a preparation for removing the 32-bit time_t type and
> > all associated interfaces, change xfs to use time64_t and
> > ktime_get_real_seconds() for the quota housekeeping.
> >
> > Signed-off-by: Arnd Bergmann 
>
> Looks mostly reasonable to me...
>
> The bigtime series refactors the triplicated timer handling and whatnot,
> but I don't think it would be difficult to rebase that series assuming
> this lands first (which it probably will, I expect a new incompat ondisk
> feature to take a /long/ time to get through review.)

Could you just merge my three patches into your tree then once
you are happy with all the changes?

> > @@ -183,7 +183,7 @@ xfs_qm_adjust_dqtimers(
> >   (d->d_rtb_hardlimit &&
> >(be64_to_cpu(d->d_rtbcount) >
> > be64_to_cpu(d->d_rtb_hardlimit {
> > - d->d_rtbtimer = cpu_to_be32(get_seconds() +
> > + d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
> >   mp->m_quotainfo->qi_rtbtimelimit);
>
> Hmm, so one thing that I clean up on the way to bigtime is the total
> lack of clamping here.  If (for example) it's September 2105 and
> rtbtimelimit is set to 1 year, this will cause an integer overflow.  The
> quota timer will be set to 1970 and expire immediately, rather than what
> I'd consider the best effort of February 2106.

I don't think clamping would be good here, that just replaces
one bug with another at the overflow time. If you would like to
have something better before this gets extended, I could try to
come up with a version that converts it to the nearest 64-bit
timestamp, similar to the way that time_before32() in the kernel
or the NTP protocol work.

If you think it can get extended properly soon, I'd just leave the
patch as it is today in order to remove the get_seconds()
interface for v5.6.

> (I'll grant you the current code also behaves like this...)
>
> Reviewed-by: Darrick J. Wong 

Thanks,

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 20/24] xfs: disallow broken ioctls without compat-32-bit-time

2019-12-16 Thread Arnd Bergmann
On Fri, Dec 13, 2019 at 10:05 PM Darrick J. Wong
 wrote:
>
> On Fri, Dec 13, 2019 at 09:53:48PM +0100, Arnd Bergmann wrote:
> > When building a kernel that disables support for 32-bit time_t
> > system calls, it also makes sense to disable the old xfs_bstat
> > ioctls completely, as they truncate the timestamps to 32-bit
> > values.
>
> Note that current xfs doesn't support > 32-bit timestamps at all, so for
> now the old bulkstat/swapext ioctls will never overflow.

Right, this patch originally came after my version of the 40-bit
timestamps that I dropped from the series now.

I've added "... once the extended times are supported." above now.

> Granted, I melded everyone's suggestions into a more fully formed
> 'bigtime' feature patchset that I'll dump out soon as part of my usual
> end of year carpetbombing of the mailing list, so we likely still need
> most of this patch anyway...

What is the timeline for that work now? I'm mainly interested in
getting the removal of 'time_t/timeval/timespec' and 'get_seconds()'
from the kernel done for v5.6, but it would be good to also have
this patch and the extended timestamps in the same version
just so we can claim that "all known y2038 issues" are addressed
in that release (I'm sure we will run into bugs we don't know yet).

> > @@ -617,6 +618,23 @@ xfs_fsinumbers_fmt(
> >   return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
> >  }
> >
> > +/* disallow y2038-unsafe ioctls with CONFIG_COMPAT_32BIT_TIME=n */
> > +static bool xfs_have_compat_bstat_time32(unsigned int cmd)
>
> The v5 bulkstat ioctls follow an entirely separate path through
> xfs_ioctl.c, so I think you don't need the @cmd parameter.

The check is there to not forbid XFS_IOC_FSINUMBERS at
the moment, since that is not affected.

> > @@ -1815,6 +1836,11 @@ xfs_ioc_swapext(
> >   struct fd   f, tmp;
> >   int error = 0;
> >
> > + if (xfs_have_compat_bstat_time32(XFS_IOC_SWAPEXT)) {
>
> if (!xfs_have...()) ?

Right, fixed now.

   Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


Re: [Y2038] [PATCH v2 19/24] xfs: rename compat_time_t to old_time32_t

2019-12-16 Thread Arnd Bergmann
On Fri, Dec 13, 2019 at 10:18 PM Darrick J. Wong
 wrote:
>
> On Fri, Dec 13, 2019 at 09:53:47PM +0100, Arnd Bergmann wrote:
> > The compat_time_t type has been removed everywhere else,
> > as most users rely on old_time32_t for both native and
> > compat mode handling of 32-bit time_t.
> >
> > Remove the last one in xfs.
> >
> > Signed-off-by: Arnd Bergmann 
>
> Looks fine to me, assuming that compat_time_t -> old_time32_t.

Yes, that's the idea. Christoph asked for the global change last year
as a cleanup,
but I left out xfs and a few others at the time when I was missing
other patches.

> Reviewed-by: Darrick J. Wong 

Thanks,

 Arnd
___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v6 7/8] media: v4l2-core: fix compat VIDIOC_DQEVENT for time64 ABI

2019-12-16 Thread Arnd Bergmann
The native code supports the variant of struct v4l2_event for 64-bit
time_t, so add the compat version as well.

Here, a new incompatibility arises: while almost all 32-bit architectures
now use the same layout as 64-bit architectures and the commands can
simply be passed through, on x86 the internal alignment of v4l2_event
is different because of the 64-bit member in v4l2_event_ctrl.

To handle all architectures, this now requires defining four different
versions of the structure to cover all possible combinations. The compat
handling for VIDIOC_DQEVENT32 and VIDIOC_DQEVENT32_TIME32 is now inside
of an #ifdef so it does not get used on architectures other than x86.

Signed-off-by: Arnd Bergmann 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 60 ++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 7ad6db8dd9f6..f8a4b0ddd47d 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1028,6 +1028,15 @@ static int put_v4l2_ext_controls32(struct file *file,
return 0;
 }
 
+#ifdef CONFIG_X86_64
+/*
+ * x86 is the only compat architecture with different struct alignment
+ * between 32-bit and 64-bit tasks.
+ *
+ * On all other architectures, v4l2_event32 and v4l2_event32_time32 are
+ * the same as v4l2_event and v4l2_event_time32, so we can use the native
+ * handlers, converting v4l2_event to v4l2_event_time32 if necessary.
+ */
 struct v4l2_event32 {
__u32   type;
union {
@@ -1036,7 +1045,23 @@ struct v4l2_event32 {
} u;
__u32   pending;
__u32   sequence;
-   struct compat_timespec  timestamp;
+   struct {
+   compat_s64  tv_sec;
+   compat_s64  tv_nsec;
+   } timestamp;
+   __u32   id;
+   __u32   reserved[8];
+};
+
+struct v4l2_event32_time32 {
+   __u32   type;
+   union {
+   compat_s64  value64;
+   __u8data[64];
+   } u;
+   __u32   pending;
+   __u32   sequence;
+   struct old_timespec32   timestamp;
__u32   id;
__u32   reserved[8];
 };
@@ -1057,6 +1082,23 @@ static int put_v4l2_event32(struct v4l2_event __user 
*p64,
return 0;
 }
 
+static int put_v4l2_event32_time32(struct v4l2_event_time32 __user *p64,
+  struct v4l2_event32_time32 __user *p32)
+{
+   if (!access_ok(p32, sizeof(*p32)) ||
+   assign_in_user(>type, >type) ||
+   copy_in_user(>u, >u, sizeof(p64->u)) ||
+   assign_in_user(>pending, >pending) ||
+   assign_in_user(>sequence, >sequence) ||
+   assign_in_user(>timestamp.tv_sec, >timestamp.tv_sec) ||
+   assign_in_user(>timestamp.tv_nsec, >timestamp.tv_nsec) ||
+   assign_in_user(>id, >id) ||
+   copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
+   return -EFAULT;
+   return 0;
+}
+#endif
+
 struct v4l2_edid32 {
__u32 pad;
__u32 start_block;
@@ -1121,6 +1163,7 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64,
 #define VIDIOC_S_EXT_CTRLS32_IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #defineVIDIOC_DQEVENT32_IOR ('V', 89, struct v4l2_event32)
+#defineVIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct 
v4l2_event32_time32)
 #define VIDIOC_CREATE_BUFS32   _IOWR('V', 92, struct v4l2_create_buffers32)
 #define VIDIOC_PREPARE_BUF32   _IOWR('V', 93, struct v4l2_buffer32)
 
@@ -1202,7 +1245,10 @@ static long do_video_ioctl(struct file *file, unsigned 
int cmd, unsigned long ar
case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
+#ifdef CONFIG_X86_64
case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
+   case VIDIOC_DQEVENT32_TIME32: ncmd = VIDIOC_DQEVENT_TIME32; break;
+#endif
case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
@@ -1336,10 +1382,16 @@ static long do_video_ioctl(struct file *file, unsigned 
int cmd, unsigned long ar
}
compatible_arg = 0;
break;
+#ifdef CONFIG_X86_64
case VIDIOC_DQEVENT32:
err = alloc_userspace(sizeof(struct v4l

[Y2038] [PATCH v6 8/8] media: v4l2-core: fix compat v4l2_buffer handling for time64 ABI

2019-12-16 Thread Arnd Bergmann
Add support for the four new variants of ioctl commands for 64-bit time_t
in v4l2_buffer.

The existing v4l2_buffer32 structure for the traditional format gets
changed to match the new v4l2_buffer format, and the old layout is
now called v4l2_buffer32_time32. Neither of these matches the native
64-bit architecture format of v4l2_buffer, so both require special
handling in compat code.

Duplicating the existing handlers for the new types is a safe conversion
for now, but unfortunately this may turn into a maintenance burden
later. A larger-scale rework of the compat code might be a better
alternative, but is out of scope of the y2038 work.

Note: x32 support for v4l2_buffer32 has always been broken and remains
so after this change, fixing it would have required even more duplication,
and apparently nobody has cared so far.

Signed-off-by: Arnd Bergmann 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 269 +-
 1 file changed, 268 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index f8a4b0ddd47d..381d29e45a49 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -468,13 +468,43 @@ struct v4l2_plane32 {
__u32   reserved[11];
 };
 
+/*
+ * This is correct for all architectures including i386, but not x32,
+ * which has different alignment requirements for timestamp
+ */
 struct v4l2_buffer32 {
__u32   index;
__u32   type;   /* enum v4l2_buf_type */
__u32   bytesused;
__u32   flags;
__u32   field;  /* enum v4l2_field */
-   struct compat_timeval   timestamp;
+   struct {
+   compat_s64  tv_sec;
+   compat_s64  tv_usec;
+   }   timestamp;
+   struct v4l2_timecodetimecode;
+   __u32   sequence;
+
+   /* memory location */
+   __u32   memory; /* enum v4l2_memory */
+   union {
+   __u32   offset;
+   compat_long_t   userptr;
+   compat_caddr_t  planes;
+   __s32   fd;
+   } m;
+   __u32   length;
+   __u32   reserved2;
+   __s32   request_fd;
+};
+
+struct v4l2_buffer32_time32 {
+   __u32   index;
+   __u32   type;   /* enum v4l2_buf_type */
+   __u32   bytesused;
+   __u32   flags;
+   __u32   field;  /* enum v4l2_field */
+   struct old_timeval32timestamp;
struct v4l2_timecodetimecode;
__u32   sequence;
 
@@ -581,6 +611,31 @@ static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user 
*p32, u32 *size)
return 0;
 }
 
+static int bufsize_v4l2_buffer_time32(struct v4l2_buffer32_time32 __user *p32, 
u32 *size)
+{
+   u32 type;
+   u32 length;
+
+   if (!access_ok(p32, sizeof(*p32)) ||
+   get_user(type, >type) ||
+   get_user(length, >length))
+   return -EFAULT;
+
+   if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+   if (length > VIDEO_MAX_PLANES)
+   return -EINVAL;
+
+   /*
+* We don't really care if userspace decides to kill itself
+* by passing a very big length value
+*/
+   *size = length * sizeof(struct v4l2_plane);
+   } else {
+   *size = 0;
+   }
+   return 0;
+}
+
 static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
 struct v4l2_buffer32 __user *p32,
 void __user *aux_buf, u32 aux_space)
@@ -681,6 +736,106 @@ static int get_v4l2_buffer32(struct v4l2_buffer __user 
*p64,
return 0;
 }
 
+static int get_v4l2_buffer32_time32(struct v4l2_buffer_time32 __user *p64,
+   struct v4l2_buffer32_time32 __user *p32,
+   void __user *aux_buf, u32 aux_space)
+{
+   u32 type;
+   u32 length;
+   s32 request_fd;
+   enum v4l2_memory memory;
+   struct v4l2_plane32 __user *uplane32;
+   struct v4l2_plane __user *uplane;
+   compat_caddr_t p;
+   int ret;
+
+   if (!access_ok(p32, sizeof(*p32)) ||
+   assign_in_user(>index, >index) ||
+   get_user(type, >type) ||
+   put_user(type, >type) ||
+   assign_in_user(>flags, >flags) ||
+   get_user(memory, >memory) ||
+   put_user(memory, >memory) ||
+   get_user(length, >length) ||
+   put_user(length, >length) ||
+   get_user(request_fd, >request_fd) ||
+   put_user(request_fd, >request_fd))
+   return -E

[Y2038] [PATCH v6 6/8] media: v4l2-core: fix v4l2_buffer handling for time64 ABI

2019-12-16 Thread Arnd Bergmann
The v4l2_buffer structure contains a 'struct timeval' member that is
defined by the user space C library, creating an ABI incompatibility
when that gets updated to a 64-bit time_t.

As in v4l2_event, handle this with a special case in video_put_user()
and video_get_user() to replace the memcpy there.

Since the structure also contains a pointer, there are now two
native versions (on 32-bit systems) as well as two compat versions
(on 64-bit systems), which unfortunately complicates the compat
handler quite a bit.

Duplicating the existing handlers for the new types is a safe
conversion for now, but unfortunately this may turn into a
maintenance burden later. A larger-scale rework of the
compat code might be a better alternative, but is out of scope
of the y2038 work.

Sparc64 needs a special case because of their special suseconds_t
definition.

Signed-off-by: Arnd Bergmann 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 74 ++--
 include/media/v4l2-ioctl.h   | 30 +++
 include/uapi/linux/videodev2.h   | 23 +
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index b066e27e99a2..667225712343 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -474,10 +474,10 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
const struct v4l2_plane *plane;
int i;
 
-   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request_fd=%d, 
flags=0x%08x, field=%s, sequence=%d, memory=%s",
-   p->timestamp.tv_sec / 3600,
-   (int)(p->timestamp.tv_sec / 60) % 60,
-   (int)(p->timestamp.tv_sec % 60),
+   pr_cont("%02d:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, 
flags=0x%08x, field=%s, sequence=%d, memory=%s",
+   (int)p->timestamp.tv_sec / 3600,
+   ((int)p->timestamp.tv_sec / 60) % 60,
+   ((int)p->timestamp.tv_sec % 60),
(long)p->timestamp.tv_usec,
p->index,
prt_names(p->type, v4l2_type_names), p->request_fd,
@@ -3029,6 +3029,14 @@ static unsigned int video_translate_cmd(unsigned int cmd)
 #ifdef CONFIG_COMPAT_32BIT_TIME
case VIDIOC_DQEVENT_TIME32:
return VIDIOC_DQEVENT;
+   case VIDIOC_QUERYBUF_TIME32:
+   return VIDIOC_QUERYBUF;
+   case VIDIOC_QBUF_TIME32:
+   return VIDIOC_QBUF;
+   case VIDIOC_DQBUF_TIME32:
+   return VIDIOC_DQBUF;
+   case VIDIOC_PREPARE_BUF_TIME32:
+   return VIDIOC_PREPARE_BUF;
 #endif
}
 
@@ -3047,6 +3055,39 @@ static int video_get_user(void __user *arg, void *parg, 
unsigned int cmd,
}
 
switch (cmd) {
+#ifdef CONFIG_COMPAT_32BIT_TIME
+   case VIDIOC_QUERYBUF_TIME32:
+   case VIDIOC_QBUF_TIME32:
+   case VIDIOC_DQBUF_TIME32:
+   case VIDIOC_PREPARE_BUF_TIME32: {
+   struct v4l2_buffer_time32 vb32;
+   struct v4l2_buffer *vb = parg;
+
+   if (copy_from_user(, arg, sizeof(vb32)))
+   return -EFAULT;
+
+   *vb = (struct v4l2_buffer) {
+   .index  = vb32.index,
+   .type   = vb32.type,
+   .bytesused  = vb32.bytesused,
+   .flags  = vb32.flags,
+   .field  = vb32.field,
+   .timestamp.tv_sec   = vb32.timestamp.tv_sec,
+   .timestamp.tv_usec  = vb32.timestamp.tv_usec,
+   .timecode   = vb32.timecode,
+   .sequence   = vb32.sequence,
+   .memory = vb32.memory,
+   .m.userptr  = vb32.m.userptr,
+   .length = vb32.length,
+   .request_fd = vb32.request_fd,
+   };
+
+   if (cmd == VIDIOC_QUERYBUF_TIME32)
+   vb->request_fd = 0;
+
+   break;
+   }
+#endif
default:
/*
 * In some cases, only a few fields are used as input,
@@ -3100,6 +3141,31 @@ static int video_put_user(void __user *arg, void *parg, 
unsigned int cmd)
return -EFAULT;
break;
}
+   case VIDIOC_QUERYBUF_TIME32:
+   case VIDIOC_QBUF_TIME32:
+   case VIDIOC_DQBUF_TIME32:
+   case VIDIOC_PREPARE_BUF_TIME32: {
+   struct v4l2_buffer *vb = parg;
+   struct v4l2_buffer_time32 vb32 = {
+   .index  = vb->index,
+   .type   = vb->type,
+   .bytesused  = vb->bytesused,
+

[Y2038] [PATCH v6 3/8] media: v4l2-core: compat: ignore native command codes

2019-12-16 Thread Arnd Bergmann
The do_video_ioctl() compat handler converts the compat command
codes into the native ones before processing further, but this
causes problems for 32-bit user applications that pass a command
code that matches a 64-bit native number, which will then be
handled the same way.

Specifically, this breaks VIDIOC_DQEVENT_TIME from user space
applications with 64-bit time_t, as the structure layout is
the same as the native 64-bit layout on many architectures
(x86 being the notable exception).

Change the handler to use the converted command code only for
passing into the native ioctl handler, not for deciding on the
conversion, in order to make the compat behavior match the
native behavior.

Actual support for the 64-bit time_t version of VIDIOC_DQEVENT_TIME
and other commands still needs to be added in a separate patch.

Cc: sta...@vger.kernel.org
Signed-off-by: Arnd Bergmann 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 148 +-
 1 file changed, 75 insertions(+), 73 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index e1eaf1135c7f..7ad6db8dd9f6 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1183,36 +1183,38 @@ static long do_video_ioctl(struct file *file, unsigned 
int cmd, unsigned long ar
u32 aux_space;
int compatible_arg = 1;
long err = 0;
+   unsigned int ncmd;
 
/*
 * 1. When struct size is different, converts the command.
 */
switch (cmd) {
-   case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
-   case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
-   case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
-   case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
-   case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
-   case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
-   case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
-   case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
-   case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
-   case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
-   case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break;
-   case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
-   case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
-   case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break;
-   case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
-   case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
-   case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
-   case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
-   case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
-   case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
-   case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
-   case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
-   case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
-   case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break;
-   case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break;
+   case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break;
+   case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break;
+   case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break;
+   case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break;
+   case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break;
+   case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break;
+   case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break;
+   case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break;
+   case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break;
+   case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break;
+   case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
+   case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
+   case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
+   case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
+   case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
+   case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
+   case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
+   case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break;
+   case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break;
+   case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break;
+   case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break;
+   case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break;
+   case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break;
+   case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break;
+   case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break;
+   default: ncmd = cmd; break;
}
 
/*
@@ -1221,11 +1223,11 @@ static long do_video_ioctl(struct file *file, unsigned 
int cmd, unsigned long ar
 * argument into it.
 */
switch (cmd) {
-   case VIDIOC_OVERLAY:
-   case VIDIOC_STREAMON:
-   case

[Y2038] [PATCH v6 5/8] media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI

2019-12-16 Thread Arnd Bergmann
The v4l2_event structure contains a 'struct timespec' member that is
defined by the user space C library, creating an ABI incompatibility
when that gets updated to a 64-bit time_t.

While passing a 32-bit time_t here would be sufficient for CLOCK_MONOTONIC
timestamps, simply redefining the structure to use the kernel's
__kernel_old_timespec would not work for any library that uses a copy
of the linux/videodev2.h header file rather than including the copy from
the latest kernel headers.

This means the kernel has to be changed to handle both versions of the
structure layout on a 32-bit architecture. The easiest way to do this
is during the copy from/to user space.

Signed-off-by: Arnd Bergmann 
---
 drivers/media/v4l2-core/v4l2-event.c  |  5 -
 drivers/media/v4l2-core/v4l2-ioctl.c  | 29 ++-
 drivers/media/v4l2-core/v4l2-subdev.c | 26 +++-
 include/media/v4l2-ioctl.h| 25 +++
 include/uapi/linux/videodev2.h|  4 
 5 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-event.c 
b/drivers/media/v4l2-core/v4l2-event.c
index 9d673d113d7a..290c6b213179 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -27,6 +27,7 @@ static unsigned sev_pos(const struct v4l2_subscribed_event 
*sev, unsigned idx)
 static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
 {
struct v4l2_kevent *kev;
+   struct timespec64 ts;
unsigned long flags;
 
spin_lock_irqsave(>vdev->fh_lock, flags);
@@ -44,7 +45,9 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct 
v4l2_event *event)
 
kev->event.pending = fh->navailable;
*event = kev->event;
-   event->timestamp = ns_to_timespec(kev->ts);
+   ts = ns_to_timespec64(kev->ts);
+   event->timestamp.tv_sec = ts.tv_sec;
+   event->timestamp.tv_nsec = ts.tv_nsec;
kev->sev->first = sev_pos(kev->sev, 1);
kev->sev->in_use--;
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index fe4678965e1b..b066e27e99a2 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -821,7 +821,7 @@ static void v4l_print_event(const void *arg, bool 
write_only)
const struct v4l2_event *p = arg;
const struct v4l2_event_ctrl *c;
 
-   pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, 
timestamp=%lu.%9.9lu\n",
+   pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, 
timestamp=%llu.%9.9llu\n",
p->type, p->pending, p->sequence, p->id,
p->timestamp.tv_sec, p->timestamp.tv_nsec);
switch (p->type) {
@@ -3025,6 +3025,13 @@ static int check_array_args(unsigned int cmd, void 
*parg, size_t *array_size,
 
 static unsigned int video_translate_cmd(unsigned int cmd)
 {
+   switch (cmd) {
+#ifdef CONFIG_COMPAT_32BIT_TIME
+   case VIDIOC_DQEVENT_TIME32:
+   return VIDIOC_DQEVENT;
+#endif
+   }
+
return cmd;
 }
 
@@ -3074,6 +3081,26 @@ static int video_put_user(void __user *arg, void *parg, 
unsigned int cmd)
return 0;
 
switch (cmd) {
+#ifdef CONFIG_COMPAT_32BIT_TIME
+   case VIDIOC_DQEVENT_TIME32: {
+   struct v4l2_event *ev = parg;
+   struct v4l2_event_time32 ev32 = {
+   .type   = ev->type,
+   .pending= ev->pending,
+   .sequence   = ev->sequence,
+   .timestamp.tv_sec  = ev->timestamp.tv_sec,
+   .timestamp.tv_nsec = ev->timestamp.tv_nsec,
+   .id = ev->id,
+   };
+
+   memcpy(, >u, sizeof(ev->u));
+   memcpy(, >reserved, sizeof(ev->reserved));
+
+   if (copy_to_user(arg, , sizeof(ev32)))
+   return -EFAULT;
+   break;
+   }
+#endif
default:
/*  Copy results into user buffer  */
if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
b/drivers/media/v4l2-core/v4l2-subdev.c
index 9e987c0f840e..de926e311348 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -331,8 +331,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
struct v4l2_fh *vfh = file->private_data;
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
-   int rval;
 #endif
+   int rval;
 
switch (cmd) {
case VIDIOC_QUERYCTRL:
@@ -392,6 +392,30 @@ static long subdev_do_ioctl(struct file *file, unsigned 
int cmd, void *arg)
 
return v

[Y2038] [PATCH v6 2/8] media: v4l2: abstract timeval handling in v4l2_buffer

2019-12-16 Thread Arnd Bergmann
As a preparation for adding 64-bit time_t support in the uapi,
change the drivers to no longer care about the format of the
timestamp field in struct v4l2_buffer.

The v4l2_timeval_to_ns() function is no longer needed in the
kernel after this, but there is userspace code relying on
it to be part of the uapi header.

Signed-off-by: Arnd Bergmann 
---
 .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++--
 drivers/media/pci/meye/meye.c |  4 ++--
 drivers/media/usb/cpia2/cpia2_v4l.c   |  4 ++--
 drivers/media/usb/stkwebcam/stk-webcam.c  |  2 +-
 drivers/media/usb/usbvision/usbvision-video.c |  4 ++--
 drivers/media/v4l2-core/videobuf-core.c   |  5 +++--
 include/media/v4l2-common.h   | 21 +++
 include/trace/events/v4l2.h   |  2 +-
 include/uapi/linux/videodev2.h|  2 ++
 9 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index e652f4318284..eb5d5db96552 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const 
void *pb)
 * and the timecode field and flag if needed.
 */
if (q->copy_timestamp)
-   vb->timestamp = v4l2_timeval_to_ns(>timestamp);
+   vb->timestamp = v4l2_buffer_get_timestamp(b);
vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
if (b->flags & V4L2_BUF_FLAG_TIMECODE)
vbuf->timecode = b->timecode;
@@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
 
b->flags = vbuf->flags;
b->field = vbuf->field;
-   b->timestamp = ns_to_timeval(vb->timestamp);
+   v4l2_buffer_set_timestamp(b, vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
b->reserved2 = 0;
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index 0e61c81356ef..3a4c29bc0ba5 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, 
struct v4l2_buffer *buf)
buf->flags |= V4L2_BUF_FLAG_DONE;
 
buf->field = V4L2_FIELD_NONE;
-   buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts);
+   v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts);
buf->sequence = meye.grab_buffer[index].sequence;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = index * gbufsize;
@@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, 
struct v4l2_buffer *buf)
buf->bytesused = meye.grab_buffer[reqnr].size;
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
buf->field = V4L2_FIELD_NONE;
-   buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts);
+   v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts);
buf->sequence = meye.grab_buffer[reqnr].sequence;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = reqnr * gbufsize;
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 626264a56517..9d3d05125d7b 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -800,7 +800,7 @@ static int cpia2_querybuf(struct file *file, void *fh, 
struct v4l2_buffer *buf)
break;
case FRAME_READY:
buf->bytesused = cam->buffers[buf->index].length;
-   buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);
+   v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
buf->sequence = cam->buffers[buf->index].seq;
buf->flags = V4L2_BUF_FLAG_DONE;
break;
@@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
| V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
buf->field = V4L2_FIELD_NONE;
-   buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);
+   v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
buf->sequence = cam->buffers[buf->index].seq;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c 
b/drivers/media/usb/stkwebcam/stk-webcam.c
index 21f90a887485..b22501f76b78 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -1125,7 +112

[Y2038] [PATCH v6 1/8] media: documentation: fix video_event description

2019-12-16 Thread Arnd Bergmann
The type for the timestamp in video_event was changed to
'long' a long time ago, change the documentation to match.

Signed-off-by: Arnd Bergmann 
---
 Documentation/media/uapi/dvb/video-get-event.rst | 2 +-
 Documentation/media/uapi/dvb/video_types.rst | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/media/uapi/dvb/video-get-event.rst 
b/Documentation/media/uapi/dvb/video-get-event.rst
index def6c40db601..7f03fbe3d3b0 100644
--- a/Documentation/media/uapi/dvb/video-get-event.rst
+++ b/Documentation/media/uapi/dvb/video-get-event.rst
@@ -81,7 +81,7 @@ for this ioctl call.
#define VIDEO_EVENT_FRAME_RATE_CHANGED  2
#define VIDEO_EVENT_DECODER_STOPPED 3
#define VIDEO_EVENT_VSYNC   4
-   __kernel_time_t timestamp;
+   long timestamp;
union {
video_size_t size;
unsigned int frame_rate;/* in frames per 
1000sec */
diff --git a/Documentation/media/uapi/dvb/video_types.rst 
b/Documentation/media/uapi/dvb/video_types.rst
index 479942ce6fb8..2697400ccf62 100644
--- a/Documentation/media/uapi/dvb/video_types.rst
+++ b/Documentation/media/uapi/dvb/video_types.rst
@@ -170,7 +170,7 @@ VIDEO_GET_EVENT call.
 #define VIDEO_EVENT_FRAME_RATE_CHANGED  2
 #define VIDEO_EVENT_DECODER_STOPPED 3
 #define VIDEO_EVENT_VSYNC   4
-   __kernel_time_t timestamp;
+   long timestamp;
union {
video_size_t size;
unsigned int frame_rate;/* in frames per 1000sec */
-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


[Y2038] [PATCH v6 0/8] y2038 safety in v4l2

2019-12-16 Thread Arnd Bergmann
I'm in the process of finishing up the last bits on y2038-unsafe
code in the kernel, this series is for v4l2, which has no problem
with overflow, but has multiple ioctls that break with user space
built against a new 32-bit libc.

I posted similar patches as part of a series back in 2015, the
new version was rewritten from scratch and I double-checked with
the old version to make sure I did not miss anything I had already
taken care of before.

Hans Verkuil worked on a different patch set in 2017, but this
also did not get to the point of being merged.

My new version contains compat-ioctl support, which the old one
did not and should be complete, but given its size likely contains
bugs. I did randconfig build tests, but no runtime test, so
careful review as well as testing would be much appreciated.

With this version, the newly added code takes care of the existing
ABI, while the existing code got moved to the 64-bit time_t
interface and is used internally. This means that testing with
existing binaries should exercise most of the modifications
and if that works and doesn't get shot down in review, we can
probably live without testing the new ABI explicitly.

I'm not entirely happy with the compat-ioctl implementation that
adds quite a bit of code duplication, but I hope this is
acceptable anyway, as a better implementation would likely
require a larger refactoring of the compat-ioctl file, while
my approach simply adds support for the additional data structure
variants.

I uploaded git branch on top of the v4l2/dvb branch to [2].

  Arnd

Changes since v5:

- Fix all bugs that Hans found during testing
- Add a comment about x32 still being broken

Changes since v4:

- Move non-public contents out of uapi header
- split out __kernel_v4l2_timeval into separate struct
- use compound initializers for v4l2_event_time32 and
  v4l2_buffer_time32 conversion
- add comment for v4l2_buffer_get_timestamp()

Changes since v3:

- This is a minor update compared to version 3 of this series,
  with bugfixes for small mistakes that I found or that were
  reported by automated build bots.


[1] https://lwn.net/Articles/657754/
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-v4l2-v6


Arnd Bergmann (8):
  media: documentation: fix video_event description
  media: v4l2: abstract timeval handling in v4l2_buffer
  media: v4l2-core: compat: ignore native command codes
  media: v4l2-core: split out data copy from video_usercopy
  media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI
  media: v4l2-core: fix v4l2_buffer handling for time64 ABI
  media: v4l2-core: fix compat VIDIOC_DQEVENT for time64 ABI
  media: v4l2-core: fix compat v4l2_buffer handling for time64 ABI

 .../media/uapi/dvb/video-get-event.rst|   2 +-
 Documentation/media/uapi/dvb/video_types.rst  |   2 +-
 .../media/common/videobuf2/videobuf2-v4l2.c   |   4 +-
 drivers/media/pci/meye/meye.c |   4 +-
 drivers/media/usb/cpia2/cpia2_v4l.c   |   4 +-
 drivers/media/usb/stkwebcam/stk-webcam.c  |   2 +-
 drivers/media/usb/usbvision/usbvision-video.c |   4 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 477 +++---
 drivers/media/v4l2-core/v4l2-event.c  |   5 +-
 drivers/media/v4l2-core/v4l2-ioctl.c  | 211 ++--
 drivers/media/v4l2-core/v4l2-subdev.c |  26 +-
 drivers/media/v4l2-core/videobuf-core.c   |   5 +-
 include/media/v4l2-common.h   |  21 +
 include/media/v4l2-ioctl.h|  55 ++
 include/trace/events/v4l2.h   |   2 +-
 include/uapi/linux/videodev2.h|  29 ++
 16 files changed, 718 insertions(+), 135 deletions(-)

-- 
2.20.0

___
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038


  1   2   3   4   5   6   7   8   9   10   >