All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild@lists.01.org, Theodore Ts'o <tytso@mit.edu>,
	Ye Bin <yebin10@huawei.com>
Cc: lkp@intel.com, kbuild-all@lists.01.org,
	Ext4 Developers List <linux-ext4@vger.kernel.org>,
	Theodore Ts'o <tytso@mit.edu>
Subject: Re: [PATCH] ext4: possible use-after-free when remounting r/o a mmp-protected file system
Date: Sat, 3 Jul 2021 15:57:43 +0300	[thread overview]
Message-ID: <202107030757.qUhYYCXI-lkp@intel.com> (raw)
In-Reply-To: <e525c0bf7b18da426bb3d3dd63830a3f85218a9e.1625244710.git.tytso@mit.edu>

Hi Theodore,

url:    https://github.com/0day-ci/linux/commits/Theodore-Ts-o/ext4-possible-use-after-free-when-remounting-r-o-a-mmp-protected-file-system/20210703-005856
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: i386-randconfig-m021-20210702 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

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

smatch warnings:
fs/ext4/mmp.c:252 kmmpd() error: uninitialized symbol 'retval'.

vim +/retval +252 fs/ext4/mmp.c

c5e06d101aaf72 Johann Lombardi   2011-05-24  128  static int kmmpd(void *data)
c5e06d101aaf72 Johann Lombardi   2011-05-24  129  {
618f003199c618 Pavel Skripkin    2021-04-30  130  	struct super_block *sb = (struct super_block *) data;
c5e06d101aaf72 Johann Lombardi   2011-05-24  131  	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
618f003199c618 Pavel Skripkin    2021-04-30  132  	struct buffer_head *bh = EXT4_SB(sb)->s_mmp_bh;
c5e06d101aaf72 Johann Lombardi   2011-05-24  133  	struct mmp_struct *mmp;
c5e06d101aaf72 Johann Lombardi   2011-05-24  134  	ext4_fsblk_t mmp_block;
c5e06d101aaf72 Johann Lombardi   2011-05-24  135  	u32 seq = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  136  	unsigned long failed_writes = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  137  	int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  138  	unsigned mmp_check_interval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  139  	unsigned long last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  140  	unsigned long diff;
c5e06d101aaf72 Johann Lombardi   2011-05-24  141  	int retval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  142  
c5e06d101aaf72 Johann Lombardi   2011-05-24  143  	mmp_block = le64_to_cpu(es->s_mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  144  	mmp = (struct mmp_struct *)(bh->b_data);
af123b3718592a Arnd Bergmann     2018-07-29  145  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  146  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  147  	 * Start with the higher mmp_check_interval and reduce it if
c5e06d101aaf72 Johann Lombardi   2011-05-24  148  	 * the MMP block is being updated on time.
c5e06d101aaf72 Johann Lombardi   2011-05-24  149  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  150  	mmp_check_interval = max(EXT4_MMP_CHECK_MULT * mmp_update_interval,
c5e06d101aaf72 Johann Lombardi   2011-05-24  151  				 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  152  	mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
14c9ca0583eee8 Andreas Dilger    2020-01-26  153  	BUILD_BUG_ON(sizeof(mmp->mmp_bdevname) < BDEVNAME_SIZE);
c5e06d101aaf72 Johann Lombardi   2011-05-24  154  	bdevname(bh->b_bdev, mmp->mmp_bdevname);
c5e06d101aaf72 Johann Lombardi   2011-05-24  155  
215fc6af739d2d Nikitas Angelinas 2011-10-18  156  	memcpy(mmp->mmp_nodename, init_utsname()->nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  157  	       sizeof(mmp->mmp_nodename));
c5e06d101aaf72 Johann Lombardi   2011-05-24  158  
c5e06d101aaf72 Johann Lombardi   2011-05-24  159  	while (!kthread_should_stop()) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  160  		if (!(le32_to_cpu(es->s_feature_incompat) &
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  161  		    EXT4_FEATURE_INCOMPAT_MMP)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  162  			ext4_warning(sb, "kmmpd being stopped since MMP feature"
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  163  				     " has been disabled.");
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  164  			goto wait_to_exit;

Smatch complains about this goto.

37b4aa9eef5b3f Theodore Ts'o     2021-07-02  165  		}
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  166  		if (sb_rdonly(sb)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  167  			schedule_timeout_interruptible(HZ);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  168  			continue;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  169  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  170  		if (++seq > EXT4_MMP_SEQ_MAX)
c5e06d101aaf72 Johann Lombardi   2011-05-24  171  			seq = 1;
c5e06d101aaf72 Johann Lombardi   2011-05-24  172  
c5e06d101aaf72 Johann Lombardi   2011-05-24  173  		mmp->mmp_seq = cpu_to_le32(seq);
af123b3718592a Arnd Bergmann     2018-07-29  174  		mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  175  		last_update_time = jiffies;
c5e06d101aaf72 Johann Lombardi   2011-05-24  176  
5c359a47e7d999 Darrick J. Wong   2012-04-29  177  		retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  178  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  179  		 * Don't spew too many error messages. Print one every
c5e06d101aaf72 Johann Lombardi   2011-05-24  180  		 * (s_mmp_update_interval * 60) seconds.
c5e06d101aaf72 Johann Lombardi   2011-05-24  181  		 */
bdfc230f33a9da Nikitas Angelinas 2011-10-18  182  		if (retval) {
878520ac45f9f6 Theodore Ts'o     2019-11-19  183  			if ((failed_writes % 60) == 0) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  184  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  185  					       "Error writing to MMP block");
878520ac45f9f6 Theodore Ts'o     2019-11-19  186  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  187  			failed_writes++;
c5e06d101aaf72 Johann Lombardi   2011-05-24  188  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  189  
c5e06d101aaf72 Johann Lombardi   2011-05-24  190  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  191  		if (diff < mmp_update_interval * HZ)
c5e06d101aaf72 Johann Lombardi   2011-05-24  192  			schedule_timeout_interruptible(mmp_update_interval *
c5e06d101aaf72 Johann Lombardi   2011-05-24  193  						       HZ - diff);
c5e06d101aaf72 Johann Lombardi   2011-05-24  194  
c5e06d101aaf72 Johann Lombardi   2011-05-24  195  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  196  		 * We need to make sure that more than mmp_check_interval
c5e06d101aaf72 Johann Lombardi   2011-05-24  197  		 * seconds have not passed since writing. If that has happened
c5e06d101aaf72 Johann Lombardi   2011-05-24  198  		 * we need to check if the MMP block is as we left it.
c5e06d101aaf72 Johann Lombardi   2011-05-24  199  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  200  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  201  		if (diff > mmp_check_interval * HZ) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  202  			struct buffer_head *bh_check = NULL;
c5e06d101aaf72 Johann Lombardi   2011-05-24  203  			struct mmp_struct *mmp_check;
c5e06d101aaf72 Johann Lombardi   2011-05-24  204  
c5e06d101aaf72 Johann Lombardi   2011-05-24  205  			retval = read_mmp_block(sb, &bh_check, mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  206  			if (retval) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  207  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  208  					       "error reading MMP data: %d",
c5e06d101aaf72 Johann Lombardi   2011-05-24  209  					       retval);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  210  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  211  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  212  
c5e06d101aaf72 Johann Lombardi   2011-05-24  213  			mmp_check = (struct mmp_struct *)(bh_check->b_data);
c5e06d101aaf72 Johann Lombardi   2011-05-24  214  			if (mmp->mmp_seq != mmp_check->mmp_seq ||
c5e06d101aaf72 Johann Lombardi   2011-05-24  215  			    memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  216  				   sizeof(mmp->mmp_nodename))) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  217  				dump_mmp_msg(sb, mmp_check,
c5e06d101aaf72 Johann Lombardi   2011-05-24  218  					     "Error while updating MMP info. "
c5e06d101aaf72 Johann Lombardi   2011-05-24  219  					     "The filesystem seems to have been"
c5e06d101aaf72 Johann Lombardi   2011-05-24  220  					     " multiply mounted.");
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  221  				ext4_error_err(sb, EBUSY, "abort");
0304688676bdfc vikram.jadhav07   2016-03-13  222  				put_bh(bh_check);
0304688676bdfc vikram.jadhav07   2016-03-13  223  				retval = -EBUSY;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  224  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  225  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  226  			put_bh(bh_check);
c5e06d101aaf72 Johann Lombardi   2011-05-24  227  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  228  
c5e06d101aaf72 Johann Lombardi   2011-05-24  229  		 /*
c5e06d101aaf72 Johann Lombardi   2011-05-24  230  		 * Adjust the mmp_check_interval depending on how much time
c5e06d101aaf72 Johann Lombardi   2011-05-24  231  		 * it took for the MMP block to be written.
c5e06d101aaf72 Johann Lombardi   2011-05-24  232  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  233  		mmp_check_interval = max(min(EXT4_MMP_CHECK_MULT * diff / HZ,
c5e06d101aaf72 Johann Lombardi   2011-05-24  234  					     EXT4_MMP_MAX_CHECK_INTERVAL),
c5e06d101aaf72 Johann Lombardi   2011-05-24  235  					 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  236  		mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  237  	}
c5e06d101aaf72 Johann Lombardi   2011-05-24  238  
c5e06d101aaf72 Johann Lombardi   2011-05-24  239  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  240  	 * Unmount seems to be clean.
c5e06d101aaf72 Johann Lombardi   2011-05-24  241  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  242  	mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN);
af123b3718592a Arnd Bergmann     2018-07-29  243  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  244  
5c359a47e7d999 Darrick J. Wong   2012-04-29  245  	retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  246  
0304688676bdfc vikram.jadhav07   2016-03-13  247  exit_thread:
c5e06d101aaf72 Johann Lombardi   2011-05-24  248  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  249  wait_to_exit:
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  250  	while (!kthread_should_stop())
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  251  		schedule();
37b4aa9eef5b3f Theodore Ts'o     2021-07-02 @252  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  253  

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


WARNING: multiple messages have this Message-ID (diff)
From: kernel test robot <lkp@intel.com>
To: kbuild@lists.01.org
Subject: Re: [PATCH] ext4: possible use-after-free when remounting r/o a mmp-protected file system
Date: Sat, 03 Jul 2021 07:52:27 +0800	[thread overview]
Message-ID: <202107030757.qUhYYCXI-lkp@intel.com> (raw)

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

CC: kbuild-all(a)lists.01.org
In-Reply-To: <e525c0bf7b18da426bb3d3dd63830a3f85218a9e.1625244710.git.tytso@mit.edu>
References: <e525c0bf7b18da426bb3d3dd63830a3f85218a9e.1625244710.git.tytso(a)mit.edu>
TO: "Theodore Ts'o" <tytso@mit.edu>
TO: Ye Bin <yebin10@huawei.com>
CC: Ext4 Developers List <linux-ext4@vger.kernel.org>
CC: "Theodore Ts'o" <tytso@mit.edu>

Hi Theodore,

I love your patch! Perhaps something to improve:

[auto build test WARNING on ext4/dev]
[also build test WARNING on next-20210701]
[cannot apply to v5.13]
[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/Theodore-Ts-o/ext4-possible-use-after-free-when-remounting-r-o-a-mmp-protected-file-system/20210703-005856
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
:::::: branch date: 7 hours ago
:::::: commit date: 7 hours ago
config: i386-randconfig-m021-20210702 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

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

smatch warnings:
fs/ext4/mmp.c:252 kmmpd() error: uninitialized symbol 'retval'.

vim +/retval +252 fs/ext4/mmp.c

c5e06d101aaf72 Johann Lombardi   2011-05-24  124  
c5e06d101aaf72 Johann Lombardi   2011-05-24  125  /*
c5e06d101aaf72 Johann Lombardi   2011-05-24  126   * kmmpd will update the MMP sequence every s_mmp_update_interval seconds
c5e06d101aaf72 Johann Lombardi   2011-05-24  127   */
c5e06d101aaf72 Johann Lombardi   2011-05-24  128  static int kmmpd(void *data)
c5e06d101aaf72 Johann Lombardi   2011-05-24  129  {
618f003199c618 Pavel Skripkin    2021-04-30  130  	struct super_block *sb = (struct super_block *) data;
c5e06d101aaf72 Johann Lombardi   2011-05-24  131  	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
618f003199c618 Pavel Skripkin    2021-04-30  132  	struct buffer_head *bh = EXT4_SB(sb)->s_mmp_bh;
c5e06d101aaf72 Johann Lombardi   2011-05-24  133  	struct mmp_struct *mmp;
c5e06d101aaf72 Johann Lombardi   2011-05-24  134  	ext4_fsblk_t mmp_block;
c5e06d101aaf72 Johann Lombardi   2011-05-24  135  	u32 seq = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  136  	unsigned long failed_writes = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  137  	int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  138  	unsigned mmp_check_interval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  139  	unsigned long last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  140  	unsigned long diff;
c5e06d101aaf72 Johann Lombardi   2011-05-24  141  	int retval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  142  
c5e06d101aaf72 Johann Lombardi   2011-05-24  143  	mmp_block = le64_to_cpu(es->s_mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  144  	mmp = (struct mmp_struct *)(bh->b_data);
af123b3718592a Arnd Bergmann     2018-07-29  145  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  146  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  147  	 * Start with the higher mmp_check_interval and reduce it if
c5e06d101aaf72 Johann Lombardi   2011-05-24  148  	 * the MMP block is being updated on time.
c5e06d101aaf72 Johann Lombardi   2011-05-24  149  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  150  	mmp_check_interval = max(EXT4_MMP_CHECK_MULT * mmp_update_interval,
c5e06d101aaf72 Johann Lombardi   2011-05-24  151  				 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  152  	mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
14c9ca0583eee8 Andreas Dilger    2020-01-26  153  	BUILD_BUG_ON(sizeof(mmp->mmp_bdevname) < BDEVNAME_SIZE);
c5e06d101aaf72 Johann Lombardi   2011-05-24  154  	bdevname(bh->b_bdev, mmp->mmp_bdevname);
c5e06d101aaf72 Johann Lombardi   2011-05-24  155  
215fc6af739d2d Nikitas Angelinas 2011-10-18  156  	memcpy(mmp->mmp_nodename, init_utsname()->nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  157  	       sizeof(mmp->mmp_nodename));
c5e06d101aaf72 Johann Lombardi   2011-05-24  158  
c5e06d101aaf72 Johann Lombardi   2011-05-24  159  	while (!kthread_should_stop()) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  160  		if (!(le32_to_cpu(es->s_feature_incompat) &
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  161  		    EXT4_FEATURE_INCOMPAT_MMP)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  162  			ext4_warning(sb, "kmmpd being stopped since MMP feature"
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  163  				     " has been disabled.");
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  164  			goto wait_to_exit;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  165  		}
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  166  		if (sb_rdonly(sb)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  167  			schedule_timeout_interruptible(HZ);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  168  			continue;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  169  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  170  		if (++seq > EXT4_MMP_SEQ_MAX)
c5e06d101aaf72 Johann Lombardi   2011-05-24  171  			seq = 1;
c5e06d101aaf72 Johann Lombardi   2011-05-24  172  
c5e06d101aaf72 Johann Lombardi   2011-05-24  173  		mmp->mmp_seq = cpu_to_le32(seq);
af123b3718592a Arnd Bergmann     2018-07-29  174  		mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  175  		last_update_time = jiffies;
c5e06d101aaf72 Johann Lombardi   2011-05-24  176  
5c359a47e7d999 Darrick J. Wong   2012-04-29  177  		retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  178  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  179  		 * Don't spew too many error messages. Print one every
c5e06d101aaf72 Johann Lombardi   2011-05-24  180  		 * (s_mmp_update_interval * 60) seconds.
c5e06d101aaf72 Johann Lombardi   2011-05-24  181  		 */
bdfc230f33a9da Nikitas Angelinas 2011-10-18  182  		if (retval) {
878520ac45f9f6 Theodore Ts'o     2019-11-19  183  			if ((failed_writes % 60) == 0) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  184  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  185  					       "Error writing to MMP block");
878520ac45f9f6 Theodore Ts'o     2019-11-19  186  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  187  			failed_writes++;
c5e06d101aaf72 Johann Lombardi   2011-05-24  188  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  189  
c5e06d101aaf72 Johann Lombardi   2011-05-24  190  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  191  		if (diff < mmp_update_interval * HZ)
c5e06d101aaf72 Johann Lombardi   2011-05-24  192  			schedule_timeout_interruptible(mmp_update_interval *
c5e06d101aaf72 Johann Lombardi   2011-05-24  193  						       HZ - diff);
c5e06d101aaf72 Johann Lombardi   2011-05-24  194  
c5e06d101aaf72 Johann Lombardi   2011-05-24  195  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  196  		 * We need to make sure that more than mmp_check_interval
c5e06d101aaf72 Johann Lombardi   2011-05-24  197  		 * seconds have not passed since writing. If that has happened
c5e06d101aaf72 Johann Lombardi   2011-05-24  198  		 * we need to check if the MMP block is as we left it.
c5e06d101aaf72 Johann Lombardi   2011-05-24  199  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  200  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  201  		if (diff > mmp_check_interval * HZ) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  202  			struct buffer_head *bh_check = NULL;
c5e06d101aaf72 Johann Lombardi   2011-05-24  203  			struct mmp_struct *mmp_check;
c5e06d101aaf72 Johann Lombardi   2011-05-24  204  
c5e06d101aaf72 Johann Lombardi   2011-05-24  205  			retval = read_mmp_block(sb, &bh_check, mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  206  			if (retval) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  207  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  208  					       "error reading MMP data: %d",
c5e06d101aaf72 Johann Lombardi   2011-05-24  209  					       retval);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  210  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  211  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  212  
c5e06d101aaf72 Johann Lombardi   2011-05-24  213  			mmp_check = (struct mmp_struct *)(bh_check->b_data);
c5e06d101aaf72 Johann Lombardi   2011-05-24  214  			if (mmp->mmp_seq != mmp_check->mmp_seq ||
c5e06d101aaf72 Johann Lombardi   2011-05-24  215  			    memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  216  				   sizeof(mmp->mmp_nodename))) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  217  				dump_mmp_msg(sb, mmp_check,
c5e06d101aaf72 Johann Lombardi   2011-05-24  218  					     "Error while updating MMP info. "
c5e06d101aaf72 Johann Lombardi   2011-05-24  219  					     "The filesystem seems to have been"
c5e06d101aaf72 Johann Lombardi   2011-05-24  220  					     " multiply mounted.");
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  221  				ext4_error_err(sb, EBUSY, "abort");
0304688676bdfc vikram.jadhav07   2016-03-13  222  				put_bh(bh_check);
0304688676bdfc vikram.jadhav07   2016-03-13  223  				retval = -EBUSY;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  224  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  225  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  226  			put_bh(bh_check);
c5e06d101aaf72 Johann Lombardi   2011-05-24  227  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  228  
c5e06d101aaf72 Johann Lombardi   2011-05-24  229  		 /*
c5e06d101aaf72 Johann Lombardi   2011-05-24  230  		 * Adjust the mmp_check_interval depending on how much time
c5e06d101aaf72 Johann Lombardi   2011-05-24  231  		 * it took for the MMP block to be written.
c5e06d101aaf72 Johann Lombardi   2011-05-24  232  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  233  		mmp_check_interval = max(min(EXT4_MMP_CHECK_MULT * diff / HZ,
c5e06d101aaf72 Johann Lombardi   2011-05-24  234  					     EXT4_MMP_MAX_CHECK_INTERVAL),
c5e06d101aaf72 Johann Lombardi   2011-05-24  235  					 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  236  		mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  237  	}
c5e06d101aaf72 Johann Lombardi   2011-05-24  238  
c5e06d101aaf72 Johann Lombardi   2011-05-24  239  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  240  	 * Unmount seems to be clean.
c5e06d101aaf72 Johann Lombardi   2011-05-24  241  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  242  	mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN);
af123b3718592a Arnd Bergmann     2018-07-29  243  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  244  
5c359a47e7d999 Darrick J. Wong   2012-04-29  245  	retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  246  
0304688676bdfc vikram.jadhav07   2016-03-13  247  exit_thread:
c5e06d101aaf72 Johann Lombardi   2011-05-24  248  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  249  wait_to_exit:
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  250  	while (!kthread_should_stop())
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  251  		schedule();
37b4aa9eef5b3f Theodore Ts'o     2021-07-02 @252  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  253  

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

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

WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild-all@lists.01.org
Subject: Re: [PATCH] ext4: possible use-after-free when remounting r/o a mmp-protected file system
Date: Sat, 03 Jul 2021 15:57:43 +0300	[thread overview]
Message-ID: <202107030757.qUhYYCXI-lkp@intel.com> (raw)
In-Reply-To: <e525c0bf7b18da426bb3d3dd63830a3f85218a9e.1625244710.git.tytso@mit.edu>

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

Hi Theodore,

url:    https://github.com/0day-ci/linux/commits/Theodore-Ts-o/ext4-possible-use-after-free-when-remounting-r-o-a-mmp-protected-file-system/20210703-005856
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
config: i386-randconfig-m021-20210702 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

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

smatch warnings:
fs/ext4/mmp.c:252 kmmpd() error: uninitialized symbol 'retval'.

vim +/retval +252 fs/ext4/mmp.c

c5e06d101aaf72 Johann Lombardi   2011-05-24  128  static int kmmpd(void *data)
c5e06d101aaf72 Johann Lombardi   2011-05-24  129  {
618f003199c618 Pavel Skripkin    2021-04-30  130  	struct super_block *sb = (struct super_block *) data;
c5e06d101aaf72 Johann Lombardi   2011-05-24  131  	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
618f003199c618 Pavel Skripkin    2021-04-30  132  	struct buffer_head *bh = EXT4_SB(sb)->s_mmp_bh;
c5e06d101aaf72 Johann Lombardi   2011-05-24  133  	struct mmp_struct *mmp;
c5e06d101aaf72 Johann Lombardi   2011-05-24  134  	ext4_fsblk_t mmp_block;
c5e06d101aaf72 Johann Lombardi   2011-05-24  135  	u32 seq = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  136  	unsigned long failed_writes = 0;
c5e06d101aaf72 Johann Lombardi   2011-05-24  137  	int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  138  	unsigned mmp_check_interval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  139  	unsigned long last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  140  	unsigned long diff;
c5e06d101aaf72 Johann Lombardi   2011-05-24  141  	int retval;
c5e06d101aaf72 Johann Lombardi   2011-05-24  142  
c5e06d101aaf72 Johann Lombardi   2011-05-24  143  	mmp_block = le64_to_cpu(es->s_mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  144  	mmp = (struct mmp_struct *)(bh->b_data);
af123b3718592a Arnd Bergmann     2018-07-29  145  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  146  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  147  	 * Start with the higher mmp_check_interval and reduce it if
c5e06d101aaf72 Johann Lombardi   2011-05-24  148  	 * the MMP block is being updated on time.
c5e06d101aaf72 Johann Lombardi   2011-05-24  149  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  150  	mmp_check_interval = max(EXT4_MMP_CHECK_MULT * mmp_update_interval,
c5e06d101aaf72 Johann Lombardi   2011-05-24  151  				 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  152  	mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
14c9ca0583eee8 Andreas Dilger    2020-01-26  153  	BUILD_BUG_ON(sizeof(mmp->mmp_bdevname) < BDEVNAME_SIZE);
c5e06d101aaf72 Johann Lombardi   2011-05-24  154  	bdevname(bh->b_bdev, mmp->mmp_bdevname);
c5e06d101aaf72 Johann Lombardi   2011-05-24  155  
215fc6af739d2d Nikitas Angelinas 2011-10-18  156  	memcpy(mmp->mmp_nodename, init_utsname()->nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  157  	       sizeof(mmp->mmp_nodename));
c5e06d101aaf72 Johann Lombardi   2011-05-24  158  
c5e06d101aaf72 Johann Lombardi   2011-05-24  159  	while (!kthread_should_stop()) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  160  		if (!(le32_to_cpu(es->s_feature_incompat) &
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  161  		    EXT4_FEATURE_INCOMPAT_MMP)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  162  			ext4_warning(sb, "kmmpd being stopped since MMP feature"
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  163  				     " has been disabled.");
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  164  			goto wait_to_exit;

Smatch complains about this goto.

37b4aa9eef5b3f Theodore Ts'o     2021-07-02  165  		}
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  166  		if (sb_rdonly(sb)) {
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  167  			schedule_timeout_interruptible(HZ);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  168  			continue;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  169  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  170  		if (++seq > EXT4_MMP_SEQ_MAX)
c5e06d101aaf72 Johann Lombardi   2011-05-24  171  			seq = 1;
c5e06d101aaf72 Johann Lombardi   2011-05-24  172  
c5e06d101aaf72 Johann Lombardi   2011-05-24  173  		mmp->mmp_seq = cpu_to_le32(seq);
af123b3718592a Arnd Bergmann     2018-07-29  174  		mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  175  		last_update_time = jiffies;
c5e06d101aaf72 Johann Lombardi   2011-05-24  176  
5c359a47e7d999 Darrick J. Wong   2012-04-29  177  		retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  178  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  179  		 * Don't spew too many error messages. Print one every
c5e06d101aaf72 Johann Lombardi   2011-05-24  180  		 * (s_mmp_update_interval * 60) seconds.
c5e06d101aaf72 Johann Lombardi   2011-05-24  181  		 */
bdfc230f33a9da Nikitas Angelinas 2011-10-18  182  		if (retval) {
878520ac45f9f6 Theodore Ts'o     2019-11-19  183  			if ((failed_writes % 60) == 0) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  184  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  185  					       "Error writing to MMP block");
878520ac45f9f6 Theodore Ts'o     2019-11-19  186  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  187  			failed_writes++;
c5e06d101aaf72 Johann Lombardi   2011-05-24  188  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  189  
c5e06d101aaf72 Johann Lombardi   2011-05-24  190  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  191  		if (diff < mmp_update_interval * HZ)
c5e06d101aaf72 Johann Lombardi   2011-05-24  192  			schedule_timeout_interruptible(mmp_update_interval *
c5e06d101aaf72 Johann Lombardi   2011-05-24  193  						       HZ - diff);
c5e06d101aaf72 Johann Lombardi   2011-05-24  194  
c5e06d101aaf72 Johann Lombardi   2011-05-24  195  		/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  196  		 * We need to make sure that more than mmp_check_interval
c5e06d101aaf72 Johann Lombardi   2011-05-24  197  		 * seconds have not passed since writing. If that has happened
c5e06d101aaf72 Johann Lombardi   2011-05-24  198  		 * we need to check if the MMP block is as we left it.
c5e06d101aaf72 Johann Lombardi   2011-05-24  199  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  200  		diff = jiffies - last_update_time;
c5e06d101aaf72 Johann Lombardi   2011-05-24  201  		if (diff > mmp_check_interval * HZ) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  202  			struct buffer_head *bh_check = NULL;
c5e06d101aaf72 Johann Lombardi   2011-05-24  203  			struct mmp_struct *mmp_check;
c5e06d101aaf72 Johann Lombardi   2011-05-24  204  
c5e06d101aaf72 Johann Lombardi   2011-05-24  205  			retval = read_mmp_block(sb, &bh_check, mmp_block);
c5e06d101aaf72 Johann Lombardi   2011-05-24  206  			if (retval) {
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  207  				ext4_error_err(sb, -retval,
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  208  					       "error reading MMP data: %d",
c5e06d101aaf72 Johann Lombardi   2011-05-24  209  					       retval);
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  210  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  211  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  212  
c5e06d101aaf72 Johann Lombardi   2011-05-24  213  			mmp_check = (struct mmp_struct *)(bh_check->b_data);
c5e06d101aaf72 Johann Lombardi   2011-05-24  214  			if (mmp->mmp_seq != mmp_check->mmp_seq ||
c5e06d101aaf72 Johann Lombardi   2011-05-24  215  			    memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename,
c5e06d101aaf72 Johann Lombardi   2011-05-24  216  				   sizeof(mmp->mmp_nodename))) {
c5e06d101aaf72 Johann Lombardi   2011-05-24  217  				dump_mmp_msg(sb, mmp_check,
c5e06d101aaf72 Johann Lombardi   2011-05-24  218  					     "Error while updating MMP info. "
c5e06d101aaf72 Johann Lombardi   2011-05-24  219  					     "The filesystem seems to have been"
c5e06d101aaf72 Johann Lombardi   2011-05-24  220  					     " multiply mounted.");
54d3adbc29f0c7 Theodore Ts'o     2020-03-28  221  				ext4_error_err(sb, EBUSY, "abort");
0304688676bdfc vikram.jadhav07   2016-03-13  222  				put_bh(bh_check);
0304688676bdfc vikram.jadhav07   2016-03-13  223  				retval = -EBUSY;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  224  				goto wait_to_exit;
c5e06d101aaf72 Johann Lombardi   2011-05-24  225  			}
c5e06d101aaf72 Johann Lombardi   2011-05-24  226  			put_bh(bh_check);
c5e06d101aaf72 Johann Lombardi   2011-05-24  227  		}
c5e06d101aaf72 Johann Lombardi   2011-05-24  228  
c5e06d101aaf72 Johann Lombardi   2011-05-24  229  		 /*
c5e06d101aaf72 Johann Lombardi   2011-05-24  230  		 * Adjust the mmp_check_interval depending on how much time
c5e06d101aaf72 Johann Lombardi   2011-05-24  231  		 * it took for the MMP block to be written.
c5e06d101aaf72 Johann Lombardi   2011-05-24  232  		 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  233  		mmp_check_interval = max(min(EXT4_MMP_CHECK_MULT * diff / HZ,
c5e06d101aaf72 Johann Lombardi   2011-05-24  234  					     EXT4_MMP_MAX_CHECK_INTERVAL),
c5e06d101aaf72 Johann Lombardi   2011-05-24  235  					 EXT4_MMP_MIN_CHECK_INTERVAL);
c5e06d101aaf72 Johann Lombardi   2011-05-24  236  		mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
c5e06d101aaf72 Johann Lombardi   2011-05-24  237  	}
c5e06d101aaf72 Johann Lombardi   2011-05-24  238  
c5e06d101aaf72 Johann Lombardi   2011-05-24  239  	/*
c5e06d101aaf72 Johann Lombardi   2011-05-24  240  	 * Unmount seems to be clean.
c5e06d101aaf72 Johann Lombardi   2011-05-24  241  	 */
c5e06d101aaf72 Johann Lombardi   2011-05-24  242  	mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN);
af123b3718592a Arnd Bergmann     2018-07-29  243  	mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds());
c5e06d101aaf72 Johann Lombardi   2011-05-24  244  
5c359a47e7d999 Darrick J. Wong   2012-04-29  245  	retval = write_mmp_block(sb, bh);
c5e06d101aaf72 Johann Lombardi   2011-05-24  246  
0304688676bdfc vikram.jadhav07   2016-03-13  247  exit_thread:
c5e06d101aaf72 Johann Lombardi   2011-05-24  248  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  249  wait_to_exit:
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  250  	while (!kthread_should_stop())
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  251  		schedule();
37b4aa9eef5b3f Theodore Ts'o     2021-07-02 @252  	return retval;
37b4aa9eef5b3f Theodore Ts'o     2021-07-02  253  

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

       reply	other threads:[~2021-07-03 12:58 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-02 23:52 kernel test robot [this message]
2021-07-03 12:57 ` [PATCH] ext4: possible use-after-free when remounting r/o a mmp-protected file system Dan Carpenter
2021-07-03 12:57 ` Dan Carpenter
  -- strict thread matches above, loose matches on Subject: below --
2021-07-02 20:49 kernel test robot
2021-06-29 14:36 [PATCH 0/2] Fix use-after-free about sbi->s_mmp_tsk Ye Bin
2021-06-29 14:36 ` [PATCH 1/2] ext4: " Ye Bin
2021-07-05 11:15   ` Jan Kara
2021-07-05 20:35     ` Theodore Ts'o
2021-07-06 11:11       ` Jan Kara
2021-07-06 16:03         ` Theodore Ts'o
2021-07-06 17:12           ` [PATCH -v3] ext4: fix possible UAF when remounting r/o a mmp-protected file system Theodore Ts'o
2021-07-06 19:49             ` Jan Kara
2021-07-07  0:24               ` [PATCH -v4] " Theodore Ts'o
2021-07-07  9:30                 ` Jan Kara
2021-06-29 14:36 ` [PATCH 2/2] ext4: Fix potential uas-after-free about sbi->s_mmp_tsk when kmmpd kthread exit before set sbi->s_mmp_tsk Ye Bin
2021-07-05 10:52   ` Jan Kara
2021-07-06  0:44   ` Andreas Dilger
2021-07-02 16:57 ` [PATCH] ext4: possible use-after-free when remounting r/o a mmp-protected file system Theodore Ts'o
2021-07-02 21:36   ` kernel test robot
2021-07-02 21:36     ` kernel test robot

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=202107030757.qUhYYCXI-lkp@intel.com \
    --to=dan.carpenter@oracle.com \
    --cc=kbuild-all@lists.01.org \
    --cc=kbuild@lists.01.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=tytso@mit.edu \
    --cc=yebin10@huawei.com \
    /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.