public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
       [not found] <CAK8P3a0bmE03wJ_iELrAMyFvamwd_r5aLsFBH=6=5YaueO=-kg@mail.gmail.com>
@ 2022-05-31  8:33 ` Arnd Bergmann
  2022-05-31  9:02   ` Arnaud Panaïotis
  2022-05-31 10:54   ` Adhemerval Zanella
  0 siblings, 2 replies; 6+ messages in thread
From: Arnd Bergmann @ 2022-05-31  8:33 UTC (permalink / raw)
  To: Arnaud Panaïotis; +Cc: linux-kernel, y2038, libc-alpha

(cc correct libc-alpha list, sorry for the typo)

On Tue, May 31, 2022 at 10:24 AM Arnd Bergmann <arnd@kernel.org> 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, &st), 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, &st_t64, flags)
>          ?: __cp_stat64_t64_stat64 (&st_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.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
  2022-05-31  8:33 ` PROBLEM: with daemon.c after y2038 on 32-bits Kernel Arnd Bergmann
@ 2022-05-31  9:02   ` Arnaud Panaïotis
  2022-05-31 10:54   ` Adhemerval Zanella
  1 sibling, 0 replies; 6+ messages in thread
From: Arnaud Panaïotis @ 2022-05-31  9:02 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-kernel, y2038, libc-alpha

Hello

On 31/05/2022 10:33, Arnd Bergmann wrote:
> (cc correct libc-alpha list, sorry for the typo)
>
> On Tue, May 31, 2022 at 10:24 AM Arnd Bergmann<arnd@kernel.org>  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?

I'm using Buildroot, I added it to TARGET_CPPFLAGS (also used by
TARGET_CLAGS) and HOST_CPPFLAGS (used by HOST_CFLAGS) in
buildroot/package/Makefile.in

Then all packages are built with the option (unless the package filter
it out, I had to create patches for few of them).

Extracts of logs while rebuild openssh:

/home/arnaud/devenv/branches/kernel510/output/host/bin/i686-buildroot-linux-gnu-gcc
  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64  -Os -g0
-D_FORTIFY_SOURCE=1 -pipe -Wno-error=format-truncation -Wall -Wextra
-Wpointer-arith
  -Wuninitialized -Wsign-compare -Wformat-security
-Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter
-Wno-unused-result -Wimplicit-fallthrough -fno-strict-aliasing -ftrapv
-fno-builtin-memset -fstack-protector-strong   -fPIC -I. -I.. -I. -I./..
  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
-D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -DHAVE_CONFIG_H -c
daemon.c

/home/arnaud/devenv/branches/kernel510/output/host/bin/i686-buildroot-linux-gnu-gcc
  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64  -Os -g0
-D_FORTIFY_SOURCE=1 -pipe -Wno-error=format-truncation -Wall -Wextra
-Wpointer-arith
  -Wuninitialized -Wsign-compare -Wformat-security
-Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter
-Wno-unused-result -Wimplicit-fallthrough -fno-strict-aliasing -ftrapv
-fno-builtin-memset -fstack-protector-strong -fPIE   -I. -I.
-D_LARGEFILE_SOURCE
  -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -D_XOPEN_SOURCE=600
-D_BSD_SOURCE -D_DEFAULT_SOURCE -DSSHDIR=\"/etc/ssh\"
-D_PATH_SSH_PROGRAM=\"/usr/bin/ssh\"
-D_PATH_SSH_ASKPASS_DEFAULT=\"/usr/libexec/ssh-askpass\"
-D_PATH_SFTP_SERVER=\"/usr/libexec/sftp-server\"
  -D_PATH_SSH_KEY_SIGN=\"/usr/libexec/ssh-keysign\"
-D_PATH_SSH_PKCS11_HELPER=\"/usr/libexec/ssh-pkcs11-helper\"
-D_PATH_SSH_SK_HELPER=\"/usr/libexec/ssh-sk-helper\"
-D_PATH_SSH_PIDDIR=\"/var/run\"
-D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c
  sshd.c -o sshd.o

>>
>>> 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, &st), 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, &st_t64, flags)
>>           ?: __cp_stat64_t64_stat64 (&st_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?
I'd tried previously to build the entire distro with musl without
success, not sure I can do it only for openssh.
>>
>>         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.
--

*Arnaud PANAÏOTIS* | Lead Developer Freelance
+33 6 34 82 12 62 | arnaud.panaiotis@gmx.fr <mailto:Arnaud Panaïotis
<arnaud.panaiotis@gmx.fr>>

18 place Jean Moulin - 38000 Grenoble
APsudo - www.panaiotis.fr <https://www.panaiotis.fr>

--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
  2022-05-31  8:33 ` PROBLEM: with daemon.c after y2038 on 32-bits Kernel Arnd Bergmann
  2022-05-31  9:02   ` Arnaud Panaïotis
@ 2022-05-31 10:54   ` Adhemerval Zanella
  2022-05-31 12:16     ` Arnaud Panaïotis
  1 sibling, 1 reply; 6+ messages in thread
From: Adhemerval Zanella @ 2022-05-31 10:54 UTC (permalink / raw)
  To: Arnd Bergmann, Arnaud Panaïotis; +Cc: y2038, libc-alpha, linux-kernel



On 31/05/2022 05:33, Arnd Bergmann via Libc-alpha wrote:
> (cc correct libc-alpha list, sorry for the typo)
> 
> On Tue, May 31, 2022 at 10:24 AM Arnd Bergmann <arnd@kernel.org> 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, &st), 0)
>>                         == 0)) {
>> ...
>>                              } else {
>>                         __close_nocancel_nostatus (fd);
>>                         return -1;
>>                 }
>>      return (0);
>> }

