linux-audit.redhat.com archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] dm: audit event logging
@ 2021-08-12 14:57 Michael Weiß
  2021-08-12 14:57 ` [PATCH 1/3] dm: introduce audit event module for device mapper Michael Weiß
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Michael Weiß @ 2021-08-12 14:57 UTC (permalink / raw)
  To: michael.weiss
  Cc: Mike Snitzer, linux-kernel, Eric Paris, linux-raid, Song Liu,
	dm-devel, linux-audit, Alasdair Kergon

dm integrity and also stacked dm crypt devices track integrity
violations internally. Thus, integrity violations could be polled
from user space, e.g., by 'integritysetup status'.

>From an auditing perspective, we only could see that there were
a number of integrity violations, but not when and where the
violation exactly was taking place. The current error log to
the kernel ring buffer, contains those information, time stamp and
sector on device. However, for auditing the audit subsystem provides
a separate logging mechanism which meets certain criteria for secure
audit logging.

With this small series we make use of the kernel audit framework
and extend the dm driver to log audit events in case of such
integrity violations. Further, we also log construction and
destruction of the device mappings.

We focus on dm-integrity and stacked dm-crypt devices for now.
However, the helper functions to log audit messages should be
applicable to dm verity too.

The first patch introduce generic audit wrapper functions.
The second patch makes use of the audit wrapper functions in the
dm-integrity.c.
The third patch uses the wrapper functions in dm-crypt.c.

The audit logs look like this if executing the following simple test:

# dd if=/dev/zero of=test.img bs=1M count=1024
# losetup -f test.img
# integritysetup -vD format --integrity sha256 -t 32 /dev/loop0 
# integritysetup open -D /dev/loop0 --integrity sha256 integritytest
# integritysetup status integritytest
# integritysetup close integritytest
# integritysetup open -D /dev/loop0 --integrity sha256 integritytest
# integritysetup status integritytest
# dd if=/dev/urandom of=/dev/loop0 bs=512 count=1 seek=100000
# dd if=/dev/mapper/integritytest of=/dev/null

-------------------------
audit.log from auditd

type=UNKNOWN[1336] msg=audit(1628692862.187:409): module=integrity dev=254:3 op=ctr res=1
type=UNKNOWN[1336] msg=audit(1628692862.443:410): module=integrity dev=254:3 op=dtr res=1
type=UNKNOWN[1336] msg=audit(1628692862.543:411): module=integrity dev=254:3 op=ctr res=1
type=UNKNOWN[1336] msg=audit(1628692877.943:412): module=integrity dev=254:3 op=dtr res=1

type=UNKNOWN[1336] msg=audit(1628692887.287:413): module=integrity dev=254:3 op=ctr res=1

type=UNKNOWN[1336] msg=audit(1628692925.156:417): module=integrity dev=254:3 op=dtr res=1

type=UNKNOWN[1336] msg=audit(1628692930.720:418): module=integrity dev=254:3 op=ctr res=1

type=UNKNOWN[1336] msg=audit(1628692989.344:419): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:420): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:421): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:422): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:423): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:424): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:425): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:426): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:427): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0
type=UNKNOWN[1336] msg=audit(1628692989.348:428): module=integrity dev=254:3 op=integrity-checksum sector=77480 res=0

Michael Weiß (3):
  dm: introduce audit event module for device mapper
  dm integrity: log audit events for dm-integrity target
  dm crypt: log aead integrity violations to audit subsystem

 drivers/md/Kconfig         | 10 +++++++
 drivers/md/Makefile        |  4 +++
 drivers/md/dm-audit.c      | 59 ++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-audit.h      | 33 +++++++++++++++++++++
 drivers/md/dm-crypt.c      | 23 ++++++++++++---
 drivers/md/dm-integrity.c  | 25 +++++++++++++---
 include/uapi/linux/audit.h |  2 ++
 7 files changed, 148 insertions(+), 8 deletions(-)
 create mode 100644 drivers/md/dm-audit.c
 create mode 100644 drivers/md/dm-audit.h

-- 
2.20.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* [PATCH 1/3] dm: introduce audit event module for device mapper
  2021-08-12 14:57 [PATCH 0/3] dm: audit event logging Michael Weiß
@ 2021-08-12 14:57 ` Michael Weiß
  2021-08-12 17:08   ` Casey Schaufler
  2021-08-12 14:57 ` [PATCH 2/3] dm integrity: log audit events for dm-integrity target Michael Weiß
  2021-08-12 14:57 ` [PATCH 3/3] dm crypt: log aead integrity violations to audit subsystem Michael Weiß
  2 siblings, 1 reply; 7+ messages in thread
From: Michael Weiß @ 2021-08-12 14:57 UTC (permalink / raw)
  To: michael.weiss
  Cc: Mike Snitzer, linux-kernel, Eric Paris, linux-raid, Song Liu,
	dm-devel, linux-audit, Alasdair Kergon

To be able to send auditing events to user space, we introduce
a generic dm-audit module. It provides helper functions to emit
audit events through the kernel audit subsystem. We claim the
AUDIT_DM type=1336 out of the audit event messages range in the
corresponding userspace api in 'include/uapi/linux/audit.h' for
those events.

Following commits to device mapper targets actually will make
use of this to emit those events in relevant cases.

Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
---
 drivers/md/Kconfig         | 10 +++++++
 drivers/md/Makefile        |  4 +++
 drivers/md/dm-audit.c      | 59 ++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-audit.h      | 33 +++++++++++++++++++++
 include/uapi/linux/audit.h |  2 ++
 5 files changed, 108 insertions(+)
 create mode 100644 drivers/md/dm-audit.c
 create mode 100644 drivers/md/dm-audit.h

diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 0602e82a9516..fd54c713a03e 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -608,6 +608,7 @@ config DM_INTEGRITY
 	select CRYPTO
 	select CRYPTO_SKCIPHER
 	select ASYNC_XOR
+	select DM_AUDIT if AUDIT
 	help
 	  This device-mapper target emulates a block device that has
 	  additional per-sector tags that can be used for storing
@@ -640,4 +641,13 @@ config DM_ZONED
 
 	  If unsure, say N.
 
+config DM_AUDIT
+	bool "DM audit events"
+	depends on AUDIT
+	help
+	  Generate audit events for device-mapper.
+
+	  Enables audit loging of several security relevant events in the
+	  particular device-mapper targets, especially the integrity target.
+
 endif # MD
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index a74aaf8b1445..4cd47623c742 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -103,3 +103,7 @@ endif
 ifeq ($(CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG),y)
 dm-verity-objs			+= dm-verity-verify-sig.o
 endif
+
+ifeq ($(CONFIG_DM_AUDIT),y)
+dm-mod-objs				+= dm-audit.o
+endif
diff --git a/drivers/md/dm-audit.c b/drivers/md/dm-audit.c
new file mode 100644
index 000000000000..c7e5824821bb
--- /dev/null
+++ b/drivers/md/dm-audit.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Creating audit records for mapped devices.
+ *
+ * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
+ *
+ * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
+ */
+
+#include <linux/audit.h>
+#include <linux/module.h>
+#include <linux/device-mapper.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+
+#include "dm-audit.h"
+#include "dm-core.h"
+
+void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
+		      struct bio *bio, sector_t sector, int result)
+{
+	struct audit_buffer *ab;
+
+	if (audit_enabled == AUDIT_OFF)
+		return;
+
+	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
+	if (unlikely(!ab))
+		return;
+
+	audit_log_format(ab, "module=%s dev=%d:%d op=%s sector=%llu res=%d",
+			 dm_msg_prefix, MAJOR(bio->bi_bdev->bd_dev),
+			 MINOR(bio->bi_bdev->bd_dev), op, sector, result);
+	audit_log_end(ab);
+}
+EXPORT_SYMBOL_GPL(dm_audit_log_bio);
+
+void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
+			 struct dm_target *ti, int result)
+{
+	struct audit_buffer *ab;
+	struct mapped_device *md = dm_table_get_md(ti->table);
+
+	if (audit_enabled == AUDIT_OFF)
+		return;
+
+	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
+	if (unlikely(!ab))
+		return;
+
+	audit_log_format(ab, "module=%s dev=%s op=%s",
+			 dm_msg_prefix, dm_device_name(md), op);
+
+	if (!result && !strcmp("ctr", op))
+		audit_log_format(ab, " error_msg='%s'", ti->error);
+	audit_log_format(ab, " res=%d", result);
+	audit_log_end(ab);
+}
+EXPORT_SYMBOL_GPL(dm_audit_log_target);
diff --git a/drivers/md/dm-audit.h b/drivers/md/dm-audit.h
new file mode 100644
index 000000000000..9db4955d32e1
--- /dev/null
+++ b/drivers/md/dm-audit.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Creating audit records for mapped devices.
+ *
+ * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
+ *
+ * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
+ */
+
+#ifndef DM_AUDIT_H
+#define DM_AUDIT_H
+
+#include <linux/device-mapper.h>
+
+#ifdef CONFIG_DM_AUDIT
+void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
+		      struct bio *bio, sector_t sector, int result);
+void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
+			 struct dm_target *ti, int result);
+#else
+static inline void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
+				    struct bio *bio, sector_t sector,
+				    int result);
+{
+}
+static inline void dm_audit_log_target(const char *dm_msg_prefix,
+				       const char *op, struct dm_target *ti,
+				       int result);
+{
+}
+#endif
+
+#endif
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index daa481729e9b..9d766fcbcf62 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -118,6 +118,7 @@
 #define AUDIT_TIME_ADJNTPVAL	1333	/* NTP value adjustment */
 #define AUDIT_BPF		1334	/* BPF subsystem */
 #define AUDIT_EVENT_LISTENER	1335	/* Task joined multicast read socket */
+#define AUDIT_DM		1336	/* Device Mapper events */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -140,6 +141,7 @@
 #define AUDIT_MAC_CALIPSO_ADD	1418	/* NetLabel: add CALIPSO DOI entry */
 #define AUDIT_MAC_CALIPSO_DEL	1419	/* NetLabel: del CALIPSO DOI entry */
 
+
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
 #define AUDIT_ANOM_PROMISCUOUS      1700 /* Device changed promiscuous mode */
-- 
2.20.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* [PATCH 2/3] dm integrity: log audit events for dm-integrity target
  2021-08-12 14:57 [PATCH 0/3] dm: audit event logging Michael Weiß
  2021-08-12 14:57 ` [PATCH 1/3] dm: introduce audit event module for device mapper Michael Weiß
