qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [0/4] Assorted bugfixes
@ 2012-01-11  5:44 David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size David Gibson
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: David Gibson @ 2012-01-11  5:44 UTC (permalink / raw)
  To: anthony; +Cc: agraf, qemu-devel

Hi Anthony,

Here are several simple non-target-specific bugfixes for qemu.  Please apply.

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

* [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size
  2012-01-11  5:44 [Qemu-devel] [0/4] Assorted bugfixes David Gibson
@ 2012-01-11  5:44 ` David Gibson
  2012-01-11  6:19   ` Stefan Weil
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 2/4] Fix dirty logging with 32-bit qemu & 64-bit guests David Gibson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: David Gibson @ 2012-01-11  5:44 UTC (permalink / raw)
  To: anthony; +Cc: agraf, qemu-devel

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

load_image_targphys() gets passed a max size for the file, but
doesn't enforce it at all. Add a check and return -1 (error) if
the file is too big, without loading it.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/loader.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/loader.c b/hw/loader.c
index 446b628..7ad9e22 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -108,6 +108,8 @@ int load_image_targphys(const char *filename,
     int size;
 
     size = get_image_size(filename);
+    if (size > max_sz)
+	return -1;
     if (size > 0)
         rom_add_file_fixed(filename, addr, -1);
     return size;
-- 
1.7.7.3

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

* [Qemu-devel] [PATCH 2/4] Fix dirty logging with 32-bit qemu & 64-bit guests
  2012-01-11  5:44 [Qemu-devel] [0/4] Assorted bugfixes David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size David Gibson
@ 2012-01-11  5:44 ` David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 4/4] Update gitignore file David Gibson
  3 siblings, 0 replies; 10+ messages in thread
From: David Gibson @ 2012-01-11  5:44 UTC (permalink / raw)
  To: anthony; +Cc: agraf, qemu-devel

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

The kvm_get_dirty_pages_log_range() function uses two address
variables to step through the monitored memory region to update the
dirty log.  However, these variables have type unsigned long, which
can overflow if running a 64-bit guest with a 32-bit qemu binary.

This patch changes these to target_phys_addr_t which will have the
correct size.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 kvm-all.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 3174f42..363c697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -344,7 +344,8 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
                                          unsigned long *bitmap)
 {
     unsigned int i, j;
-    unsigned long page_number, addr, addr1, c;
+    unsigned long page_number, c;
+    target_phys_addr_t addr, addr1;
     unsigned int len = ((section->size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
 
     /*
-- 
1.7.7.3

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

* [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work
  2012-01-11  5:44 [Qemu-devel] [0/4] Assorted bugfixes David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size David Gibson
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 2/4] Fix dirty logging with 32-bit qemu & 64-bit guests David Gibson
@ 2012-01-11  5:44 ` David Gibson
  2012-01-11  6:25   ` Stefan Weil
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 4/4] Update gitignore file David Gibson
  3 siblings, 1 reply; 10+ messages in thread
From: David Gibson @ 2012-01-11  5:44 UTC (permalink / raw)
  To: anthony; +Cc: agraf, qemu-devel

The pci_host_config_{read,write}_common() functions perform PCI config
accesses.  They take a limit parameter which they appear to be supposed
to bounds check against, however the bounds checking logic, such as it is,
is completely broken.

Currently, it takes the minimum of the supplied length and the remaining
space in the region and passes that as the length to the underlying
config_{read,write} function pointer.  This means that accesses which
partially overrun the region will be silently truncated - which makes
little sense.  Accesses which entirely overrun the region will *not*
be blocked (an exploitable bug), because in that case (limit - addr) will
be negative and so the unsigned MIN will always return len instead.  Even
if signed arithmetic was used, the config_{read,write} callback wouldn't
know what to do with a negative len parameter.

This patch handles things more sanely by simply ignoring writes which
overrun, and returning -1 for reads, which is the usual hardware convention
for reads to unpopulated IO regions.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/pci_host.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/pci_host.c b/hw/pci_host.c
index 44c6c20..16b3ac3 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -51,14 +51,20 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
                                   uint32_t limit, uint32_t val, uint32_t len)
 {
     assert(len <= 4);
-    pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
+    if ((addr + len) <= limit) {
+        pci_dev->config_write(pci_dev, addr, val, len);
+    }
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
                                      uint32_t limit, uint32_t len)
 {
     assert(len <= 4);
-    return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+    if ((addr + len) <= limit) {
+        return pci_dev->config_read(pci_dev, addr, len);
+    } else {
+        return ~0x0;
+    }
 }
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
-- 
1.7.7.3

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

* [Qemu-devel] [PATCH 4/4] Update gitignore file
  2012-01-11  5:44 [Qemu-devel] [0/4] Assorted bugfixes David Gibson
                   ` (2 preceding siblings ...)
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work David Gibson
@ 2012-01-11  5:44 ` David Gibson
  3 siblings, 0 replies; 10+ messages in thread
From: David Gibson @ 2012-01-11  5:44 UTC (permalink / raw)
  To: anthony; +Cc: agraf, qemu-devel

This patch adds several auto-generated files to .gitignore which were
previously missing.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 .gitignore |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 406f75f..f5aab2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,10 @@ qemu-ga
 qemu-monitor.texi
 QMP/qmp-commands.txt
 test-coroutine
+test-qmp-input-visitor
+test-qmp-output-visitor
+fsdev/virtfs-proxy-helper.1
+fsdev/virtfs-proxy-helper.pod
 .gdbinit
 *.a
 *.aux
-- 
1.7.7.3

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

* Re: [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size David Gibson
@ 2012-01-11  6:19   ` Stefan Weil
  2012-01-12  3:26     ` David Gibson
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Weil @ 2012-01-11  6:19 UTC (permalink / raw)
  To: David Gibson; +Cc: agraf, qemu-devel

Am 11.01.2012 06:44, schrieb David Gibson:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>
> load_image_targphys() gets passed a max size for the file, but
> doesn't enforce it at all. Add a check and return -1 (error) if
> the file is too big, without loading it.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> hw/loader.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/hw/loader.c b/hw/loader.c
> index 446b628..7ad9e22 100644
> --- a/hw/loader.c
> +++ b/hw/loader.c
> @@ -108,6 +108,8 @@ int load_image_targphys(const char *filename,
> int size;
>
> size = get_image_size(filename);
> + if (size > max_sz)
> + return -1;
> if (size > 0)
> rom_add_file_fixed(filename, addr, -1);
> return size;

Even if this file is full of block statements without braces,
we should not add more of them. See CODING_STYLE and
scripts/checkpatch.pl.

There remains an additional problem:
Using 'int' for the size of files was sufficient 10 years ago,
but it is that no longer. get_image_size() silently reduced the
return value from lseek() to an 'int' value. So even with your
patch, very large files will be loaded (partially)!

Regards,
Stefan Weil

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

* Re: [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work
  2012-01-11  5:44 ` [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work David Gibson
@ 2012-01-11  6:25   ` Stefan Weil
  2012-01-12  3:27     ` David Gibson
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Weil @ 2012-01-11  6:25 UTC (permalink / raw)
  To: David Gibson; +Cc: agraf, qemu-devel

Am 11.01.2012 06:44, schrieb David Gibson:
> The pci_host_config_{read,write}_common() functions perform PCI config
> accesses. They take a limit parameter which they appear to be supposed
> to bounds check against, however the bounds checking logic, such as it is,
> is completely broken.
>
> Currently, it takes the minimum of the supplied length and the remaining
> space in the region and passes that as the length to the underlying
> config_{read,write} function pointer. This means that accesses which
> partially overrun the region will be silently truncated - which makes
> little sense. Accesses which entirely overrun the region will *not*
> be blocked (an exploitable bug), because in that case (limit - addr) will
> be negative and so the unsigned MIN will always return len instead. Even
> if signed arithmetic was used, the config_{read,write} callback wouldn't
> know what to do with a negative len parameter.
>
> This patch handles things more sanely by simply ignoring writes which
> overrun, and returning -1 for reads, which is the usual hardware 
> convention
> for reads to unpopulated IO regions.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> hw/pci_host.c | 10 ++++++++--
> 1 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/hw/pci_host.c b/hw/pci_host.c
> index 44c6c20..16b3ac3 100644
> --- a/hw/pci_host.c
> +++ b/hw/pci_host.c
> @@ -51,14 +51,20 @@ void pci_host_config_write_common(PCIDevice 
> *pci_dev, uint32_t addr,
> uint32_t limit, uint32_t val, uint32_t len)
> {
> assert(len <= 4);
> - pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
> + if ((addr + len) <= limit) {
> + pci_dev->config_write(pci_dev, addr, val, len);
> + }
> }
>
> uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
> uint32_t limit, uint32_t len)
> {
> assert(len <= 4);
> - return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
> + if ((addr + len) <= limit) {
> + return pci_dev->config_read(pci_dev, addr, len);
> + } else {
> + return ~0x0;
> + }
> }
>
> void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)