Thanks for catching it, I have opened a bug report for it [1] and I will fix
and backport to 2.34 and 2.35.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=29203

>>
>> __fstatat64 (int fd, const char *file, struct stat64 *buf, int flags)
>> {
>>   struct __stat64_t64 st_t64;
>>   return __fstatat64_time64 (fd, file, &st_t64, flags)
>>          ?: __cp_stat64_t64_stat64 (&st_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.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
  2022-05-31 10:54   ` Adhemerval Zanella
@ 2022-05-31 12:16     ` Arnaud Panaïotis
  2022-05-31 13:02       ` Szabolcs Nagy
  0 siblings, 1 reply; 6+ messages in thread
From: Arnaud Panaïotis @ 2022-05-31 12:16 UTC (permalink / raw)
  To: Adhemerval Zanella, Arnd Bergmann; +Cc: y2038, libc-alpha, linux-kernel

Hello,

On 31/05/2022 12:54, Adhemerval Zanella wrote:
>
> On 31/05/2022 05:33, Arnd Bergmann via Libc-alpha wrote:
>> (cc correct libc-alpha list, sorry for the typo)
>>
>> On Tue, May 31, 2022 at 10:24 AM Arnd Bergmann <arnd@kernel.org> 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?

I made a patch for the whole Builroot, this way all packages are built
with it (unless it is filter-out, I had to make few patches).

Option is present in build log for daemon.c and sshd.c

>>>
>>>> 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, &st), 0)
>>>                          == 0)) {
>>> ...
>>>                               } else {
>>>                          __close_nocancel_nostatus (fd);
>>>                          return -1;
>>>                  }
>>>       return (0);
>>> }
> Thanks for catching it, I have opened a bug report for it [1] and I will fix
> and backport to 2.34 and 2.35.
>
> [1] https://sourceware.org/bugzilla/show_bug.cgi?id=29203
Thanks, I'll watch this.
>
>>> __fstatat64 (int fd, const char *file, struct stat64 *buf, int flags)
>>> {
>>>    struct __stat64_t64 st_t64;
>>>    return __fstatat64_time64 (fd, file, &st_t64, flags)
>>>           ?: __cp_stat64_t64_stat64 (&st_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?

Musl did not worked previously for me, not sure for openssh only within
Buildroot.

I'll test the patch from ticket 29203, probably the easiest solution for me.

>>>
>>>         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.
--

*Arnaud PANAÏOTIS* | Lead Developer Freelance
+33 6 34 82 12 62 | arnaud.panaiotis@gmx.fr <mailto:Arnaud Panaïotis
<arnaud.panaiotis@gmx.fr>>

18 place Jean Moulin - 38000 Grenoble
APsudo - www.panaiotis.fr <https://www.panaiotis.fr>

--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
  2022-05-31 12:16     ` Arnaud Panaïotis
@ 2022-05-31 13:02       ` Szabolcs Nagy
  2022-05-31 13:24         ` Arnaud Panaïotis
  0 siblings, 1 reply; 6+ messages in thread
From: Szabolcs Nagy @ 2022-05-31 13:02 UTC (permalink / raw)
  To: Arnaud Panaïotis
  Cc: Adhemerval Zanella, Arnd Bergmann, y2038, libc-alpha, linux-kernel

The 05/31/2022 14:16, Arnaud Panaïotis via Libc-alpha wrote:
> > > > 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?
> 
> Musl did not worked previously for me, not sure for openssh only within
> Buildroot.

did you have a specific issue with musl?

it is supposed to work with buildroot and
has 64bit time_t support out of the box.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PROBLEM: with daemon.c after y2038 on 32-bits Kernel
  2022-05-31 13:02       ` Szabolcs Nagy
@ 2022-05-31 13:24         ` Arnaud Panaïotis
  0 siblings, 0 replies; 6+ messages in thread
From: Arnaud Panaïotis @ 2022-05-31 13:24 UTC (permalink / raw)
  To: Szabolcs Nagy
  Cc: Adhemerval Zanella, Arnd Bergmann, y2038, libc-alpha, linux-kernel


On 31/05/2022 15:02, Szabolcs Nagy wrote:
> The 05/31/2022 14:16, Arnaud Panaïotis via Libc-alpha wrote:
>>>>> 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?
>> Musl did not worked previously for me, not sure for openssh only within
>> Buildroot.
> did you have a specific issue with musl?
>
> it is supposed to work with buildroot and
> has 64bit time_t support out of the box.

Not really, I'm working on an existing project that was developed before
with Glibc. If I remember correctly some packages used by the project
did not build with musl (even with the previous version of Kernel).

The purpose of my mission was to analyze how to pass y2038 on embedded
devices (2 Linux and 1 Windows), now is to build the solution.

Upgrading Glibc and Buildroot were easier than switching to musl due
what was done before. I probably would have to change many elements
(packages, init scripts...) if I'd switched to musl.

Now both y2038 Linux works with glibc, this subject is the third I
raised (mysqld solved by a patch I made, cp binutils with issue from
fchmodat (bug 29097)).


--
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-31 13:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAK8P3a0bmE03wJ_iELrAMyFvamwd_r5aLsFBH=6=5YaueO=-kg@mail.gmail.com>
2022-05-31  8:33 ` PROBLEM: with daemon.c after y2038 on 32-bits Kernel Arnd Bergmann
2022-05-31  9:02   ` Arnaud Panaïotis
2022-05-31 10:54   ` Adhemerval Zanella
2022-05-31 12:16     ` Arnaud Panaïotis
2022-05-31 13:02       ` Szabolcs Nagy
2022-05-31 13:24         ` Arnaud Panaïotis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).