All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Ivan Babrou <ivan@cloudflare.com>,
	Minchan Kim <minchan@kernel.org>, Nitin Gupta <ngupta@vflare.org>,
	Sergey Senozhatsky <senozhatsky@chromium.org>,
	Jens Axboe <axboe@kernel.dk>,
	David Hildenbrand <david@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 5.10 071/105] mm: fix unexpected zeroed page mapping with zram swap
Date: Mon, 18 Apr 2022 14:13:13 +0200	[thread overview]
Message-ID: <20220418121148.507932753@linuxfoundation.org> (raw)
In-Reply-To: <20220418121145.140991388@linuxfoundation.org>

From: Minchan Kim <minchan@kernel.org>

commit e914d8f00391520ecc4495dd0ca0124538ab7119 upstream.

Two processes under CLONE_VM cloning, user process can be corrupted by
seeing zeroed page unexpectedly.

      CPU A                        CPU B

  do_swap_page                do_swap_page
  SWP_SYNCHRONOUS_IO path     SWP_SYNCHRONOUS_IO path
  swap_readpage valid data
    swap_slot_free_notify
      delete zram entry
                              swap_readpage zeroed(invalid) data
                              pte_lock
                              map the *zero data* to userspace
                              pte_unlock
  pte_lock
  if (!pte_same)
    goto out_nomap;
  pte_unlock
  return and next refault will
  read zeroed data

The swap_slot_free_notify is bogus for CLONE_VM case since it doesn't
increase the refcount of swap slot at copy_mm so it couldn't catch up
whether it's safe or not to discard data from backing device.  In the
case, only the lock it could rely on to synchronize swap slot freeing is
page table lock.  Thus, this patch gets rid of the swap_slot_free_notify
function.  With this patch, CPU A will see correct data.

      CPU A                        CPU B

  do_swap_page                do_swap_page
  SWP_SYNCHRONOUS_IO path     SWP_SYNCHRONOUS_IO path
                              swap_readpage original data
                              pte_lock
                              map the original data
                              swap_free
                                swap_range_free
                                  bd_disk->fops->swap_slot_free_notify
  swap_readpage read zeroed data
                              pte_unlock
  pte_lock
  if (!pte_same)
    goto out_nomap;
  pte_unlock
  return
  on next refault will see mapped data by CPU B

The concern of the patch would increase memory consumption since it
could keep wasted memory with compressed form in zram as well as
uncompressed form in address space.  However, most of cases of zram uses
no readahead and do_swap_page is followed by swap_free so it will free
the compressed form from in zram quickly.

Link: https://lkml.kernel.org/r/YjTVVxIAsnKAXjTd@google.com
Fixes: 0bcac06f27d7 ("mm, swap: skip swapcache for swapin of synchronous device")
Reported-by: Ivan Babrou <ivan@cloudflare.com>
Tested-by: Ivan Babrou <ivan@cloudflare.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: David Hildenbrand <david@redhat.com>
Cc: <stable@vger.kernel.org>	[4.14+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/page_io.c |   54 ------------------------------------------------------
 1 file changed, 54 deletions(-)

--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -69,54 +69,6 @@ void end_swap_bio_write(struct bio *bio)
 	bio_put(bio);
 }
 