@ 2021-08-12 14:57 ` Michael Weiß
  2021-08-12 17:20   ` kernel test robot
  2021-08-12 14:57 ` [PATCH 3/3] dm crypt: log aead integrity violations to audit subsystem Michael Weiß
  2 siblings, 1 reply; 7+ messages in thread
From: Michael Weiß @ 2021-08-12 14:57 UTC (permalink / raw)
  To: michael.weiss
  Cc: Mike Snitzer, linux-kernel, Eric Paris, linux-raid, Song Liu,
	dm-devel, linux-audit, Alasdair Kergon

dm-integrity signals integrity violations by returning I/O errors
to user space. To identify integrity violations by a controlling
instance, the kernel audit subsystem can be used to emit audit
events to user space. We use the new dm-audit submodule allowing
to emit audit events on relevant I/O errors.

The construction and destruction of integrity device mappings are
also relevant for auditing a system. Thus, those events are also
logged as audit events.

Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
---
 drivers/md/dm-integrity.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 20f2510db1f6..fbbb4c3f16cb 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -23,6 +23,8 @@
 #include <linux/async_tx.h>
 #include <linux/dm-bufio.h>
 
+#include "dm-audit.h"
+
 #define DM_MSG_PREFIX "integrity"
 
 #define DEFAULT_INTERLEAVE_SECTORS	32768
@@ -539,6 +541,7 @@ static int sb_mac(struct dm_integrity_c *ic, bool wr)
 		}
 		if (memcmp((__u8 *)ic->sb + (1 << SECTOR_SHIFT) - size, result, size)) {
 			dm_integrity_io_error(ic, "superblock mac", -EILSEQ);
+			dm_audit_log_target(DM_MSG_PREFIX, "mac-superblock", ic->ti, 0);
 			return -EILSEQ;
 		}
 	}
@@ -876,8 +879,10 @@ static void rw_section_mac(struct dm_integrity_c *ic, unsigned section, bool wr)
 		if (likely(wr))
 			memcpy(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR);
 		else {
-			if (memcmp(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR))
+			if (memcmp(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR)) {
 				dm_integrity_io_error(ic, "journal mac", -EILSEQ);
+				dm_audit_log_target(DM_MSG_PREFIX, "mac-journal", ic->ti, 0);
+			}
 		}
 	}
 }
@@ -1782,10 +1787,15 @@ static void integrity_metadata(struct work_struct *w)
 			if (unlikely(r)) {
 				if (r > 0) {
 					char b[BDEVNAME_SIZE];
-					DMERR_LIMIT("%s: Checksum failed at sector 0x%llx", bio_devname(bio, b),
-						    (sector - ((r + ic->tag_size - 1) / ic->tag_size)));
+					sector_t s;
+
+					s = sector - ((r + ic->tag_size - 1) / ic->tag_size);
+					DMERR_LIMIT("%s: Checksum failed at sector 0x%llx",
+						    bio_devname(bio, b), s);
 					r = -EILSEQ;
 					atomic64_inc(&ic->number_of_mismatches);
+					dm_audit_log_bio(DM_MSG_PREFIX, "integrity-checksum",
+							 bio, s, 0);
 				}
 				if (likely(checksums != checksums_onstack))
 					kfree(checksums);
@@ -1991,6 +2001,8 @@ static bool __journal_read_write(struct dm_integrity_io *dio, struct bio *bio,
 					if (unlikely(memcmp(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) {
 						DMERR_LIMIT("Checksum failed when reading from journal, at sector 0x%llx",
 							    logical_sector);
+						dm_audit_log_bio(DM_MSG_PREFIX, "journal-checksum",
+								 bio, logical_sector, 0);
 					}
 				}
 #endif
@@ -2534,8 +2546,10 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned write_start,
 
 					integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block),
 								  (char *)access_journal_data(ic, i, l), test_tag);
-					if (unlikely(memcmp(test_tag, journal_entry_tag(ic, je2), ic->tag_size)))
+					if (unlikely(memcmp(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
 						dm_integrity_io_error(ic, "tag mismatch when replaying journal", -EILSEQ);
+						dm_audit_log_target(DM_MSG_PREFIX, "integrity-replay-journal", ic->ti, 0);
+					}
 				}
 
 				journal_entry_set_unused(je2);
@@ -4490,9 +4504,11 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	if (ic->discard)
 		ti->num_discard_bios = 1;
 
+	dm_audit_log_target(DM_MSG_PREFIX, "ctr", ti, 1);
 	return 0;
 
 bad:
+	dm_audit_log_target(DM_MSG_PREFIX, "ctr", ti, 0);
 	dm_integrity_dtr(ti);
 	return r;
 }
@@ -4566,6 +4582,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
 	free_alg(&ic->journal_mac_alg);
 
 	kfree(ic);
+	dm_audit_log_target(DM_MSG_PREFIX, "dtr", ti, 1);
 }
 
 static struct target_type integrity_target = {
-- 
2.20.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* [PATCH 3/3] dm crypt: log aead integrity violations to audit subsystem
  2021-08-12 14:57 [PATCH 0/3] dm: audit event logging Michael Weiß
  2021-08-12 14:57 ` [PATCH 1/3] dm: introduce audit event module for device mapper Michael Weiß
  2021-08-12 14:57 ` [PATCH 2/3] dm integrity: log audit events for dm-integrity target Michael Weiß
@ 2021-08-12 14:57 ` Michael Weiß
  2 siblings, 0 replies; 7+ messages in thread
