public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Colin Slater <hoho@binbash.net>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: linux-kernel@vger.kernel.org, davej@suse.de
Subject: Re: [PATCH] Various suser() -> capable() chang
Date: 27 Apr 2002 19:16:42 -0400	[thread overview]
Message-ID: <1019949402.7399.3101.camel@neptune> (raw)
In-Reply-To: <E171XNI-0000Ji-00@the-village.bc.nu>


[-- Attachment #1.1: Type: text/plain, Size: 1133 bytes --]

On Sat, 2002-04-27 at 14:56, Alan Cox wrote:
> >  	case IDAPASSTHRU:
> > -		if (!suser()) return -EPERM;
> > +		if (!capable(CAP_SYS_ADMIN)) return -EPERM;
> 
> The cpqarray ones should be CAP_SYS_RAWIO
> 
> > diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
> > --- a/drivers/scsi/cpqfcTSinit.c	Fri Apr 26 18:34:23 2002
> > +++ b/drivers/scsi/cpqfcTSinit.c	Fri Apr 26 18:34:23 2002
> > @@ -532,7 +532,7 @@
> > =20
> >  	// must be super user to send stuff directly to the
> >  	// controller and/or physical drives...
> > -	if( !suser() )
> > +	if( !capable(CAP_SYS_ADMIN) )
> 
> Also RAWIO
> 
> 
> Basically - stuff giving raw hardware access sohuld be CAP_SYS_RAWIO, the
> others CAP_SYS_ADMIN is a good general case, but as you change then check
> its appropriate

I figured that it would be functionaly equivilent and didn't pay mutch
more attention to the issue. I've gone through it all again, and changed
alot of them to CAP_SYS_TTY_CONFIG and CAP_RAW_IO. New patch attached.

-- 
-----
GPG Key 0x626FD58E; wwwkeys.pgp.net
6788 94B7 A407 A1D4 1B05  2559 FD52 D2D0 626F D58E

[-- Attachment #1.2: suser3.patch --]
[-- Type: text/plain, Size: 14893 bytes --]

diff -Nru a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
--- a/arch/i386/kernel/mtrr.c	Sat Apr 27 19:14:55 2002
+++ b/arch/i386/kernel/mtrr.c	Sat Apr 27 19:14:55 2002
@@ -1659,7 +1659,7 @@
     char *ptr;
     char line[LINE_SIZE];
 
-    if ( !suser () ) return -EPERM;
+    if ( !capable(CAP_SYS_ADMIN)) return -EPERM;
     /*  Can't seek (pwrite) on this device  */
     if (ppos != &file->f_pos) return -ESPIPE;
     memset (line, 0, LINE_SIZE);
@@ -1727,28 +1727,28 @@
       default:
 	return -ENOIOCTLCMD;
       case MTRRIOC_ADD_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( ! capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 0);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_SET_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_add (sentry.base, sentry.size, sentry.type, 0);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_DEL_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_file_del (sentry.base, sentry.size, file, 0);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_KILL_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_del (-1, sentry.base, sentry.size);
@@ -1773,28 +1773,28 @@
 	     return -EFAULT;
 	break;
       case MTRRIOC_ADD_PAGE_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 1);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_SET_PAGE_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_DEL_PAGE_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_file_del (sentry.base, sentry.size, file, 1);
 	if (err < 0) return err;
 	break;
       case MTRRIOC_KILL_PAGE_ENTRY:
-	if ( !suser () ) return -EPERM;
+	if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
 	if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
 	    return -EFAULT;
 	err = mtrr_del_page (-1, sentry.base, sentry.size);
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Sat Apr 27 19:14:56 2002
+++ b/arch/ppc64/kernel/ioctl32.c	Sat Apr 27 19:14:56 2002
@@ -1561,7 +1561,7 @@
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or super-user.
 	 */
-	if (current->tty == tty || suser())
+	if (current->tty == tty || capable(CAP_SYS_ADMIN))
 		return 1;
 	return 0;                                                    
 }
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Sat Apr 27 19:14:55 2002
+++ b/arch/sparc64/kernel/ioctl32.c	Sat Apr 27 19:14:55 2002
@@ -2060,7 +2060,7 @@
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or super-user.
 	 */
-	if (current->tty == tty || suser())
+	if (current->tty == tty || capable(CAP_SYS_ADMIN))
 		return 1;
 	return 0;                                                    
 }
diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
--- a/arch/x86_64/ia32/ia32_ioctl.c	Sat Apr 27 19:14:55 2002
+++ b/arch/x86_64/ia32/ia32_ioctl.c	Sat Apr 27 19:14:55 2002
@@ -1650,7 +1650,7 @@
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or super-user.
 	 */
-	if (current->tty == tty || suser())
+	if (current->tty == tty || capable(CAP_SYS_ADMIN))
 		return 1;
 	return 0;                                                    
 }
diff -Nru a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
--- a/arch/x86_64/kernel/mtrr.c	Sat Apr 27 19:14:55 2002
+++ b/arch/x86_64/kernel/mtrr.c	Sat Apr 27 19:14:55 2002
@@ -983,7 +983,7 @@
     char *ptr;
     char line[LINE_SIZE];
 