-static void swap_slot_free_notify(struct page *page)
-{
-	struct swap_info_struct *sis;
-	struct gendisk *disk;
-	swp_entry_t entry;
-
-	/*
-	 * There is no guarantee that the page is in swap cache - the software
-	 * suspend code (at least) uses end_swap_bio_read() against a non-
-	 * swapcache page.  So we must check PG_swapcache before proceeding with
-	 * this optimization.
-	 */
-	if (unlikely(!PageSwapCache(page)))
-		return;
-
-	sis = page_swap_info(page);
-	if (data_race(!(sis->flags & SWP_BLKDEV)))
-		return;
-
-	/*
-	 * The swap subsystem performs lazy swap slot freeing,
-	 * expecting that the page will be swapped out again.
-	 * So we can avoid an unnecessary write if the page
-	 * isn't redirtied.
-	 * This is good for real swap storage because we can
-	 * reduce unnecessary I/O and enhance wear-leveling
-	 * if an SSD is used as the as swap device.
-	 * But if in-memory swap device (eg zram) is used,
-	 * this causes a duplicated copy between uncompressed
-	 * data in VM-owned memory and compressed data in
-	 * zram-owned memory.  So let's free zram-owned memory
-	 * and make the VM-owned decompressed page *dirty*,
-	 * so the page should be swapped out somewhere again if
-	 * we again wish to reclaim it.
-	 */
-	disk = sis->bdev->bd_disk;
-	entry.val = page_private(page);
-	if (disk->fops->swap_slot_free_notify && __swap_count(entry) == 1) {
-		unsigned long offset;
-
-		offset = swp_offset(entry);
-
-		SetPageDirty(page);
-		disk->fops->swap_slot_free_notify(sis->bdev,
-				offset);
-	}
-}
-
 static void end_swap_bio_read(struct bio *bio)
 {
 	struct page *page = bio_first_page_all(bio);
@@ -132,7 +84,6 @@ static void end_swap_bio_read(struct bio
 	}
 
 	SetPageUptodate(page);
-	swap_slot_free_notify(page);
 out:
 	unlock_page(page);
 	WRITE_ONCE(bio->bi_private, NULL);
@@ -409,11 +360,6 @@ int swap_readpage(struct page *page, boo
 	if (sis->flags & SWP_SYNCHRONOUS_IO) {
 		ret = bdev_read_page(sis->bdev, swap_page_sector(page), page);
 		if (!ret) {
-			if (trylock_page(page)) {
-				swap_slot_free_notify(page);
-				unlock_page(page);
-			}
-
 			count_vm_event(PSWPIN);
 			goto out;
 		}



  parent reply	other threads:[~2022-04-18 13:18 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-18 12:12 [PATCH 5.10 000/105] 5.10.112-rc1 review Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 001/105] drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 002/105] hamradio: defer 6pack kfree after unregister_netdev Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 003/105] hamradio: remove needs_free_netdev to avoid UAF Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 004/105] cpuidle: PSCI: Move the `has_lpi` check to the beginning of the function Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 005/105] ACPI: processor idle: Check for architectural support for LPI Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 006/105] btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 007/105] drm/msm: Add missing put_task_struct() in debugfs path Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 008/105] memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 009/105] firmware: arm_scmi: Fix sorting of retrieved clock rates Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 010/105] media: rockchip/rga: do proper error checking in probe Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 011/105] SUNRPC: Fix the svc_deferred_event trace class Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 012/105] net/sched: flower: fix parsing of ethertype following VLAN header Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 013/105] veth: Ensure eth header is in skbs linear part Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 014/105] gpiolib: acpi: use correct format characters Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 015/105] net: mdio: Alphabetically sort header inclusion Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 016/105] mlxsw: i2c: Fix initialization error flow Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 017/105] net/sched: fix initialization order when updating chain 0 head Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 018/105] net: dsa: felix: suppress -EPROBE_DEFER errors Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 019/105] net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 020/105] net/sched: taprio: Check if socket flags are valid Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 021/105] cfg80211: hold bss_lock while updating nontrans_list Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 022/105] drm/msm: Fix range size vs end confusion Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 023/105] drm/msm/dsi: Use connector directly in msm_dsi_manager_connector_init() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 024/105] net/smc: Fix NULL pointer dereference in smc_pnet_find_ib() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 025/105] scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63 Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 026/105] scsi: pm80xx: Enable upper inbound, outbound queues Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 027/105] scsi: iscsi: Stop queueing during ep_disconnect Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 028/105] scsi: iscsi: Force immediate failure during shutdown Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 029/105] scsi: iscsi: Use system_unbound_wq for destroy_work Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 030/105] scsi: iscsi: Rel ref after iscsi_lookup_endpoint() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 031/105] scsi: iscsi: Fix in-kernel conn failure handling Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 032/105] scsi: iscsi: Move iscsi_ep_disconnect() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 033/105] scsi: iscsi: Fix offload conn cleanup when iscsid restarts Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 034/105] scsi: iscsi: Fix conn cleanup and stop race during iscsid restart Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 035/105] sctp: Initialize daddr on peeled off socket Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 036/105] testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu set Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 037/105] perf tools: Fix misleading add event PMU debug message Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 038/105] nfc: nci: add flush_workqueue to prevent uaf Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 039/105] cifs: potential buffer overflow in handling symlinks Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 040/105] dm mpath: only use ktime_get_ns() in historical selector Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 041/105] net: bcmgenet: Revert "Use stronger register read/writes to assure ordering" Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 042/105] drm/amd: Add USBC connector ID Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 043/105] btrfs: fix fallocate to use file_modified to update permissions consistently Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 044/105] btrfs: do not warn for free space inode in cow_file_range Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 045/105] drm/amd/display: fix audio format not updated after edid updated Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 046/105] drm/amd/display: FEC check in timing validation Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 047/105] drm/amd/display: Update VTEM Infopacket definition Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 048/105] drm/amdkfd: Fix Incorrect VMIDs passed to HWS Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 049/105] drm/amdgpu/vcn: improve vcn dpg stop procedure Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 050/105] drm/amdkfd: Check for potential null return of kmalloc_array() Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 051/105] Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 052/105] scsi: target: tcmu: Fix possible page UAF Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 053/105] scsi: lpfc: Fix queue failures when recovering from PCI parity error Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 054/105] scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024 Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 055/105] net: micrel: fix KS8851_MLL Kconfig Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 056/105] ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs Greg Kroah-Hartman