From: Michael Weiß @ 2021-08-12 14:57 UTC (permalink / raw)
  To: michael.weiss
  Cc: Mike Snitzer, linux-kernel, Eric Paris, linux-raid, Song Liu,
	dm-devel, linux-audit, Alasdair Kergon

Since dm-crypt target can be stacked on dm-integrity targets to
provide authenticated encryption, integrity violations are recognized
here during aead computation. We use the dm-audit submodule to
signal those events to user space, too.

The construction and destruction of crypt device mappings are also
logged as audit events.

Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
---
 drivers/md/dm-crypt.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 50f4cbd600d5..343aef4dcf5e 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -41,6 +41,8 @@
 
 #include <linux/device-mapper.h>
 
+#include "dm-audit.h"
+
 #define DM_MSG_PREFIX "crypt"
 
 /*
@@ -1122,6 +1124,7 @@ static bool crypt_integrity_hmac(struct crypt_config *cc)
 	return crypt_integrity_aead(cc) && cc->key_mac_size;
 }
 
+
 /* Get sg containing data */
 static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc,
 					     struct scatterlist *sg)
@@ -1362,8 +1365,12 @@ static int crypt_convert_block_aead(struct crypt_config *cc,
 
 	if (r == -EBADMSG) {
 		char b[BDEVNAME_SIZE];
-		DMERR_LIMIT("%s: INTEGRITY AEAD ERROR, sector %llu", bio_devname(ctx->bio_in, b),
-			    (unsigned long long)le64_to_cpu(*sector));
+		sector_t s = le64_to_cpu(*sector);
+
+		DMERR_LIMIT("%s: INTEGRITY AEAD ERROR, sector %llu",
+			    bio_devname(ctx->bio_in, b), s);
+		dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead",
+				 ctx->bio_in, s, 0);
 	}
 
 	if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post)