-	if (!suser ())
+	if (!capable (CAP_SYS_ADMIN))
 		return -EPERM;
 
     /*  Can't seek (pwrite) on this device  */
@@ -1071,7 +1071,7 @@
 	return -ENOIOCTLCMD;
 
       case MTRRIOC_ADD_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1083,7 +1083,7 @@
 	break;
 
       case MTRRIOC_SET_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1093,7 +1093,7 @@
 	break;
 
       case MTRRIOC_DEL_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1103,7 +1103,7 @@
 	break;
 
       case MTRRIOC_KILL_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1134,7 +1134,7 @@
 	break;
 
       case MTRRIOC_ADD_PAGE_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1146,7 +1146,7 @@
 	break;
 
       case MTRRIOC_SET_PAGE_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1156,7 +1156,7 @@
 	break;
 
       case MTRRIOC_DEL_PAGE_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
@@ -1166,7 +1166,7 @@
 	break;
 
       case MTRRIOC_KILL_PAGE_ENTRY:
-		if (!suser ())
+		if (!capable (CAP_SYS_ADMIN))
 			return -EPERM;
 		if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
 	    return -EFAULT;
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/block/cpqarray.c	Sat Apr 27 19:14:55 2002
@@ -787,7 +787,7 @@
 	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 
-	if (!suser() && ida_sizes[(ctlr << CTLR_SHIFT) +
+	if (!capable(CAP_SYS_ADMIN) && ida_sizes[(ctlr << CTLR_SHIFT) +
 						minor(inode->i_rdev)] == 0)
 		return -ENXIO;
 
@@ -797,7 +797,7 @@
 	 * but I'm already using way to many device nodes to claim another one
 	 * for "raw controller".
 	 */
-	if (suser()
+	if (capable(CAP_SYS_ADMIN)
 		&& ida_sizes[(ctlr << CTLR_SHIFT) + minor(inode->i_rdev)] == 0 
 		&& minor(inode->i_rdev) != 0)
 		return -ENXIO;
@@ -1139,7 +1139,7 @@
 	case BLKRRPART:
 		return revalidate_logvol(inode->i_rdev, 1);
 	case IDAPASSTHRU:
-		if (!suser()) return -EPERM;
+		if (!capable(CAP_SYS_ADMIN)) return -EPERM;
 		error = copy_from_user(&my_io, io, sizeof(my_io));
 		if (error) return error;
 		error = ida_ctlr_ioctl(ctlr, dsk, &my_io);
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/block/swim3.c	Sat Apr 27 19:14:55 2002
@@ -821,7 +821,7 @@
 	if (devnum >= floppy_count)
 		return -ENODEV;
 		
-	if ((cmd & 0x80) && !suser())
+	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	fs = &floppy_states[devnum];
diff -Nru a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
--- a/drivers/block/swim_iop.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/block/swim_iop.c	Sat Apr 27 19:14:55 2002
@@ -349,7 +349,7 @@
 	if (devnum >= floppy_count)
 		return -ENODEV;
 		
-	if ((cmd & 0x80) && !suser())
+	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	fs = &floppy_states[devnum];
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/char/ip2main.c	Sat Apr 27 19:14:56 2002
@@ -2660,7 +2660,7 @@
 	old_flags = pCh->flags;
 	old_baud_divisor = pCh->BaudDivisor;
 
-	if ( !suser() ) {
+	if ( !capable(CAP_SYS_ADMIN) ) {
 		if ( ( ns.close_delay != pCh->ClosingDelay ) ||
 		    ( (ns.flags & ~ASYNC_USR_MASK) !=
 		      (pCh->flags & ~ASYNC_USR_MASK) ) ) {
diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/char/moxa.c	Sat Apr 27 19:14:56 2002
@@ -2799,7 +2799,7 @@
 	    (new_serial.baud_base != 921600))
 		return (-EPERM);
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if (((new_serial.flags & ~ASYNC_USR_MASK) !=
 		     (info->asyncflags & ~ASYNC_USR_MASK)))
 			return (-EPERM);
diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c
--- a/drivers/char/mxser.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/char/mxser.c	Sat Apr 27 19:14:56 2002
@@ -2199,7 +2199,7 @@
 
 	flags = info->flags & ASYNC_SPD_MASK;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.close_delay != info->close_delay) ||
 		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
diff -Nru a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
--- a/drivers/char/rio/rio_linux.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/char/rio/rio_linux.c	Sat Apr 27 19:14:55 2002
@@ -702,7 +702,7 @@
   func_enter();
 
   /* The "dev" argument isn't used. */
-  rc = -riocontrol (p, 0, cmd, (void *)arg, suser ());
+  rc = -riocontrol (p, 0, cmd, (void *)arg, capable(CAP_SYS_ADMIN));
 
   func_exit ();
   return rc;
diff -Nru a/drivers/char/rocket.c b/drivers/char/rocket.c
--- a/drivers/char/rocket.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/char/rocket.c	Sat Apr 27 19:14:55 2002
@@ -1238,11 +1238,7 @@
 	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
 		return -EFAULT;
 
-#ifdef CAP_SYS_ADMIN
 	if (!capable(CAP_SYS_ADMIN))
-#else
-	if (!suser())
-#endif
 	{
 		if ((new_serial.flags & ~ROCKET_USR_MASK) !=
 		    (info->flags & ~ROCKET_USR_MASK))
diff -Nru a/drivers/char/serial167.c b/drivers/char/serial167.c
--- a/drivers/char/serial167.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/char/serial167.c	Sat Apr 27 19:14:55 2002
@@ -1472,7 +1472,7 @@
 	    return -EFAULT;
     old_info = *info;
 
-    if (!suser()) {
+    if (!capable(CAP_SYS_ADMIN)) {
 	    if ((new_serial.close_delay != info->close_delay) ||
 		((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
 		 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/char/tty_io.c	Sat Apr 27 19:14:56 2002
@@ -1370,7 +1370,7 @@
 		retval = -ENODEV;
 	filp->f_flags = saved_flags;
 
-	if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
+	if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
 		retval = -EBUSY;
 
 	if (retval) {
@@ -1472,7 +1472,7 @@
 {
 	char ch, mbz = 0;
 
-	if ((current->tty != tty) && !suser())
+	if ((current->tty != tty) && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (get_user(ch, arg))
 		return -EFAULT;
@@ -1510,7 +1510,7 @@
 {
 	if (IS_SYSCONS_DEV(inode->i_rdev) ||
 	    IS_CONSOLE_DEV(inode->i_rdev)) {
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		redirect = NULL;
 		return 0;
@@ -1552,7 +1552,7 @@
 		 * This tty is already the controlling
 		 * tty for another session group!
 		 */
-		if ((arg == 1) && suser()) {
+		if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
 			/*
 			 * Steal it away
 			 */
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/char/vt.c	Sat Apr 27 19:14:56 2002
@@ -443,7 +443,7 @@
 	 * to be the owner of the tty, or super-user.
 	 */
 	perm = 0;
-	if (current->tty == tty || suser())
+	if (current->tty == tty || capable(CAP_SYS_ADMIN))
 		perm = 1;
  
 	kbd = kbd_table + console;
@@ -1038,12 +1038,12 @@
 		return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
 
 	case VT_LOCKSWITCH:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 		   return -EPERM;
 		vt_dont_switch = 1;
 		return 0;
 	case VT_UNLOCKSWITCH:
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 		   return -EPERM;
 		vt_dont_switch = 0;
 		return 0;
diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
--- a/drivers/media/video/zr36120.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/media/video/zr36120.c	Sat Apr 27 19:14:56 2002
@@ -1294,7 +1294,7 @@
 #if LINUX_VERSION_CODE >= 0x020100
 			if(!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_ADMIN))
 #else
-			if(!suser())
+			if(!capable(CAP_SYS_ADMIN))
 #endif
 			return -EPERM;
 		if (copy_from_user(&v, arg,sizeof(v)))
diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/pcmcia/ds.c	Sat Apr 27 19:14:55 2002
@@ -830,7 +830,7 @@
 	err = unbind_request(i, &buf.bind_info);
 	break;
     case DS_BIND_MTD:
-	if (!suser()) return -EPERM;
+	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
 	err = bind_mtd(i, &buf.mtd_info);
 	break;
     default:
diff -Nru a/drivers/s390/char/tubtty.c b/drivers/s390/char/tubtty.c
--- a/drivers/s390/char/tubtty.c	Sat Apr 27 19:14:56 2002
+++ b/drivers/s390/char/tubtty.c	Sat Apr 27 19:14:56 2002
@@ -561,7 +561,7 @@
 	/*
 	 * Superuser-mode settings affect the driver overall ---
 	 */
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		return -EPERM;
 	} else if (strncmp(mybuf, "index=", 6) == 0) {
 		tty3270_proc_index = simple_strtoul(mybuf + 6, 0,0);
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Sat Apr 27 19:14:55 2002
+++ b/drivers/scsi/cpqfcTSinit.c	Sat Apr 27 19:14:55 2002
@@ -532,7 +532,7 @@
 
 	// must be super user to send stuff directly to the
 	// controller and/or physical drives...
-	if( !suser() )
+	if( !capable(CAP_SYS_ADMIN) )
 	  return -EPERM;
 
 	// copy the caller's struct to our space.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 232 bytes --]

  reply	other threads:[~2002-04-27 23:17 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-04-26 23:28 [PATCH] Various suser() -> capable() chang Colin Slater
2002-04-27 18:56 ` Alan Cox
2002-04-27 23:16   ` Colin Slater [this message]
2002-04-28  1:52     ` Chris Wright
2002-04-28 16:47       ` Colin Slater

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=1019949402.7399.3101.camel@neptune \
    --to=hoho@binbash.net \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=davej@suse.de \
    --cc=linux-kernel@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox