[kernel/f13/master] Security updates CVE-2010-4346: install_special_mapping skips security_file_mmap check CVE-2010-

Chuck Ebbert cebbert at fedoraproject.org
Sat Jan 22 17:26:33 UTC 2011


commit ce15d645be55a6229f4c596aca7ba66ca960bb21
Author: Chuck Ebbert <cebbert at redhat.com>
Date:   Sat Jan 22 12:25:37 2011 -0500

    Security updates
      CVE-2010-4346: install_special_mapping skips security_file_mmap check
      CVE-2010-4649: IB/uverbs: Handle large number of entries in poll CQ
      CVE-2011-0006: ima: fix add LSM rule bug
      CVE-2010-4648: orinoco: fix TKIP countermeasure behaviour
      CVE-2010-4650: fuse: verify ioctl retries

 fuse-verify-ioctl-retries.patch                    |   56 +++++++
 ...e-large-number-of-poll-entries-in-poll-cq.patch |  160 ++++++++++++++++++++
 ima-fix-add-lsm-rule-bug.patch                     |   62 ++++++++
 ...al-mapping-skips-security-file-mmap-check.patch |  107 +++++++++++++
 kernel.spec                                        |   30 ++++
 orinoco-fix-tkip-countermeasure-behaviour.patch    |   59 +++++++
 6 files changed, 474 insertions(+), 0 deletions(-)