@@ -2173,8 +2180,12 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
 
 	if (error == -EBADMSG) {
 		char b[BDEVNAME_SIZE];
-		DMERR_LIMIT("%s: INTEGRITY AEAD ERROR, sector %llu", bio_devname(ctx->bio_in, b),
-			    (unsigned long long)le64_to_cpu(*org_sector_of_dmreq(cc, dmreq)));
+		sector_t s = le64_to_cpu(*org_sector_of_dmreq(cc, dmreq));
+
+		DMERR_LIMIT("%s: INTEGRITY AEAD ERROR, sector %llu",
+			    bio_devname(ctx->bio_in, b), s);
+		dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead",
+				 ctx->bio_in, s, 0);
 		io->error = BLK_STS_PROTECTION;
 	} else if (error < 0)
 		io->error = BLK_STS_IOERR;
@@ -2729,6 +2740,8 @@ static void crypt_dtr(struct dm_target *ti)
 	dm_crypt_clients_n--;
 	crypt_calculate_pages_per_client();
 	spin_unlock(&dm_crypt_clients_lock);
+
+	dm_audit_log_target(DM_MSG_PREFIX, "dtr", ti, 1);
 }
 
 static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode)
@@ -3357,9 +3370,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	ti->num_flush_bios = 1;
 	ti->limit_swap_bios = true;
 
+	dm_audit_log_target(DM_MSG_PREFIX, "ctr", ti, 1);
 	return 0;
 
 bad:
+	dm_audit_log_target(DM_MSG_PREFIX, "ctr", ti, 0);
 	crypt_dtr(ti);
 	return ret;
 }