Some people use QEMU to detect this kind of errors in an emulated
systems. Therefore an additional debug output would be good here.

As long as there is no QEMU standard for reporting this kind of errors,
a PCI_DPRINTF statement might be best.

Regards,
Stefan Weil

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

* Re: [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size
  2012-01-11  6:19   ` Stefan Weil
@ 2012-01-12  3:26     ` David Gibson
  0 siblings, 0 replies; 10+ messages in thread
From: David Gibson @ 2012-01-12  3:26 UTC (permalink / raw)
  To: Stefan Weil; +Cc: agraf, qemu-devel

On Wed, Jan 11, 2012 at 07:19:00AM +0100, Stefan Weil wrote:
> Am 11.01.2012 06:44, schrieb David Gibson:
> >From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >
> >load_image_targphys() gets passed a max size for the file, but
> >doesn't enforce it at all. Add a check and return -1 (error) if
> >the file is too big, without loading it.
> >
> >Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >---
> >hw/loader.c | 2 ++
> >1 files changed, 2 insertions(+), 0 deletions(-)
> >
> >diff --git a/hw/loader.c b/hw/loader.c
> >index 446b628..7ad9e22 100644
> >--- a/hw/loader.c
> >+++ b/hw/loader.c
> >@@ -108,6 +108,8 @@ int load_image_targphys(const char *filename,
> >int size;
> >
> >size = get_image_size(filename);
> >+ if (size > max_sz)
> >+ return -1;
> >if (size > 0)
> >rom_add_file_fixed(filename, addr, -1);
> >return size;
> 
> Even if this file is full of block statements without braces,
> we should not add more of them. See CODING_STYLE and
> scripts/checkpatch.pl.

I know the coding style, I thought the counterexample right next to it
would take precedence.  Corrected in a respin.

> There remains an additional problem:
> Using 'int' for the size of files was sufficient 10 years ago,
> but it is that no longer. get_image_size() silently reduced the
> return value from lseek() to an 'int' value. So even with your
> patch, very large files will be loaded (partially)!

Well, sure, but that's an independent bug.  I'll fix it later if I get
to it, but that kind of leads to changing the types of a whole bunch
of things.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work
  2012-01-11  6:25   ` Stefan Weil
@ 2012-01-12  3:27     ` David Gibson
  2012-01-12  6:10       ` Stefan Weil
  0 siblings, 1 reply; 10+ messages in thread
From: David Gibson @ 2012-01-12  3:27 UTC (permalink / raw)
  To: Stefan Weil; +Cc: agraf, qemu-devel

On Wed, Jan 11, 2012 at 07:25:52AM +0100, Stefan Weil wrote:
> Am 11.01.2012 06:44, schrieb David Gibson:
> >The pci_host_config_{read,write}_common() functions perform PCI config
> >accesses. They take a limit parameter which they appear to be supposed
> >to bounds check against, however the bounds checking logic, such as it is,
> >is completely broken.
> >
> >Currently, it takes the minimum of the supplied length and the remaining
> >space in the region and passes that as the length to the underlying
> >config_{read,write} function pointer. This means that accesses which
> >partially overrun the region will be silently truncated - which makes
> >little sense. Accesses which entirely overrun the region will *not*
> >be blocked (an exploitable bug), because in that case (limit - addr) will
> >be negative and so the unsigned MIN will always return len instead. Even
> >if signed arithmetic was used, the config_{read,write} callback wouldn't
> >know what to do with a negative len parameter.
> >
> >This patch handles things more sanely by simply ignoring writes which
> >overrun, and returning -1 for reads, which is the usual hardware
> >convention
> >for reads to unpopulated IO regions.
> >
> >Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >---
> >hw/pci_host.c | 10 ++++++++--
> >1 files changed, 8 insertions(+), 2 deletions(-)
> >
> >diff --git a/hw/pci_host.c b/hw/pci_host.c
> >index 44c6c20..16b3ac3 100644
> >--- a/hw/pci_host.c
> >+++ b/hw/pci_host.c
> >@@ -51,14 +51,20 @@ void pci_host_config_write_common(PCIDevice
> >*pci_dev, uint32_t addr,
> >uint32_t limit, uint32_t val, uint32_t len)
> >{
> >assert(len <= 4);
> >- pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
> >+ if ((addr + len) <= limit) {
> >+ pci_dev->config_write(pci_dev, addr, val, len);
> >+ }
> >}
> >
> >uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
> >uint32_t limit, uint32_t len)
> >{
> >assert(len <= 4);
> >- return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
> >+ if ((addr + len) <= limit) {
> >+ return pci_dev->config_read(pci_dev, addr, len);
> >+ } else {
> >+ return ~0x0;
> >+ }
> >}
> >
> >void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
> 
> Some people use QEMU to detect this kind of errors in an emulated
> systems. Therefore an additional debug output would be good here.
> 
> As long as there is no QEMU standard for reporting this kind of errors,
> a PCI_DPRINTF statement might be best.

This seems like an independent enhancement to me.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work
  2012-01-12  3:27     ` David Gibson
@ 2012-01-12  6:10       ` Stefan Weil
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Weil @ 2012-01-12  6:10 UTC (permalink / raw)
  To: David Gibson, anthony, agraf, qemu-devel

   Am 12.01.2012 04:27, schrieb David Gibson:
> On Wed, Jan 11, 2012 at 07:25:52AM +0100, Stefan Weil wrote:
>> Am 11.01.2012 06:44, schrieb David Gibson:
>>> The pci_host_config_{read,write}_common() functions perform PCI config
>>> accesses. They take a limit parameter which they appear to be supposed
>>> to bounds check against, however the bounds checking logic, such as it is,
>>> is completely broken.
>>>
>>> Currently, it takes the minimum of the supplied length and the remaining
>>> space in the region and passes that as the length to the underlying
>>> config_{read,write} function pointer. This means that accesses which
>>> partially overrun the region will be silently truncated - which makes
>>> little sense. Accesses which entirely overrun the region will *not*
>>> be blocked (an exploitable bug), because in that case (limit - addr) will
>>> be negative and so the unsigned MIN will always return len instead. Even
>>> if signed arithmetic was used, the config_{read,write} callback wouldn't
>>> know what to do with a negative len parameter.
>>>
>>> This patch handles things more sanely by simply ignoring writes which
>>> overrun, and returning -1 for reads, which is the usual hardware
>>> convention
>>> for reads to unpopulated IO regions.
>>>
>>> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
>>> ---
>>> hw/pci_host.c | 10 ++++++++--
>>> 1 files changed, 8 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/hw/pci_host.c b/hw/pci_host.c
>>> index 44c6c20..16b3ac3 100644
>>> --- a/hw/pci_host.c
>>> +++ b/hw/pci_host.c
>>> @@ -51,14 +51,20 @@ void pci_host_config_write_common(PCIDevice
>>> *pci_dev, uint32_t addr,
>>> uint32_t limit, uint32_t val, uint32_t len)
>>> {
>>> assert(len<= 4);
>>> - pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
>>> + if ((addr + len)<= limit) {
>>> + pci_dev->config_write(pci_dev, addr, val, len);
>>> + }
>>> }
>>>
>>> uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
>>> uint32_t limit, uint32_t len)
>>> {
>>> assert(len<= 4);
>>> - return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
>>> + if ((addr + len)<= limit) {
>>> + return pci_dev->config_read(pci_dev, addr, len);
>>> + } else {
>>> + return ~0x0;
>>> + }
>>> }
>>>
>>> void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
>> Some people use QEMU to detect this kind of errors in an emulated
>> systems. Therefore an additional debug output would be good here.
>>
>> As long as there is no QEMU standard for reporting this kind of errors,
>> a PCI_DPRINTF statement might be best.
> This seems like an independent enhancement to me.

I don't mind if the debug output is added in a separate patch.

Adding a TODO comment now helps to remember that there
is something to be done later.

A TODO comment would also be good for PATCH 1/4.

Another point: instead of ~0, you could also use UINT32_MAX.

Regards,
Stefan Weil

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

end of thread, other threads:[~2012-01-12  6:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-11  5:44 [Qemu-devel] [0/4] Assorted bugfixes David Gibson
2012-01-11  5:44 ` [Qemu-devel] [PATCH 1/4] load_image_targphys() should enforce the max size David Gibson
2012-01-11  6:19   ` Stefan Weil
2012-01-12  3:26     ` David Gibson
2012-01-11  5:44 ` [Qemu-devel] [PATCH 2/4] Fix dirty logging with 32-bit qemu & 64-bit guests David Gibson
2012-01-11  5:44 ` [Qemu-devel] [PATCH 3/4] pci: Make bounds checks on config space accesses actually work David Gibson
2012-01-11  6:25   ` Stefan Weil
2012-01-12  3:27     ` David Gibson
2012-01-12  6:10       ` Stefan Weil
2012-01-11  5:44 ` [Qemu-devel] [PATCH 4/4] Update gitignore file David Gibson

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 NNTP newsgroup(s).