---
diff --git a/fuse-verify-ioctl-retries.patch b/fuse-verify-ioctl-retries.patch
new file mode 100644
index 0000000..d95d8ce
--- /dev/null
+++ b/fuse-verify-ioctl-retries.patch
@@ -0,0 +1,56 @@
+From: Miklos Szeredi <mszeredi at suse.cz>
+Date: Tue, 30 Nov 2010 15:39:27 +0000 (+0100)
+Subject: fuse: verify ioctl retries
+X-Git-Tag: v2.6.37-rc6~31^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7572777eef78ebdee1ecb7c258c0ef94d35bad16
+
+fuse: verify ioctl retries
+
+Verify that the total length of the iovec returned in FUSE_IOCTL_RETRY
+doesn't overflow iov_length().
+
+Signed-off-by: Miklos Szeredi <mszeredi at suse.cz>
+CC: Tejun Heo <tj at kernel.org>
+CC: <stable at kernel.org>         [2.6.31+]
+---
+
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 0e2e25b..8b984a2 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1666,6 +1666,20 @@ static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src,
+ 	return 0;
+ }
+ 
++/* Make sure iov_length() won't overflow */
++static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
++{
++	size_t n;
++	u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
++
++	for (n = 0; n < count; n++) {
++		if (iov->iov_len > (size_t) max)
++			return -ENOMEM;
++		max -= iov->iov_len;
++	}
++	return 0;
++}
++
+ /*
+  * For ioctls, there is no generic way to determine how much memory
+  * needs to be read and/or written.  Furthermore, ioctls are allowed
+@@ -1858,6 +1872,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
+ 		in_iov = page_address(iov_page);
+ 		out_iov = in_iov + in_iovs;
+ 
++		err = fuse_verify_ioctl_iov(in_iov, in_iovs);
++		if (err)
++			goto out;
++
++		err = fuse_verify_ioctl_iov(out_iov, out_iovs);
++		if (err)
++			goto out;
++
+ 		goto retry;
+ 	}
+ 
diff --git a/ib-uverbs-handle-large-number-of-poll-entries-in-poll-cq.patch b/ib-uverbs-handle-large-number-of-poll-entries-in-poll-cq.patch
new file mode 100644
index 0000000..cfa5bf9
--- /dev/null
+++ b/ib-uverbs-handle-large-number-of-poll-entries-in-poll-cq.patch
@@ -0,0 +1,160 @@
+From: Dan Carpenter <error27 at gmail.com>
+Date: Wed, 13 Oct 2010 09:13:12 +0000 (+0000)
+Subject: IB/uverbs: Handle large number of entries in poll CQ
+X-Git-Tag: v2.6.37-rc6~22^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7182afea8d1afd432a17c18162cc3fd441d0da93
+
+IB/uverbs: Handle large number of entries in poll CQ
+
+In ib_uverbs_poll_cq() code there is a potential integer overflow if
+userspace passes in a large cmd.ne.  The calls to kmalloc() would
+allocate smaller buffers than intended, leading to memory corruption.
+There iss also an information leak if resp wasn't all used.
+Unprivileged userspace may call this function, although only if an
+RDMA device that uses this function is present.
+
+Fix this by copying CQ entries one at a time, which avoids the
+allocation entirely, and also by moving this copying into a function
+that makes sure to initialize all memory copied to userspace.
+
+Special thanks to Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
+for his help and advice.
+
+Cc: <stable at kernel.org>
+Signed-off-by: Dan Carpenter <error27 at gmail.com>
+
+[ Monkey around with things a bit to avoid bad code generation by gcc
+  when designated initializers are used.  - Roland ]
+
+Signed-off-by: Roland Dreier <rolandd at cisco.com>
+---
+
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index b342248..c426992 100644
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -893,68 +893,81 @@ out:
+ 	return ret ? ret : in_len;
+ }
+ 
++static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
++{
++	struct ib_uverbs_wc tmp;
++
++	tmp.wr_id		= wc->wr_id;
++	tmp.status		= wc->status;
++	tmp.opcode		= wc->opcode;
++	tmp.vendor_err		= wc->vendor_err;
++	tmp.byte_len		= wc->byte_len;
++	tmp.ex.imm_data		= (__u32 __force) wc->ex.imm_data;
++	tmp.qp_num		= wc->qp->qp_num;
++	tmp.src_qp		= wc->src_qp;
++	tmp.wc_flags		= wc->wc_flags;
++	tmp.pkey_index		= wc->pkey_index;
++	tmp.slid		= wc->slid;
++	tmp.sl			= wc->sl;
++	tmp.dlid_path_bits	= wc->dlid_path_bits;
++	tmp.port_num		= wc->port_num;
++	tmp.reserved		= 0;
++
++	if (copy_to_user(dest, &tmp, sizeof tmp))
++		return -EFAULT;
++
++	return 0;
++}
++
+ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
+ 			  const char __user *buf, int in_len,
+ 			  int out_len)
+ {
+ 	struct ib_uverbs_poll_cq       cmd;
+-	struct ib_uverbs_poll_cq_resp *resp;
++	struct ib_uverbs_poll_cq_resp  resp;
++	u8 __user                     *header_ptr;
++	u8 __user                     *data_ptr;
+ 	struct ib_cq                  *cq;
+-	struct ib_wc                  *wc;
+-	int                            ret = 0;
+-	int                            i;
+-	int                            rsize;
++	struct ib_wc                   wc;
++	int                            ret;
+ 
+ 	if (copy_from_user(&cmd, buf, sizeof cmd))
+ 		return -EFAULT;
+ 
+-	wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
+-	if (!wc)
+-		return -ENOMEM;
+-
+-	rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
+-	resp = kmalloc(rsize, GFP_KERNEL);
+-	if (!resp) {
+-		ret = -ENOMEM;
+-		goto out_wc;
+-	}
+-
+ 	cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
+-	if (!cq) {
+-		ret = -EINVAL;
+-		goto out;
+-	}
++	if (!cq)
++		return -EINVAL;
+ 
+-	resp->count = ib_poll_cq(cq, cmd.ne, wc);
++	/* we copy a struct ib_uverbs_poll_cq_resp to user space */
++	header_ptr = (void __user *)(unsigned long) cmd.response;
++	data_ptr = header_ptr + sizeof resp;
+ 
+-	put_cq_read(cq);
++	memset(&resp, 0, sizeof resp);
++	while (resp.count < cmd.ne) {
++		ret = ib_poll_cq(cq, 1, &wc);
++		if (ret < 0)
++			goto out_put;
++		if (!ret)
++			break;
++
++		ret = copy_wc_to_user(data_ptr, &wc);
++		if (ret)
++			goto out_put;
+ 
+-	for (i = 0; i < resp->count; i++) {
+-		resp->wc[i].wr_id 	   = wc[i].wr_id;
+-		resp->wc[i].status 	   = wc[i].status;
+-		resp->wc[i].opcode 	   = wc[i].opcode;
+-		resp->wc[i].vendor_err 	   = wc[i].vendor_err;
+-		resp->wc[i].byte_len 	   = wc[i].byte_len;
+-		resp->wc[i].ex.imm_data    = (__u32 __force) wc[i].ex.imm_data;
+-		resp->wc[i].qp_num 	   = wc[i].qp->qp_num;
+-		resp->wc[i].src_qp 	   = wc[i].src_qp;
+-		resp->wc[i].wc_flags 	   = wc[i].wc_flags;
+-		resp->wc[i].pkey_index 	   = wc[i].pkey_index;
+-		resp->wc[i].slid 	   = wc[i].slid;
+-		resp->wc[i].sl 		   = wc[i].sl;
+-		resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
+-		resp->wc[i].port_num 	   = wc[i].port_num;
++		data_ptr += sizeof(struct ib_uverbs_wc);
++		++resp.count;
+ 	}
+ 
+-	if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
++	if (copy_to_user(header_ptr, &resp, sizeof resp)) {
+ 		ret = -EFAULT;
++		goto out_put;
++	}
+ 
+-out:
+-	kfree(resp);
++	ret = in_len;
+ 
+-out_wc:
+-	kfree(wc);
+-	return ret ? ret : in_len;
++out_put:
++	put_cq_read(cq);
++	return ret;
+ }
+ 
+ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
diff --git a/ima-fix-add-lsm-rule-bug.patch b/ima-fix-add-lsm-rule-bug.patch
new file mode 100644
index 0000000..ac56bcd
--- /dev/null
+++ b/ima-fix-add-lsm-rule-bug.patch
@@ -0,0 +1,62 @@
+From: Mimi Zohar <zohar at linux.vnet.ibm.com>
+Date: Mon, 3 Jan 2011 22:59:10 +0000 (-0800)
+Subject: ima: fix add LSM rule bug
+X-Git-Tag: v2.6.37~5
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=867c20265459d30a01b021a9c1e81fb4c5832aa9
+
+ima: fix add LSM rule bug
+
+If security_filter_rule_init() doesn't return a rule, then not everything
+is as fine as the return code implies.
+
+This bug only occurs when the LSM (eg. SELinux) is disabled at runtime.
+
+Adding an empty LSM rule causes ima_match_rules() to always succeed,
+ignoring any remaining rules.
+
+ default IMA TCB policy:
+  # PROC_SUPER_MAGIC
+  dont_measure fsmagic=0x9fa0
+  # SYSFS_MAGIC
+  dont_measure fsmagic=0x62656572
+  # DEBUGFS_MAGIC
+  dont_measure fsmagic=0x64626720
+  # TMPFS_MAGIC
+  dont_measure fsmagic=0x01021994
+  # SECURITYFS_MAGIC
+  dont_measure fsmagic=0x73636673
+
+  < LSM specific rule >
+  dont_measure obj_type=var_log_t
+
+  measure func=BPRM_CHECK
+  measure func=FILE_MMAP mask=MAY_EXEC
+  measure func=FILE_CHECK mask=MAY_READ uid=0
+
+Thus without the patch, with the boot parameters 'tcb selinux=0', adding
+the above 'dont_measure obj_type=var_log_t' rule to the default IMA TCB
+measurement policy, would result in nothing being measured.  The patch
+prevents the default TCB policy from being replaced.
+
+Signed-off-by: Mimi Zohar <zohar at us.ibm.com>
+Cc: James Morris <jmorris at namei.org>
+Acked-by: Serge Hallyn <serge.hallyn at canonical.com>
+Cc: David Safford <safford at watson.ibm.com>
+Cc: <stable at kernel.org>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index aef8c0a..d661afb 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -253,6 +253,8 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
+ 	result = security_filter_rule_init(entry->lsm[lsm_rule].type,
+ 					   Audit_equal, args,
+ 					   &entry->lsm[lsm_rule].rule);
++	if (!entry->lsm[lsm_rule].rule)
++		return -EINVAL;
+ 	return result;
+ }
+ 
diff --git a/install-special-mapping-skips-security-file-mmap-check.patch b/install-special-mapping-skips-security-file-mmap-check.patch
new file mode 100644
index 0000000..b53b399
--- /dev/null
+++ b/install-special-mapping-skips-security-file-mmap-check.patch
@@ -0,0 +1,107 @@
+From: Tavis Ormandy <taviso at cmpxchg8b.com>
+Date: Thu, 9 Dec 2010 14:29:42 +0000 (+0100)
+Subject: install_special_mapping skips security_file_mmap check.
+X-Git-Tag: v2.6.37-rc6~5
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=462e635e5b73ba9a4c03913b77138cd57ce4b050
+
+install_special_mapping skips security_file_mmap check.
+
+[ Trivial backport to 2.6.34 ]
+
+The install_special_mapping routine (used, for example, to setup the
+vdso) skips the security check before insert_vm_struct, allowing a local
+attacker to bypass the mmap_min_addr security restriction by limiting
+the available pages for special mappings.
+
+bprm_mm_init() also skips the check, and although I don't think this can
+be used to bypass any restrictions, I don't see any reason not to have
+the security check.
+
+  $ uname -m
+  x86_64
+  $ cat /proc/sys/vm/mmap_min_addr
+  65536
+  $ cat install_special_mapping.s
+  section .bss
+      resb BSS_SIZE
+  section .text
+      global _start
+      _start:
+          mov     eax, __NR_pause
+          int     0x80
+  $ nasm -D__NR_pause=29 -DBSS_SIZE=0xfffed000 -f elf -o install_special_mapping.o install_special_mapping.s
+  $ ld -m elf_i386 -Ttext=0x10000 -Tbss=0x11000 -o install_special_mapping install_special_mapping.o
+  $ ./install_special_mapping &
+  [1] 14303
+  $ cat /proc/14303/maps
+  0000f000-00010000 r-xp 00000000 00:00 0                                  [vdso]
+  00010000-00011000 r-xp 00001000 00:19 2453665                            /home/taviso/install_special_mapping
+  00011000-ffffe000 rwxp 00000000 00:00 0                                  [stack]
+
+It's worth noting that Red Hat are shipping with mmap_min_addr set to
+4096.
+
+Signed-off-by: Tavis Ormandy <taviso at google.com>
+Acked-by: Kees Cook <kees at ubuntu.com>
+Acked-by: Robert Swiecki <swiecki at google.com>
+[ Changed to not drop the error code - akpm ]
+Reviewed-by: James Morris <jmorris at namei.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+
+diff --git a/fs/exec.c b/fs/exec.c
+index d68c378..c62efcb 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -275,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+ 	vma->vm_flags = VM_STACK_FLAGS;
+ 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ 	INIT_LIST_HEAD(&vma->anon_vma_chain);
++
++	err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
++	if (err)
++		goto err;
++
+ 	err = insert_vm_struct(mm, vma);
+ 	if (err)
+ 		goto err;
+diff --git a/mm/mmap.c b/mm/mmap.c
+index b179abb..50a4aa0 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm,
+ 			    unsigned long addr, unsigned long len,
+ 			    unsigned long vm_flags, struct page **pages)
+ {
++	int ret;
+ 	struct vm_area_struct *vma;
+ 
+ 	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
+@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm,
+ 	vma->vm_ops = &special_mapping_vmops;
+ 	vma->vm_private_data = pages;
+ 
+-	if (unlikely(insert_vm_struct(mm, vma))) {
+-		kmem_cache_free(vm_area_cachep, vma);
+-		return -ENOMEM;
+-	}
++	ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
++	if (ret)
++		goto out;
++
++	ret = insert_vm_struct(mm, vma);
++	if (ret)
++		goto out;
+ 
+ 	mm->total_vm += len >> PAGE_SHIFT;
+ 
+ 	perf_event_mmap(vma);
+ 
+ 	return 0;
++
++out:
++	kmem_cache_free(vm_area_cachep, vma);
++	return ret;
+ }
+ 
+ static DEFINE_MUTEX(mm_all_locks_mutex);
diff --git a/kernel.spec b/kernel.spec
index cfc99f7..d6e21b4 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -918,6 +918,17 @@ Patch13925: block-check-for-proper-length-of-iov-entries-earlier-in-blk_rq_map_u
 # rhbz#643758
 Patch13926: hostap_cs-fix-sleeping-function-called-from-invalid-context.patch
 