-- 
2.20.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* Re: [PATCH 1/3] dm: introduce audit event module for device mapper
  2021-08-12 14:57 ` [PATCH 1/3] dm: introduce audit event module for device mapper Michael Weiß
@ 2021-08-12 17:08   ` Casey Schaufler
  2021-08-13  6:59     ` Weiß, Michael
  0 siblings, 1 reply; 7+ messages in thread
From: Casey Schaufler @ 2021-08-12 17:08 UTC (permalink / raw)
  To: Michael Weiß
  Cc: Mike Snitzer, linux-kernel, Eric Paris, linux-raid, Song Liu,
	dm-devel, linux-audit, Alasdair Kergon

On 8/12/2021 7:57 AM, Michael Weiß wrote:
> To be able to send auditing events to user space, we introduce
> a generic dm-audit module. It provides helper functions to emit
> audit events through the kernel audit subsystem. We claim the
> AUDIT_DM type=1336 out of the audit event messages range in the
> corresponding userspace api in 'include/uapi/linux/audit.h' for
> those events.
>
> Following commits to device mapper targets actually will make
> use of this to emit those events in relevant cases.
>
> Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> ---
>  drivers/md/Kconfig         | 10 +++++++
>  drivers/md/Makefile        |  4 +++
>  drivers/md/dm-audit.c      | 59 ++++++++++++++++++++++++++++++++++++++
>  drivers/md/dm-audit.h      | 33 +++++++++++++++++++++
>  include/uapi/linux/audit.h |  2 ++
>  5 files changed, 108 insertions(+)
>  create mode 100644 drivers/md/dm-audit.c
>  create mode 100644 drivers/md/dm-audit.h
>
> diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
> index 0602e82a9516..fd54c713a03e 100644
> --- a/drivers/md/Kconfig
> +++ b/drivers/md/Kconfig
> @@ -608,6 +608,7 @@ config DM_INTEGRITY
>  	select CRYPTO
>  	select CRYPTO_SKCIPHER
>  	select ASYNC_XOR
> +	select DM_AUDIT if AUDIT
>  	help
>  	  This device-mapper target emulates a block device that has
>  	  additional per-sector tags that can be used for storing
> @@ -640,4 +641,13 @@ config DM_ZONED
>  
>  	  If unsure, say N.
>  
> +config DM_AUDIT
> +	bool "DM audit events"
> +	depends on AUDIT
> +	help
> +	  Generate audit events for device-mapper.
> +
> +	  Enables audit loging of several security relevant events in the

s/loging/logging/

> +	  particular device-mapper targets, especially the integrity target.
> +
>  endif # MD
> diff --git a/drivers/md/Makefile b/drivers/md/Makefile
> index a74aaf8b1445..4cd47623c742 100644
> --- a/drivers/md/Makefile
> +++ b/drivers/md/Makefile
> @@ -103,3 +103,7 @@ endif
>  ifeq ($(CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG),y)
>  dm-verity-objs			+= dm-verity-verify-sig.o
>  endif
> +
> +ifeq ($(CONFIG_DM_AUDIT),y)
> +dm-mod-objs				+= dm-audit.o
> +endif
> diff --git a/drivers/md/dm-audit.c b/drivers/md/dm-audit.c
> new file mode 100644
> index 000000000000..c7e5824821bb
> --- /dev/null
> +++ b/drivers/md/dm-audit.c
> @@ -0,0 +1,59 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Creating audit records for mapped devices.
> + *
> + * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
> + *
> + * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> + */
> +
> +#include <linux/audit.h>
> +#include <linux/module.h>
> +#include <linux/device-mapper.h>
> +#include <linux/bio.h>
> +#include <linux/blkdev.h>
> +
> +#include "dm-audit.h"
> +#include "dm-core.h"
> +
> +void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> +		      struct bio *bio, sector_t sector, int result)
> +{
> +	struct audit_buffer *ab;
> +
> +	if (audit_enabled == AUDIT_OFF)
> +		return;
> +
> +	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
> +	if (unlikely(!ab))
> +		return;
> +
> +	audit_log_format(ab, "module=%s dev=%d:%d op=%s sector=%llu res=%d",
> +			 dm_msg_prefix, MAJOR(bio->bi_bdev->bd_dev),
> +			 MINOR(bio->bi_bdev->bd_dev), op, sector, result);
> +	audit_log_end(ab);
> +}
> +EXPORT_SYMBOL_GPL(dm_audit_log_bio);
> +
> +void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
> +			 struct dm_target *ti, int result)
> +{
> +	struct audit_buffer *ab;
> +	struct mapped_device *md = dm_table_get_md(ti->table);
> +
> +	if (audit_enabled == AUDIT_OFF)
> +		return;
> +
> +	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
> +	if (unlikely(!ab))
> +		return;
> +
> +	audit_log_format(ab, "module=%s dev=%s op=%s",
> +			 dm_msg_prefix, dm_device_name(md), op);
> +
> +	if (!result && !strcmp("ctr", op))
> +		audit_log_format(ab, " error_msg='%s'", ti->error);
> +	audit_log_format(ab, " res=%d", result);
> +	audit_log_end(ab);
> +}
> +EXPORT_SYMBOL_GPL(dm_audit_log_target);
> diff --git a/drivers/md/dm-audit.h b/drivers/md/dm-audit.h
> new file mode 100644
> index 000000000000..9db4955d32e1
> --- /dev/null
> +++ b/drivers/md/dm-audit.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Creating audit records for mapped devices.
> + *
> + * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
> + *
> + * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> + */
> +
> +#ifndef DM_AUDIT_H
> +#define DM_AUDIT_H
> +
> +#include <linux/device-mapper.h>
> +
> +#ifdef CONFIG_DM_AUDIT
> +void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> +		      struct bio *bio, sector_t sector, int result);
> +void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
> +			 struct dm_target *ti, int result);
> +#else
> +static inline void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> +				    struct bio *bio, sector_t sector,
> +				    int result);
> +{
> +}
> +static inline void dm_audit_log_target(const char *dm_msg_prefix,
> +				       const char *op, struct dm_target *ti,
> +				       int result);
> +{
> +}
> +#endif
> +
> +#endif
> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index daa481729e9b..9d766fcbcf62 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -118,6 +118,7 @@
>  #define AUDIT_TIME_ADJNTPVAL	1333	/* NTP value adjustment */
>  #define AUDIT_BPF		1334	/* BPF subsystem */
>  #define AUDIT_EVENT_LISTENER	1335	/* Task joined multicast read socket */
> +#define AUDIT_DM		1336	/* Device Mapper events */
>  
>  #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
>  #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
> @@ -140,6 +141,7 @@
>  #define AUDIT_MAC_CALIPSO_ADD	1418	/* NetLabel: add CALIPSO DOI entry */
>  #define AUDIT_MAC_CALIPSO_DEL	1419	/* NetLabel: del CALIPSO DOI entry */
>  
> +

Unnecessary additional whitespace.

>  #define AUDIT_FIRST_KERN_ANOM_MSG   1700
>  #define AUDIT_LAST_KERN_ANOM_MSG    1799
>  #define AUDIT_ANOM_PROMISCUOUS      1700 /* Device changed promiscuous mode */

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* Re: [PATCH 2/3] dm integrity: log audit events for dm-integrity target
  2021-08-12 14:57 ` [PATCH 2/3] dm integrity: log audit events for dm-integrity target Michael Weiß