2022-04-18 12:12 ` [PATCH 5.10 057/105] gpu: ipu-v3: Fix dev_dbg frequency output Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 058/105] regulator: wm8994: Add an off-on delay for WM8994 variant Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 059/105] arm64: alternatives: mark patch_alternative() as `noinstr` Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 060/105] tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 061/105] net: axienet: setup mdio unconditionally Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 062/105] net: usb: aqc111: Fix out-of-bounds accesses in RX fixup Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 063/105] myri10ge: fix an incorrect free for skb in myri10ge_sw_tso Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 064/105] drm/amd/display: Revert FEC check in validation Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 065/105] drm/amd/display: Fix allocate_mst_payload assert on resume Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 066/105] scsi: mvsas: Add PCI ID of RocketRaid 2640 Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 067/105] scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 068/105] drivers: net: slip: fix NPD bug in sl_tx_timeout() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 069/105] perf/imx_ddr: Fix undefined behavior due to shift overflowing the constant Greg Kroah-Hartman
2022-04-18 12:13   ` Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 070/105] mm, page_alloc: fix build_zonerefs_node() Greg Kroah-Hartman
2022-04-18 12:13 ` Greg Kroah-Hartman [this message]
2022-04-18 12:13 ` [PATCH 5.10 072/105] mm: kmemleak: take a full lowmem check in kmemleak_*_phys() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 073/105] KVM: x86/mmu: Resolve nx_huge_pages when kvm.ko is loaded Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 074/105] KVM: Dont create VM debugfs files outside of the VM directory Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 075/105] memory: renesas-rpc-if: fix platform-device leak in error path Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 076/105] gcc-plugins: latent_entropy: use /dev/urandom Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 077/105] ath9k: Properly clear TX status area before reporting to mac80211 Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 078/105] ath9k: Fix usage of driver-private space in tx_info Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 079/105] btrfs: fix root ref counts in error handling in btrfs_get_root_ref Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 080/105] btrfs: mark resumed async balance as writing Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 081/105] ALSA: hda/realtek: Add quirk for Clevo PD50PNT Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 082/105] ALSA: hda/realtek: add quirk for Lenovo Thinkpad X12 speakers Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 083/105] ALSA: pcm: Test for "silence" field in struct "pcm_format_data" Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 084/105] nl80211: correctly check NL80211_ATTR_REG_ALPHA2 size Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 085/105] ipv6: fix panic when forwarding a pkt with no in6 dev Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 086/105] drm/amd/display: dont ignore alpha property on pre-multiplied mode Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 087/105] drm/amdgpu: Enable gfxoff quirk on MacBook Pro Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 088/105] genirq/affinity: Consider that CPUs on nodes can be unbalanced Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 089/105] tick/nohz: Use WARN_ON_ONCE() to prevent console saturation Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 090/105] ARM: davinci: da850-evm: Avoid NULL pointer dereference Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 091/105] dm integrity: fix memory corruption when tag_size is less than digest size Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 092/105] smp: Fix offline cpu check in flush_smp_call_function_queue() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 093/105] i2c: pasemi: Wait for write xfers to finish Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 094/105] timers: Fix warning condition in __run_timers() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 095/105] dma-direct: avoid redundant memory sync for swiotlb Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 096/105] scsi: iscsi: Fix endpoint reuse regression Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 097/105] scsi: iscsi: Fix unbound endpoint error handling Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 098/105] ax25: add refcount in ax25_dev to avoid UAF bugs Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 099/105] ax25: fix reference count leaks of ax25_dev Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 100/105] ax25: fix UAF bugs of net_device caused by rebinding operation Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 101/105] ax25: Fix refcount leaks caused by ax25_cb_del() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 102/105] ax25: fix UAF bug in ax25_send_control() Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 103/105] ax25: fix NPD bug in ax25_disconnect Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 104/105] ax25: Fix NULL pointer dereferences in ax25 timers Greg Kroah-Hartman
2022-04-18 12:13 ` [PATCH 5.10 105/105] ax25: Fix UAF bugs " Greg Kroah-Hartman
2022-04-18 20:01 ` [PATCH 5.10 000/105] 5.10.112-rc1 review Florian Fainelli
2022-04-19  0:05 ` Guenter Roeck
2022-04-19  0:08 ` Shuah Khan
2022-04-19  5:54 ` Naresh Kamboju
2022-04-19 12:04 ` Sudip Mukherjee
2022-04-19 12:21 ` Jon Hunter
2022-04-20  1:39 ` Samuel Zou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220418121148.507932753@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=axboe@kernel.dk \
    --cc=david@redhat.com \
    --cc=ivan@cloudflare.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=minchan@kernel.org \
    --cc=ngupta@vflare.org \
    --cc=senozhatsky@chromium.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.