+# CVE-2010-4346
+Patch13930: install-special-mapping-skips-security-file-mmap-check.patch
+# CVE-2010-4649
+Patch13931: ib-uverbs-handle-large-number-of-poll-entries-in-poll-cq.patch
+# CVE-2011-0006
+Patch13932: ima-fix-add-lsm-rule-bug.patch
+# CVE-2010-4648
+Patch13933: orinoco-fix-tkip-countermeasure-behaviour.patch
+# CVE-2010-4650
+Patch13934: fuse-verify-ioctl-retries.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1759,6 +1770,17 @@ ApplyPatch block-check-for-proper-length-of-iov-entries-earlier-in-blk_rq_map_us
 # rhbz#643758
 ApplyPatch hostap_cs-fix-sleeping-function-called-from-invalid-context.patch
 
+# CVE-2010-4346
+ApplyPatch install-special-mapping-skips-security-file-mmap-check.patch
+# CVE-2010-4649
+ApplyPatch ib-uverbs-handle-large-number-of-poll-entries-in-poll-cq.patch
+# CVE-2011-0006
+ApplyPatch ima-fix-add-lsm-rule-bug.patch
+# CVE-2010-4648
+ApplyPatch orinoco-fix-tkip-countermeasure-behaviour.patch
+# CVE-2010-4650
+ApplyPatch fuse-verify-ioctl-retries.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2380,6 +2402,14 @@ fi
 
 
 %changelog