@ 2021-08-12 17:20   ` kernel test robot
  0 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-08-12 17:20 UTC (permalink / raw)
  To: Michael Weiß
  Cc: kbuild-all, Mike Snitzer, linux-kernel, Eric Paris, linux-raid,
	Song Liu, dm-devel, linux-audit, Alasdair Kergon

[-- Attachment #1: Type: text/plain, Size: 3756 bytes --]

Hi "Michael,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on dm/for-next]
[also build test ERROR on song-md/md-next pcmoore-audit/next v5.14-rc5 next-20210812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Michael-Wei/dm-audit-event-logging/20210812-230045
base:   https://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git for-next
config: h8300-randconfig-r032-20210812 (attached as .config)
compiler: h8300-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/6fbfa051e144cc5cb000f7de14ee5b0e83d82b57
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Michael-Wei/dm-audit-event-logging/20210812-230045
        git checkout 6fbfa051e144cc5cb000f7de14ee5b0e83d82b57
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=h8300 SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/md/dm-integrity.c:26:
>> drivers/md/dm-audit.h:24:1: error: expected identifier or '(' before '{' token
      24 | {
         | ^
   drivers/md/dm-audit.h:29:1: error: expected identifier or '(' before '{' token
      29 | {
         | ^
>> drivers/md/dm-audit.h:21:20: warning: 'dm_audit_log_bio' used but never defined
      21 | static inline void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
         |                    ^~~~~~~~~~~~~~~~
>> drivers/md/dm-audit.h:26:20: warning: 'dm_audit_log_target' used but never defined
      26 | static inline void dm_audit_log_target(const char *dm_msg_prefix,
         |                    ^~~~~~~~~~~~~~~~~~~


vim +24 drivers/md/dm-audit.h

a409dd36b7054b Michael Weiß 2021-08-12  14  
a409dd36b7054b Michael Weiß 2021-08-12  15  #ifdef CONFIG_DM_AUDIT
a409dd36b7054b Michael Weiß 2021-08-12  16  void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
a409dd36b7054b Michael Weiß 2021-08-12  17  		      struct bio *bio, sector_t sector, int result);
a409dd36b7054b Michael Weiß 2021-08-12  18  void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
a409dd36b7054b Michael Weiß 2021-08-12  19  			 struct dm_target *ti, int result);
a409dd36b7054b Michael Weiß 2021-08-12  20  #else
a409dd36b7054b Michael Weiß 2021-08-12 @21  static inline void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
a409dd36b7054b Michael Weiß 2021-08-12  22  				    struct bio *bio, sector_t sector,
a409dd36b7054b Michael Weiß 2021-08-12  23  				    int result);
a409dd36b7054b Michael Weiß 2021-08-12 @24  {
a409dd36b7054b Michael Weiß 2021-08-12  25  }
a409dd36b7054b Michael Weiß 2021-08-12 @26  static inline void dm_audit_log_target(const char *dm_msg_prefix,
a409dd36b7054b Michael Weiß 2021-08-12  27  				       const char *op, struct dm_target *ti,
a409dd36b7054b Michael Weiß 2021-08-12  28  				       int result);
a409dd36b7054b Michael Weiß 2021-08-12  29  {
a409dd36b7054b Michael Weiß 2021-08-12  30  }
a409dd36b7054b Michael Weiß 2021-08-12  31  #endif
a409dd36b7054b Michael Weiß 2021-08-12  32  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 21996 bytes --]

[-- Attachment #3: Type: text/plain, Size: 106 bytes --]

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

* Re: [PATCH 1/3] dm: introduce audit event module for device mapper
  2021-08-12 17:08   ` Casey Schaufler