+* Sat Jan 22 2011 Chuck Ebbert <cebbert at redhat.com>
+- Security updates
+  CVE-2010-4346: install_special_mapping skips security_file_mmap check
+  CVE-2010-4649: IB/uverbs: Handle large number of entries in poll CQ
+  CVE-2011-0006: ima: fix add LSM rule bug
+  CVE-2010-4648: orinoco: fix TKIP countermeasure behaviour
+  CVE-2010-4650: fuse: verify ioctl retries
+
 * Tue Jan 18 2011 Kyle McMartin <kmcmartin at redhat.com>
 - sgruszka: hostap_cs: fix sleeping function called in invalid
   context (#643758)
diff --git a/orinoco-fix-tkip-countermeasure-behaviour.patch b/orinoco-fix-tkip-countermeasure-behaviour.patch
new file mode 100644
index 0000000..f62a601
--- /dev/null
+++ b/orinoco-fix-tkip-countermeasure-behaviour.patch
@@ -0,0 +1,59 @@
+From: David Kilroy <kilroyd at googlemail.com>
+Date: Sun, 5 Dec 2010 15:43:55 +0000 (+0000)
+Subject: orinoco: fix TKIP countermeasure behaviour
+X-Git-Tag: v2.6.37-rc6~14^2~14^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=0a54917c3fc295cb61f3fb52373c173fd3b69f48
+
+orinoco: fix TKIP countermeasure behaviour
+
+Enable the port when disabling countermeasures, and disable it on
+enabling countermeasures.
+
+This bug causes the response of the system to certain attacks to be
+ineffective.
+
+It also prevents wpa_supplicant from getting scan results, as
+wpa_supplicant disables countermeasures on startup - preventing the
+hardware from scanning.
+
+wpa_supplicant works with ap_mode=2 despite this bug because the commit
+handler re-enables the port.
+
+The log tends to look like:
+
+State: DISCONNECTED -> SCANNING
+Starting AP scan for wildcard SSID
+Scan requested (ret=0) - scan timeout 5 seconds
+EAPOL: disable timer tick
+EAPOL: Supplicant port status: Unauthorized
+Scan timeout - try to get results
+Failed to get scan results
+Failed to get scan results - try scanning again
+Setting scan request: 1 sec 0 usec
+Starting AP scan for wildcard SSID
+Scan requested (ret=-1) - scan timeout 5 seconds
+Failed to initiate AP scan.
+
+Reported by: Giacomo Comes <comes at naic.edu>
+Signed-off by: David Kilroy <kilroyd at googlemail.com>
+Cc: stable at kernel.org
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+---
+
+diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
+index 93505f9..e5afabe 100644
+--- a/drivers/net/wireless/orinoco/wext.c
++++ b/drivers/net/wireless/orinoco/wext.c
+@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
+ 		 */
+ 		if (param->value) {
+ 			priv->tkip_cm_active = 1;
+-			ret = hermes_enable_port(hw, 0);
++			ret = hermes_disable_port(hw, 0);
+ 		} else {
+ 			priv->tkip_cm_active = 0;
+-			ret = hermes_disable_port(hw, 0);
++			ret = hermes_enable_port(hw, 0);
+ 		}
+ 		break;
+ 


More information about the scm-commits mailing list