@ 2021-08-13  6:59     ` Weiß, Michael
  0 siblings, 0 replies; 7+ messages in thread
From: Weiß, Michael @ 2021-08-13  6:59 UTC (permalink / raw)
  To: casey
  Cc: snitzer, linux-kernel, eparis, linux-raid, song, dm-devel,
	linux-audit, agk

Hi Casey,

On Thu, 2021-08-12 at 10:08 -0700, Casey Schaufler wrote:
> On 8/12/2021 7:57 AM, Michael Weiß wrote:
> > To be able to send auditing events to user space, we introduce
> > a generic dm-audit module. It provides helper functions to emit
> > audit events through the kernel audit subsystem. We claim the
> > AUDIT_DM type=1336 out of the audit event messages range in the
> > corresponding userspace api in 'include/uapi/linux/audit.h' for
> > those events.
> > 
> > Following commits to device mapper targets actually will make
> > use of this to emit those events in relevant cases.
> > 
> > Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> > ---
> >  drivers/md/Kconfig         | 10 +++++++
> >  drivers/md/Makefile        |  4 +++
> >  drivers/md/dm-audit.c      | 59 ++++++++++++++++++++++++++++++++++++++
> >  drivers/md/dm-audit.h      | 33 +++++++++++++++++++++
> >  include/uapi/linux/audit.h |  2 ++
> >  5 files changed, 108 insertions(+)
> >  create mode 100644 drivers/md/dm-audit.c
> >  create mode 100644 drivers/md/dm-audit.h
> > 
> > diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
> > index 0602e82a9516..fd54c713a03e 100644
> > --- a/drivers/md/Kconfig
> > +++ b/drivers/md/Kconfig
> > @@ -608,6 +608,7 @@ config DM_INTEGRITY
> >  	select CRYPTO
> >  	select CRYPTO_SKCIPHER
> >  	select ASYNC_XOR
> > +	select DM_AUDIT if AUDIT
> >  	help
> >  	  This device-mapper target emulates a block device that has
> >  	  additional per-sector tags that can be used for storing
> > @@ -640,4 +641,13 @@ config DM_ZONED
> >  
> >  	  If unsure, say N.
> >  
> > +config DM_AUDIT
> > +	bool "DM audit events"
> > +	depends on AUDIT
> > +	help
> > +	  Generate audit events for device-mapper.
> > +
> > +	  Enables audit loging of several security relevant events in the
> 
> s/loging/logging/
> 
> > +	  particular device-mapper targets, especially the integrity target.
> > +
> >  endif # MD
> > diff --git a/drivers/md/Makefile b/drivers/md/Makefile
> > index a74aaf8b1445..4cd47623c742 100644
> > --- a/drivers/md/Makefile
> > +++ b/drivers/md/Makefile
> > @@ -103,3 +103,7 @@ endif
> >  ifeq ($(CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG),y)
> >  dm-verity-objs			+= dm-verity-verify-sig.o
> >  endif
> > +
> > +ifeq ($(CONFIG_DM_AUDIT),y)
> > +dm-mod-objs				+= dm-audit.o
> > +endif
> > diff --git a/drivers/md/dm-audit.c b/drivers/md/dm-audit.c
> > new file mode 100644
> > index 000000000000..c7e5824821bb
> > --- /dev/null
> > +++ b/drivers/md/dm-audit.c
> > @@ -0,0 +1,59 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Creating audit records for mapped devices.
> > + *
> > + * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
> > + *
> > + * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> > + */
> > +
> > +#include <linux/audit.h>
> > +#include <linux/module.h>
> > +#include <linux/device-mapper.h>
> > +#include <linux/bio.h>
> > +#include <linux/blkdev.h>
> > +
> > +#include "dm-audit.h"
> > +#include "dm-core.h"
> > +
> > +void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> > +		      struct bio *bio, sector_t sector, int result)
> > +{
> > +	struct audit_buffer *ab;
> > +
> > +	if (audit_enabled == AUDIT_OFF)
> > +		return;
> > +
> > +	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
> > +	if (unlikely(!ab))
> > +		return;
> > +
> > +	audit_log_format(ab, "module=%s dev=%d:%d op=%s sector=%llu res=%d",
> > +			 dm_msg_prefix, MAJOR(bio->bi_bdev->bd_dev),
> > +			 MINOR(bio->bi_bdev->bd_dev), op, sector, result);
> > +	audit_log_end(ab);
> > +}
> > +EXPORT_SYMBOL_GPL(dm_audit_log_bio);
> > +
> > +void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
> > +			 struct dm_target *ti, int result)
> > +{
> > +	struct audit_buffer *ab;
> > +	struct mapped_device *md = dm_table_get_md(ti->table);
> > +
> > +	if (audit_enabled == AUDIT_OFF)
> > +		return;
> > +
> > +	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_DM);
> > +	if (unlikely(!ab))
> > +		return;
> > +
> > +	audit_log_format(ab, "module=%s dev=%s op=%s",
> > +			 dm_msg_prefix, dm_device_name(md), op);
> > +
> > +	if (!result && !strcmp("ctr", op))
> > +		audit_log_format(ab, " error_msg='%s'", ti->error);
> > +	audit_log_format(ab, " res=%d", result);
> > +	audit_log_end(ab);
> > +}
> > +EXPORT_SYMBOL_GPL(dm_audit_log_target);
> > diff --git a/drivers/md/dm-audit.h b/drivers/md/dm-audit.h
> > new file mode 100644
> > index 000000000000..9db4955d32e1
> > --- /dev/null
> > +++ b/drivers/md/dm-audit.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Creating audit records for mapped devices.
> > + *
> > + * Copyright (C) 2021 Fraunhofer AISEC. All rights reserved.
> > + *
> > + * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
> > + */
> > +
> > +#ifndef DM_AUDIT_H
> > +#define DM_AUDIT_H
> > +
> > +#include <linux/device-mapper.h>
> > +
> > +#ifdef CONFIG_DM_AUDIT
> > +void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> > +		      struct bio *bio, sector_t sector, int result);
> > +void dm_audit_log_target(const char *dm_msg_prefix, const char *op,
> > +			 struct dm_target *ti, int result);
> > +#else
> > +static inline void dm_audit_log_bio(const char *dm_msg_prefix, const char *op,
> > +				    struct bio *bio, sector_t sector,
> > +				    int result);
> > +{
> > +}

kernel test robot spotted a syntax error if CONFIG_DM_AUDIT is
not set here, too. Will fix this in v2.

> > +static inline void dm_audit_log_target(const char *dm_msg_prefix,
> > +				       const char *op, struct dm_target *ti,
> > +				       int result);
> > +{
> > +}
> > +#endif
> > +
> > +#endif
> > diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> > index daa481729e9b..9d766fcbcf62 100644
> > --- a/include/uapi/linux/audit.h
> > +++ b/include/uapi/linux/audit.h
> > @@ -118,6 +118,7 @@
> >  #define AUDIT_TIME_ADJNTPVAL	1333	/* NTP value adjustment */
> >  #define AUDIT_BPF		1334	/* BPF subsystem */
> >  #define AUDIT_EVENT_LISTENER	1335	/* Task joined multicast read socket */
> > +#define AUDIT_DM		1336	/* Device Mapper events */
> >  
> >  #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
> >  #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
> > @@ -140,6 +141,7 @@
> >  #define AUDIT_MAC_CALIPSO_ADD	1418	/* NetLabel: add CALIPSO DOI entry */
> >  #define AUDIT_MAC_CALIPSO_DEL	1419	/* NetLabel: del CALIPSO DOI entry */
> >  
> > +
> 
> Unnecessary additional whitespace.
> 
> >  #define AUDIT_FIRST_KERN_ANOM_MSG   1700
> >  #define AUDIT_LAST_KERN_ANOM_MSG    1799
> >  #define AUDIT_ANOM_PROMISCUOUS      1700 /* Device changed promiscuous mode */

Thanks for spotting the errors, I will fix them in v2.

Regards,
Michael

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

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

end of thread, other threads:[~2021-08-13 15:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 14:57 [PATCH 0/3] dm: audit event logging Michael Weiß
2021-08-12 14:57 ` [PATCH 1/3] dm: introduce audit event module for device mapper Michael Weiß
2021-08-12 17:08   ` Casey Schaufler
2021-08-13  6:59     ` Weiß, Michael
2021-08-12 14:57 ` [PATCH 2/3] dm integrity: log audit events for dm-integrity target Michael Weiß
2021-08-12 17:20   ` kernel test robot
2021-08-12 14:57 ` [PATCH 3/3] dm crypt: log aead integrity violations to audit subsystem Michael Weiß

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