bgpd up_generate_attr() minor speed improvement

2019-05-27 Thread Claudio Jeker
There is no need to loop over the full attribute space if there are no
attributes left to dump and the type is bigger then the last known one
(which is ATTR_LARGE_COMMUNITIES).

Gprof agrees with me. Before:
[28] 3.5  182.55   16.48 16460587 up_generate_attr [28]
after:
[58] 0.7   25.09   16.83 16687626 up_generate_attr [58]

Goes from 180s down to 30s of self time.

OK?
-- 
:wq Claudio

Index: rde_update.c
===
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.111
diff -u -p -r1.111 rde_update.c
--- rde_update.c13 May 2019 21:13:04 -  1.111
+++ rde_update.c27 May 2019 12:21:24 -
@@ -518,6 +518,10 @@ up_generate_attr(u_char *buf, int len, s
}
break;
default:
+   if (oa == NULL && type > ATTR_LARGE_COMMUNITIES)
+   /* there is no attribute left to dump */
+   goto done;
+
if (oa == NULL || oa->type != type)
break;
 
@@ -537,9 +541,10 @@ up_generate_attr(u_char *buf, int len, s
return (-1);
break;
}
-   wlen += r; len -= r;
+   wlen += r;
+   len -= r;
}
-
+done:
return (wlen);
 }
 



Re: usr.bin/getconf: Add reporting LONG_BIT

2019-05-27 Thread Philip Guenther
On Mon, May 27, 2019 at 3:43 PM Brian Callahan  wrote:

> Below is a small diff in response to some configuration attempts
> found in ports land.
> lang/ponyc uses $(shell getconf LONG_BIT) in its Makefile to
> determine whether or not we're on a 64-bit platform.
>

It needs to know that at the scripting level, outside of the C code itself
where it can directly test LONG_BIT (or perhaps better, _LP64)?  Huh.



> However, our getconf(1) doesn't support reporting LONG_BIT.
> This diff enables it. GNU/FreeBSD/DragonFly/MacOS getconf reports
> LONG_BIT, but NetBSD getconf does not.
> Desirable? OK?
>

That's the way to do it, I just have this vague "what tempting lunacy has
led them to this?" lurking in my mind.


Philip Guenther


usr.bin/getconf: Add reporting LONG_BIT

2019-05-27 Thread Brian Callahan
Hi tech --

Below is a small diff in response to some configuration attempts
found in ports land.
lang/ponyc uses $(shell getconf LONG_BIT) in its Makefile to
determine whether or not we're on a 64-bit platform.
However, our getconf(1) doesn't support reporting LONG_BIT.
This diff enables it. GNU/FreeBSD/DragonFly/MacOS getconf reports
LONG_BIT, but NetBSD getconf does not.
Desirable? OK?

~Brian

Index: getconf.c
===
RCS file: /cvs/src/usr.bin/getconf/getconf.c,v
retrieving revision 1.20
diff -u -p -r1.20 getconf.c
--- getconf.c   26 Oct 2018 17:11:32 -  1.20
+++ getconf.c   27 May 2019 21:06:01 -
@@ -163,6 +163,7 @@ const struct conf_variable conf_table[] 
   constant_row(_XOPEN_IOV_MAX)
   constant_row(_XOPEN_NAME_MAX)
   constant_row(_XOPEN_PATH_MAX)
+  constant_row(LONG_BIT)
 
   /* Extensions */
   sysconf_row(PHYS_PAGES)



Re: Attach kvm-clock to Linux guests on VMM

2019-05-27 Thread Pratik Vyas

* Renato Aguiar  [2019-05-27 03:53:11 -0700]:


Hi,

The following patch makes Linux guests use kvm-clock by setting KVM's 
CPUID signature on VMM:




I think the right thing is to make linux attach pvclock if it's on
OpenBSD vmm.  You want to send them a patch?

Otherwise, does vmm pvclock keep good time on linux from your experiments?

--
Pratik



Re: Make pthread_np.h standalone

2019-05-27 Thread Philip Guenther
On Mon, May 27, 2019 at 7:36 AM Jeremie Courreges-Anglas 
wrote:

>
> A bunch of our ports expect pthread_np.h to be standalone, alas our
> version doesn't include pthread.h.  The diff below should help us get
> rid of some patches in (at least) mongodb, mono, gnustep and webkitgtk4.
>
> ok?
>

ok guenther@


A further W^X refinement

2019-05-27 Thread Theo de Raadt
When we started work on W^X, we knew it would be a long road due to the
prevalance of JIT tooling.

1) Some of the JIT tooling is clean and will flip memory between W and X
states -- accepting the cost of mprotect().

2) Other JIT tooling creates aliases between a pair of W and X mappings of
the same memory (sadly, sometimes with pointers or deltas which I think
are too discoverable)

3) Other JIT tooling is even dirtier, and requires the W|X memory model.

The W^X picture has gotten better.  There are more programs in catagories
1 and 2 now, and fewer in 3.

But we wanted to run the W|X JIT programs, in particular chrome/iridium
after pledge (and later unveil) was added to mitigate the system call
(and filesystem view) problems.

So partly admitting defeat, I created a "wxneeded" ELF marker, and a
"wxallowed" filesystem mount option, so that the W|X binaries could be
run from such a filesystem (/usr/local).

Recently I considered the potential case of code-upload into the JIT W|X
code arenas which might contain native system call instructions.  I wish
to block direct system calls from those areas, thereby forcing the
attacker to deal with the (hopefully) more complex effort of using JIT
support environment code, or probably even harder discovering the
syscall stubs directly inside the randomly-relinked libc.  Even if the
JIT support access method is not more complicated, I want to remove the
direct syscall exploitation avenue.

With chrome/iridium on OpenBSD, the processes operating JIT are
tightly pledged, but taking away the write(2) system call obviously
has some advantage, as we steer the attacker towards using the
JIT support code.

This diff refactors the MAP_STACK pseudo-permission bit code, adding
additional code which checks if a syscall is being performed from a
writeable page.  If the page is writeable, the process is killed.

There is one concern.  Are there any JIT which create native syscalls
inside W|X memory?  I am hopeful because we've changed the syscall ABI
so often and never heard of failure modes.

This diff is now in snapshots, to help my dear readers discover any
potential problems.

ps. In related news, chrome has a JIT-less mode in development which
does no W|X mappings.  It is acceptable for more minimal usage patterns,
but obviously uses a lot more cpu.  As well, chrome will now mostly work
if you disable "wxallowed" on the filesystem.  At startup it observes
MAP_WRITE|MAP_EXEC fails with ENOTSUP, and then proceeds to use mprotect
to flip pages between modes.  It *mostly* works, there are problems with
some plugins (ghostery, for instance), but I'm very hopeful they will
complete this work in the near future.

Index: sys/proc.h
===
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.265
diff -u -p -u -r1.265 proc.h
--- sys/proc.h  13 May 2019 19:21:31 -  1.265
+++ sys/proc.h  27 May 2019 12:12:43 -
@@ -298,6 +298,12 @@ struct process {
 struct kcov_dev;
 struct lock_list_entry;
 
+struct p_inentry {
+   u_intie_serial;
+   vaddr_t  ie_start;
+   vaddr_t  ie_end;
+};
+
 /*
  *  Locks used to protect struct members in this file:
  * s   scheduler lock
@@ -315,6 +321,8 @@ struct proc {
/* substructures: */
struct  filedesc *p_fd; /* copy of p_p->ps_fd */
struct  vmspace *p_vmspace; /* copy of p_p->ps_vmspace */
+   struct  p_inentry p_spinentry;
+   struct  p_inentry p_pcinentry;
 #definep_rlimitp_p->ps_limit->pl_rlimit
 
int p_flag; /* P_* flags. */
@@ -357,10 +365,6 @@ struct proc {
 /* The following fields are all copied upon creation in fork. */
 #definep_startcopy p_sigmask
sigset_t p_sigmask; /* Current signal mask. */
-
-   u_intp_spserial;
-   vaddr_t  p_spstart;
-   vaddr_t  p_spend;
 
u_char  p_priority; /* [s] Process priority. */
u_char  p_usrpri;   /* [s] User-prio based on p_estcpu & ps_nice. */
Index: sys/syscall_mi.h
===
RCS file: /cvs/src/sys/sys/syscall_mi.h,v
retrieving revision 1.19
diff -u -p -u -r1.19 syscall_mi.h
--- sys/syscall_mi.h12 Apr 2018 17:13:44 -  1.19
+++ sys/syscall_mi.h27 May 2019 12:12:43 -
@@ -50,7 +50,6 @@ mi_syscall(struct proc *p, register_t co
uint64_t tval;
int lock = !(callp->sy_flags & SY_NOLOCK);
int error, pledged;
-   vaddr_t sp = PROC_STACK(p);
 
/* refresh the thread's cache of the process's creds */
refreshcreds(p);
@@ -68,24 +67,16 @@ mi_syscall(struct proc *p, register_t co
}
 #endif
 
-   if (p->p_vmspace->vm_map.serial != p->p_spserial ||
-   p->p_spstart == 0 || sp < p->p_spstart || sp >= p->p_spend) {
-   KERNEL_LOCK();
+   /* SP must be within MAP_STACK space */
+   if (!uvm_map_inentry(p, &p->p_spinentry, P

Re: typos in /src/sys/dev/pci/if_jme.c

2019-05-27 Thread Jason McIntyre
On Sat, May 25, 2019 at 09:27:48AM -0500, J Sisson wrote:
> Noticed a typo in jme(4) printf output.  Found additional typos while
> browsing the code.
> 
> Yes, possibly the most useless diff ever...I freely admit it.
> 

fixed, thanks (though note your diff didn;t apply).
jmc

> Index: sys/dev/pci/if_jme.c
> ===
> RCS file: /cvs/src/sys/dev/pci/if_jme.c,v
> retrieving revision 1.51
> diff -u -p -u -r1.51 if_jme.c
> --- sys/dev/pci/if_jme.c29 Mar 2019 17:25:44 -  1.51
> +++ sys/dev/pci/if_jme.c25 May 2019 14:19:46 -
> @@ -233,7 +233,7 @@ jme_miibus_statchg(struct device *dev)
>  * Disabling Rx/Tx MACs have a side-effect of resetting
>  * JME_TXNDA/JME_RXNDA register to the first address of
>  * Tx/Rx descriptor address. So driver should reset its
> -* internal procucer/consumer pointer and reclaim any
> +* internal producer/consumer pointer and reclaim any
>  * allocated resources.  Note, just saving the value of
>  * JME_TXNDA and JME_RXNDA registers before stopping MAC
>  * and restoring JME_TXNDA/JME_RXNDA register is not
> @@ -277,7 +277,7 @@ jme_miibus_statchg(struct device *dev)
> 
> /*
>  * Reuse configured Rx descriptors and reset
> -* procuder/consumer index.
> +* producer/consumer index.
>  */
> sc->jme_cdata.jme_rx_cons = 0;
> 
> @@ -550,7 +550,7 @@ jme_attach(struct device *parent, struct
>  * JMC250 supports both memory mapped and I/O register space
>  * access.  Because I/O register access should use different
>  * BARs to access registers it's waste of time to use I/O
> -* register spce access.  JMC250 uses 16K to map entire memory
> +* register space access.  JMC250 uses 16K to map entire memory
>  * space.
>  */
> 
> @@ -984,7 +984,7 @@ jme_dma_free(struct jme_softc *sc)
>  /*
>   * Unlike other ethernet controllers, JMC250 requires
>   * explicit resetting link speed to 10/100Mbps as gigabit
> - * link will cunsume more power than 375mA.
> + * link will consume more power than 375mA.
>   * Note, we reset the link speed to 10/100Mbps with
>   * auto-negotiation but we don't know whether that operation
>   * would succeed or not as we have no control after powering
> @@ -1169,7 +1169,7 @@ jme_encap(struct jme_softc *sc, struct m
> sc->jme_cdata.jme_tx_prod = prod;
> /*
>  * Finally request interrupt and give the first descriptor
> -* owenership to hardware.
> +* ownership to hardware.
>  */
> desc = txd->tx_desc;
> desc->flags |= htole32(JME_TD_OWN | JME_TD_INTR);
> @@ -1534,7 +1534,7 @@ jme_txeof(struct jme_softc *sc)
> /*
>  * Only the first descriptor of multi-descriptor
>  * transmission is updated so driver have to skip entire
> -* chained buffers for the transmiited frame. In other
> +* chained buffers for the transmitted frame. In other
>  * words, JME_TD_OWN bit is valid only at the first
>  * descriptor of a multi-descriptor transmission.
>  */
> @@ -2110,7 +2110,7 @@ jme_stop_rx(struct jme_softc *sc)
> break;
> }
> if (i == 0)
> -   printf("%s: stopping recevier timeout!\n", 
> sc->sc_dev.dv_xname);
> +   printf("%s: stopping receiver timeout!\n", 
> sc->sc_dev.dv_xname);
>  }
> 
>  void
> 



Re: Attach kvm-clock to Linux guests on VMM

2019-05-27 Thread Mike Larkin
On Mon, May 27, 2019 at 03:53:11AM -0700, Renato Aguiar wrote:
> Hi,
> 
> The following patch makes Linux guests use kvm-clock by setting KVM's CPUID
> signature on VMM:
> 

By saying the hypervisor is KVM to all guests, does this cause the guests
to make other assumptions we don't want?

> Index: sys/arch/amd64/amd64/vmm.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v
> retrieving revision 1.245
> diff -u -p -r1.245 vmm.c
> --- sys/arch/amd64/amd64/vmm.c17 May 2019 19:07:15 -1.245
> +++ sys/arch/amd64/amd64/vmm.c27 May 2019 09:44:07 -
> @@ -238,6 +238,7 @@ extern uint64_t tsc_frequency;
> extern int tsc_is_invariant;
> 
> const char *vmm_hv_signature = VMM_HV_SIGNATURE;
> +const char *kvm_hv_signature = KVM_HV_SIGNATURE;
> 
> const struct kmem_pa_mode vmm_kp_contig = {
>   .kp_constraint = &no_constraint,
> @@ -6433,7 +6434,14 @@ vmm_handle_cpuid(struct vcpu *vcpu)
>   *rcx = *((uint32_t *)&vmm_hv_signature[4]);
>   *rdx = *((uint32_t *)&vmm_hv_signature[8]);
>   break;
> + case 0x4100:/* KVM CPUID signature */
> + *rax = 0;
> + *rbx = *((uint32_t *)&kvm_hv_signature[0]);
> + *rcx = *((uint32_t *)&kvm_hv_signature[4]);
> + *rdx = *((uint32_t *)&kvm_hv_signature[8]);
> + break;
>   case 0x4001:/* KVM hypervisor features */
> + case 0x4101:
>   *rax = (1 << KVM_FEATURE_CLOCKSOURCE2) |
>   (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
>   *rbx = 0;
> Index: sys/arch/amd64/include/vmmvar.h
> ===
> RCS file: /cvs/src/sys/arch/amd64/include/vmmvar.h,v
> retrieving revision 1.66
> diff -u -p -r1.66 vmmvar.h
> --- sys/arch/amd64/include/vmmvar.h   17 May 2019 19:07:16 -1.66
> +++ sys/arch/amd64/include/vmmvar.h   27 May 2019 09:44:07 -
> @@ -22,6 +22,7 @@
> #define _MACHINE_VMMVAR_H_
> 
> #define VMM_HV_SIGNATURE  "OpenBSDVMM58"
> +#define KVM_HV_SIGNATURE "KVMKVMKVM\0\0\0"
> 
> #define VMM_MAX_MEM_RANGES16
> #define VMM_MAX_DISKS_PER_VM  4
> Index: sys/arch/i386/include/vmmvar.h
> ===
> RCS file: /cvs/src/sys/arch/i386/include/vmmvar.h,v
> retrieving revision 1.19
> diff -u -p -r1.19 vmmvar.h
> --- sys/arch/i386/include/vmmvar.h18 Jan 2019 01:34:50 -1.19
> +++ sys/arch/i386/include/vmmvar.h27 May 2019 09:44:07 -
> @@ -15,3 +15,4 @@
>  */
> 
> #define VMM_HV_SIGNATURE  "OpenBSDVMM58"
> +#define KVM_HV_SIGNATURE "KVMKVMKVM\0\0\0"
> Index: sys/dev/pv/pvbus.c
> ===
> RCS file: /cvs/src/sys/dev/pv/pvbus.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 pvbus.c
> --- sys/dev/pv/pvbus.c13 May 2019 15:40:34 -  1.19
> +++ sys/dev/pv/pvbus.c27 May 2019 09:44:08 -
> @@ -85,7 +85,7 @@ struct pvbus_type {
>   void(*init)(struct pvbus_hv *);
>   void(*print)(struct pvbus_hv *);
> } pvbus_types[PVBUS_MAX] = {
> - { "KVMKVMKVM\0\0\0","KVM",  pvbus_kvm },
> + { KVM_HV_SIGNATURE, "KVM",  pvbus_kvm },
>   { "Microsoft Hv",   "Hyper-V", pvbus_hyperv, pvbus_hyperv_print },
>   { "VMwareVMware",   "VMware" },
>   { "XenVMMXenVMM",   "Xen",  pvbus_xen, pvbus_xen_print },
> 
> 
> -- 
> Renato Aguiar
> 



Re: vmd(8): slight NS8250 fix

2019-05-27 Thread Mike Larkin
On Sun, May 26, 2019 at 11:38:37PM -0700, Mike Larkin wrote:
> On Wed, May 22, 2019 at 08:05:50PM -0500, Katherine Rohl wrote:
> > Hi,
> > 
> > Adjusted NS8250 behavior in vmd(8) so it gets detected as an 8250 and not a 
> > 16450 by OpenBSD’s boot process. Also generalized some of the COM1-specific 
> > I/O address definitions to support adding COM2 (and COM3, and COM4…) in the 
> > future.
> > 
> > Tested by logging into my VM with the virtual serial console and 
> > reinstalling 6.5, everything was fine. The boot process detected an NS8250.
> > 
> 
> It occurred to me that by always returning 0xFF, a guest might write 0xFF to
> scratch, then read it back, and we'd always return 0xFF. They might then
> think that the scratch register worked. That's pretty bizarre, but I've seen
> a lot of bizarre behaviour in various guests.
> 

Theo pointed out that this is probably the right way (always return 0xFF), so
I'll commit the original version.

Thanks.

-ml

> The slightly revised version below just inverts whatever was written, ensuring
> that whatever is read is not what was written. This should make anyone doing
> such calculation think the scratch doesn't work.
> 
> Tested on Linux and OpenBSD guests.
> 
> Thoughts?
> 
> -ml
> 
> Index: ns8250.c
> ===
> RCS file: /cvs/src/usr.sbin/vmd/ns8250.c,v
> retrieving revision 1.20
> diff -u -p -a -u -r1.20 ns8250.c
> --- ns8250.c  11 Mar 2019 17:08:52 -  1.20
> +++ ns8250.c  27 May 2019 06:34:38 -
> @@ -74,6 +74,7 @@ ns8250_init(int fd, uint32_t vmid)
>   }
>   com1_dev.fd = fd;
>   com1_dev.irq = 4;
> + com1_dev.portid = NS8250_COM1;
>   com1_dev.rcv_pending = 0;
>   com1_dev.vmid = vmid;
>   com1_dev.byte_out = 0;
> @@ -509,7 +510,8 @@ vcpu_process_com_scr(struct vm_exit *vei
>   /*
>* vei_dir == VEI_DIR_OUT : out instruction
>*
> -  * Write to SCR
> +  * The 8250 does not have a scratch register. Make sure that whatever
> +  * was written is not what gets read back.
>*/
>   if (vei->vei.vei_dir == VEI_DIR_OUT) {
>   com1_dev.regs.scr = vei->vei.vei_data;
> @@ -517,9 +519,11 @@ vcpu_process_com_scr(struct vm_exit *vei
>   /*
>* vei_dir == VEI_DIR_IN : in instruction
>*
> -  * Read from SCR
> +  * Read from SCR - invert whatever was previously written,
> +  * to ensure the guest doesn't think the scratch register
> +  * works.
>*/
> - set_return_data(vei, com1_dev.regs.scr);
> + set_return_data(vei, ~com1_dev.regs.scr);
>   }
>  }
>  
> @@ -647,6 +651,7 @@ ns8250_restore(int fd, int con_fd, uint3
>   }
>   com1_dev.fd = con_fd;
>   com1_dev.irq = 4;
> + com1_dev.portid = NS8250_COM1;
>   com1_dev.rcv_pending = 0;
>   com1_dev.vmid = vmid;
>   com1_dev.byte_out = 0;
> Index: ns8250.h
> ===
> RCS file: /cvs/src/usr.sbin/vmd/ns8250.h,v
> retrieving revision 1.7
> diff -u -p -a -u -r1.7 ns8250.h
> --- ns8250.h  11 Mar 2019 17:08:52 -  1.7
> +++ ns8250.h  27 May 2019 06:31:13 -
> @@ -18,14 +18,30 @@
>  /*
>   * Emulated 8250 UART
>   */
> -#define COM1_DATA0x3f8
> -#define COM1_IER 0x3f9
> -#define COM1_IIR 0x3fa
> -#define COM1_LCR 0x3fb
> -#define COM1_MCR 0x3fc
> -#define COM1_LSR 0x3fd
> -#define COM1_MSR 0x3fe
> -#define COM1_SCR 0x3ff
> +#define COM1_BASE   0x3f8
> +#define COM1_DATACOM1_BASE+COM_OFFSET_DATA
> +#define COM1_IER COM1_BASE+COM_OFFSET_IER
> +#define COM1_IIR COM1_BASE+COM_OFFSET_IIR
> +#define COM1_LCR COM1_BASE+COM_OFFSET_LCR
> +#define COM1_MCR COM1_BASE+COM_OFFSET_MCR
> +#define COM1_LSR COM1_BASE+COM_OFFSET_LSR
> +#define COM1_MSR COM1_BASE+COM_OFFSET_MSR
> +#define COM1_SCR COM1_BASE+COM_OFFSET_SCR
> +
> +#define COM_OFFSET_DATA 0
> +#define COM_OFFSET_IER  1
> +#define COM_OFFSET_IIR  2
> +#define COM_OFFSET_LCR  3
> +#define COM_OFFSET_MCR  4
> +#define COM_OFFSET_LSR  5
> +#define COM_OFFSET_MSR  6
> +#define COM_OFFSET_SCR  7
> +
> +/* ns8250 port identifier */
> +enum ns8250_portid {
> + NS8250_COM1,
> + NS8250_COM2,
> +};
>  
>  /* ns8250 UART registers */
>  struct ns8250_regs {
> @@ -50,6 +66,7 @@ struct ns8250_dev {
>   struct event rate;
>   struct event wake;
>   struct timeval rate_tv;
> + enum ns8250_portid portid;
>   int fd;
>   int irq;
>   int rcv_pending;



Make pthread_np.h standalone

2019-05-27 Thread Jeremie Courreges-Anglas


A bunch of our ports expect pthread_np.h to be standalone, alas our
version doesn't include pthread.h.  The diff below should help us get
rid of some patches in (at least) mongodb, mono, gnustep and webkitgtk4.

ok?


Index: include/pthread_np.h
===
RCS file: /cvs/src/include/pthread_np.h,v
retrieving revision 1.2
diff -u -p -r1.2 pthread_np.h
--- include/pthread_np.h4 Feb 2019 17:18:08 -   1.2
+++ include/pthread_np.h27 May 2019 15:30:10 -
@@ -34,6 +34,8 @@
 #ifndef _PTHREAD_NP_H_
 #define _PTHREAD_NP_H_
 
+#include 
+
 /*
  * Non-POSIX type definitions:
  */


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: bgpd set nexthop 198.51.100.42 clarifications

2019-05-27 Thread Job Snijders
On Mon, May 13, 2019 at 21:11 Claudio Jeker 
wrote:

> When using a rule forcing the nexthop to a specific address bgpd
> currently does not mark that nexthop as no-modify. In other words
> the default rules for nexthop propagation applies. This means that
> for ebgp it only sends out the set nexthop when this nexthop is connected
> and on the same network as the peer. So while the Adj-RIB-Out shows the
> right nexthop it is actually not on the wire.
>
> This diff changes set nexthop 198.51.100.42 to also imply set nexthop
> no-modify. This way the set nexthop is always on the wire.
> The problem with that is that it will hand you a nice footgun ready to
> blow of your big toe (but in the end the current behaviour is doing the
> same just with a different angle of attack) .
>
> The set nexthop section in bgpd.conf.5 needs to be adjusted once a
> decision is made on how to handle this.
> --
> :wq Claudio
>
> Index: rde_rib.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> retrieving revision 1.190
> diff -u -p -r1.190 rde_rib.c
> --- rde_rib.c   7 Mar 2019 07:42:36 -   1.190
> +++ rde_rib.c   13 May 2019 17:32:14 -
> @@ -1491,7 +1491,7 @@ nexthop_modify(struct nexthop *setnh, en
> break;
> nexthop_put(*nexthop);
> *nexthop = nexthop_ref(setnh);
> -   *flags = 0;
> +   *flags = NEXTHOP_NOMODIFY;
> break;
> default:
> break;
>
>


Re: bgpd set nexthop 198.51.100.42 clarifications

2019-05-27 Thread Denis Fondras
On Mon, May 13, 2019 at 09:03:41PM +0200, Claudio Jeker wrote:
> When using a rule forcing the nexthop to a specific address bgpd
> currently does not mark that nexthop as no-modify. In other words
> the default rules for nexthop propagation applies. This means that
> for ebgp it only sends out the set nexthop when this nexthop is connected
> and on the same network as the peer. So while the Adj-RIB-Out shows the
> right nexthop it is actually not on the wire.
> 
> This diff changes set nexthop 198.51.100.42 to also imply set nexthop
> no-modify. This way the set nexthop is always on the wire.
> The problem with that is that it will hand you a nice footgun ready to
> blow of your big toe (but in the end the current behaviour is doing the
> same just with a different angle of attack) .
>

It does not seem right to show a NH which does not reflect reality.

OK denis@

> The set nexthop section in bgpd.conf.5 needs to be adjusted once a
> decision is made on how to handle this.
> -- 
> :wq Claudio
> 
> Index: rde_rib.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> retrieving revision 1.190
> diff -u -p -r1.190 rde_rib.c
> --- rde_rib.c 7 Mar 2019 07:42:36 -   1.190
> +++ rde_rib.c 13 May 2019 17:32:14 -
> @@ -1491,7 +1491,7 @@ nexthop_modify(struct nexthop *setnh, en
>   break;
>   nexthop_put(*nexthop);
>   *nexthop = nexthop_ref(setnh);
> - *flags = 0;
> + *flags = NEXTHOP_NOMODIFY;
>   break;
>   default:
>   break;
> 



Attach kvm-clock to Linux guests on VMM

2019-05-27 Thread Renato Aguiar

Hi,

The following patch makes Linux guests use kvm-clock by setting 
KVM's CPUID signature on VMM:


Index: sys/arch/amd64/amd64/vmm.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v
retrieving revision 1.245
diff -u -p -r1.245 vmm.c
--- sys/arch/amd64/amd64/vmm.c	17 May 2019 19:07:15 - 
   1.245

+++ sys/arch/amd64/amd64/vmm.c  27 May 2019 09:44:07 -
@@ -238,6 +238,7 @@ extern uint64_t tsc_frequency;
extern int tsc_is_invariant;

const char *vmm_hv_signature = VMM_HV_SIGNATURE;
+const char *kvm_hv_signature = KVM_HV_SIGNATURE;

const struct kmem_pa_mode vmm_kp_contig = {
.kp_constraint = &no_constraint,
@@ -6433,7 +6434,14 @@ vmm_handle_cpuid(struct vcpu *vcpu)
*rcx = *((uint32_t *)&vmm_hv_signature[4]);
*rdx = *((uint32_t *)&vmm_hv_signature[8]);
break;
+   case 0x4100:/* KVM CPUID signature */
+   *rax = 0;
+   *rbx = *((uint32_t *)&kvm_hv_signature[0]);
+   *rcx = *((uint32_t *)&kvm_hv_signature[4]);
+   *rdx = *((uint32_t *)&kvm_hv_signature[8]);
+   break;
case 0x4001:/* KVM hypervisor features */
+   case 0x4101:
*rax = (1 << KVM_FEATURE_CLOCKSOURCE2) |
(1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
*rbx = 0;
Index: sys/arch/amd64/include/vmmvar.h
===
RCS file: /cvs/src/sys/arch/amd64/include/vmmvar.h,v
retrieving revision 1.66
diff -u -p -r1.66 vmmvar.h
--- sys/arch/amd64/include/vmmvar.h	17 May 2019 19:07:16 - 
   1.66

+++ sys/arch/amd64/include/vmmvar.h 27 May 2019 09:44:07 -
@@ -22,6 +22,7 @@
#define _MACHINE_VMMVAR_H_

#define VMM_HV_SIGNATURE"OpenBSDVMM58"
+#define KVM_HV_SIGNATURE   "KVMKVMKVM\0\0\0"

#define VMM_MAX_MEM_RANGES  16
#define VMM_MAX_DISKS_PER_VM4
Index: sys/arch/i386/include/vmmvar.h
===
RCS file: /cvs/src/sys/arch/i386/include/vmmvar.h,v
retrieving revision 1.19
diff -u -p -r1.19 vmmvar.h
--- sys/arch/i386/include/vmmvar.h	18 Jan 2019 01:34:50 - 
   1.19

+++ sys/arch/i386/include/vmmvar.h  27 May 2019 09:44:07 -
@@ -15,3 +15,4 @@
 */

#define VMM_HV_SIGNATURE"OpenBSDVMM58"
+#define KVM_HV_SIGNATURE   "KVMKVMKVM\0\0\0"
Index: sys/dev/pv/pvbus.c
===
RCS file: /cvs/src/sys/dev/pv/pvbus.c,v
retrieving revision 1.19
diff -u -p -r1.19 pvbus.c
--- sys/dev/pv/pvbus.c  13 May 2019 15:40:34 -  1.19
+++ sys/dev/pv/pvbus.c  27 May 2019 09:44:08 -
@@ -85,7 +85,7 @@ struct pvbus_type {
void(*init)(struct pvbus_hv *);
void(*print)(struct pvbus_hv *);
} pvbus_types[PVBUS_MAX] = {
-   { "KVMKVMKVM\0\0\0",  "KVM",pvbus_kvm },
+   { KVM_HV_SIGNATURE, "KVM",pvbus_kvm },
	{ "Microsoft Hv",	"Hyper-V", pvbus_hyperv, 
pvbus_hyperv_print },

{ "VMwareVMware", "VMware" },
	{ "XenVMMXenVMM",	"Xen",	pvbus_xen, pvbus_xen_print 
},



--
Renato Aguiar



Re: net80211: fix ifconfig mode command

2019-05-27 Thread Jonathan Matthew
On Mon, May 27, 2019 at 01:36:38PM +0200, Stefan Sperling wrote:
> Anyone?

makes sense to me, ok jmatthew@

> 
> On Wed, May 22, 2019 at 02:49:43PM +0200, Stefan Sperling wrote:
> > On Mon, Apr 15, 2019 at 04:56:52PM +0200, Stefan Sperling wrote:
> > > The ifconfig mode command is broken; It is supposed to force a wireless
> > > interface into 11a/b/g/n media mode. This stopped working some time ago,
> > > probably during my work on background scanning. Problem spotted by 
> > > mlarkin@
> > > who noticed that interfaces were using 11g mode while forced to 11b mode.
> > > 
> > > The diff below allows me to force media modes again on iwm(4), urtwn(4),
> > > and athn(4), with e.g. 'ifconfig iwm0 mode 11b'  More tests welcome.
> > > 
> > > Note that the stack will autoselect a mode by default and things will
> > > usually just work. So this isn't a critical issue unless a mode needs to
> > > be forced for some reason. The main purpose of switching modes is to
> > > restrict drivers to a particular set of channels and Tx rates.
> > 
> > The previous version of this diff had a bug which would cause recursion
> > in ieee80211_end_scan() followed by a panic in ieee80211_fix_rate().
> > 
> > Here is a new diff with that problem fixed;  ok?
> > 
> > diff e7d7f4196e8f84e5d8b61c3e357f85fa9b4a44db /usr/src
> > blob - d362284ff0b163b77ec8774f5307d6becbc867c0
> > file + sys/net80211/ieee80211.c
> > --- sys/net80211/ieee80211.c
> > +++ sys/net80211/ieee80211.c
> > @@ -1007,6 +1007,7 @@ enum ieee80211_phymode
> >  ieee80211_next_mode(struct ifnet *ifp)
> >  {
> > struct ieee80211com *ic = (void *)ifp;
> > +   uint16_t mode;
> >  
> > if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) {
> > /*
> > @@ -1018,36 +1019,52 @@ ieee80211_next_mode(struct ifnet *ifp)
> > }
> >  
> > /*
> > -* Get the next supported mode
> > +* Always scan in AUTO mode if the driver scans all bands, and
> > +* leave the current mode as it is.
> >  */
> > -   for (++ic->ic_curmode;
> > -   ic->ic_curmode <= IEEE80211_MODE_MAX;
> > -   ic->ic_curmode++) {
> > +   if (ic->ic_caps & IEEE80211_C_SCANALLBAND)
> > +   return (IEEE80211_MODE_AUTO);
> > +
> > +   /*
> > +* Get the next supported mode; effectively, this alternates between
> > +* the 11a (5GHz) and 11b/g (2GHz) modes. What matters is that each
> > +* supported channel gets scanned.
> > +*/
> > +   for (mode = ic->ic_curmode + 1; mode <= IEEE80211_MODE_MAX; mode++) {
> > /* 
> >  * Skip over 11n mode. Its set of channels is the superset
> >  * of all channels supported by the other modes.
> >  */
> > -   if (ic->ic_curmode == IEEE80211_MODE_11N)
> > +   if (mode == IEEE80211_MODE_11N)
> > continue;
> > /* 
> >  * Skip over 11ac mode. Its set of channels is the set
> >  * of all channels supported by 11a.
> >  */
> > -   if (ic->ic_curmode == IEEE80211_MODE_11AC)
> > +   if (mode == IEEE80211_MODE_11AC)
> > continue;
> >  
> > -   /* Always scan in AUTO mode if the driver scans all bands. */
> > -   if (ic->ic_curmode >= IEEE80211_MODE_MAX ||
> > -   (ic->ic_caps & IEEE80211_C_SCANALLBAND)) {
> > -   ic->ic_curmode = IEEE80211_MODE_AUTO;
> > +   if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) {
> > +   /* 
> > +* Skip over 11b mode. Its set of channels is
> > +* the set of all channels supported by 11g.
> > +*/
> > +   if (mode == IEEE80211_MODE_11B)
> > +   continue;
> > +   }
> > +
> > +   /* Start over if we have already tried all modes. */
> > +   if (mode == IEEE80211_MODE_MAX) {
> > +   mode = IEEE80211_MODE_AUTO;
> > break;
> > }
> >  
> > -   if (ic->ic_modecaps & (1 << ic->ic_curmode))
> > +   if (ic->ic_modecaps & (1 << mode))
> > break;
> > }
> >  
> > -   ieee80211_setmode(ic, ic->ic_curmode);
> > +   if (mode != ic->ic_curmode)
> > +   ieee80211_setmode(ic, mode);
> >  
> > return (ic->ic_curmode);
> >  }
> > @@ -1058,26 +1075,41 @@ ieee80211_next_mode(struct ifnet *ifp)
> >   * work here assumes how things work elsewhere in this code.
> >   *
> >   * Because the result of this function is ultimately used to select a
> > - * rate from the rate set of the returned mode, it must not return
> > - * IEEE80211_MODE_11N, which uses MCS instead of rates for unicast frames.
> > + * rate from the rate set of the returned mode, it must return one of the
> > + * legacy 11a/b/g modes; 11n and 11ac modes use MCS instead of rate sets.
> >   */
> >  enum ieee80211_phymode
> >  ieee80211_chan2mode(struct ieee80211com *ic,
> >  const struct ieee80211_channel 

Re: net80211: fix ifconfig mode command

2019-05-27 Thread Stefan Sperling
Anyone?

On Wed, May 22, 2019 at 02:49:43PM +0200, Stefan Sperling wrote:
> On Mon, Apr 15, 2019 at 04:56:52PM +0200, Stefan Sperling wrote:
> > The ifconfig mode command is broken; It is supposed to force a wireless
> > interface into 11a/b/g/n media mode. This stopped working some time ago,
> > probably during my work on background scanning. Problem spotted by mlarkin@
> > who noticed that interfaces were using 11g mode while forced to 11b mode.
> > 
> > The diff below allows me to force media modes again on iwm(4), urtwn(4),
> > and athn(4), with e.g. 'ifconfig iwm0 mode 11b'  More tests welcome.
> > 
> > Note that the stack will autoselect a mode by default and things will
> > usually just work. So this isn't a critical issue unless a mode needs to
> > be forced for some reason. The main purpose of switching modes is to
> > restrict drivers to a particular set of channels and Tx rates.
> 
> The previous version of this diff had a bug which would cause recursion
> in ieee80211_end_scan() followed by a panic in ieee80211_fix_rate().
> 
> Here is a new diff with that problem fixed;  ok?
> 
> diff e7d7f4196e8f84e5d8b61c3e357f85fa9b4a44db /usr/src
> blob - d362284ff0b163b77ec8774f5307d6becbc867c0
> file + sys/net80211/ieee80211.c
> --- sys/net80211/ieee80211.c
> +++ sys/net80211/ieee80211.c
> @@ -1007,6 +1007,7 @@ enum ieee80211_phymode
>  ieee80211_next_mode(struct ifnet *ifp)
>  {
>   struct ieee80211com *ic = (void *)ifp;
> + uint16_t mode;
>  
>   if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) {
>   /*
> @@ -1018,36 +1019,52 @@ ieee80211_next_mode(struct ifnet *ifp)
>   }
>  
>   /*
> -  * Get the next supported mode
> +  * Always scan in AUTO mode if the driver scans all bands, and
> +  * leave the current mode as it is.
>*/
> - for (++ic->ic_curmode;
> - ic->ic_curmode <= IEEE80211_MODE_MAX;
> - ic->ic_curmode++) {
> + if (ic->ic_caps & IEEE80211_C_SCANALLBAND)
> + return (IEEE80211_MODE_AUTO);
> +
> + /*
> +  * Get the next supported mode; effectively, this alternates between
> +  * the 11a (5GHz) and 11b/g (2GHz) modes. What matters is that each
> +  * supported channel gets scanned.
> +  */
> + for (mode = ic->ic_curmode + 1; mode <= IEEE80211_MODE_MAX; mode++) {
>   /* 
>* Skip over 11n mode. Its set of channels is the superset
>* of all channels supported by the other modes.
>*/
> - if (ic->ic_curmode == IEEE80211_MODE_11N)
> + if (mode == IEEE80211_MODE_11N)
>   continue;
>   /* 
>* Skip over 11ac mode. Its set of channels is the set
>* of all channels supported by 11a.
>*/
> - if (ic->ic_curmode == IEEE80211_MODE_11AC)
> + if (mode == IEEE80211_MODE_11AC)
>   continue;
>  
> - /* Always scan in AUTO mode if the driver scans all bands. */
> - if (ic->ic_curmode >= IEEE80211_MODE_MAX ||
> - (ic->ic_caps & IEEE80211_C_SCANALLBAND)) {
> - ic->ic_curmode = IEEE80211_MODE_AUTO;
> + if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) {
> + /* 
> +  * Skip over 11b mode. Its set of channels is
> +  * the set of all channels supported by 11g.
> +  */
> + if (mode == IEEE80211_MODE_11B)
> + continue;
> + }
> +
> + /* Start over if we have already tried all modes. */
> + if (mode == IEEE80211_MODE_MAX) {
> + mode = IEEE80211_MODE_AUTO;
>   break;
>   }
>  
> - if (ic->ic_modecaps & (1 << ic->ic_curmode))
> + if (ic->ic_modecaps & (1 << mode))
>   break;
>   }
>  
> - ieee80211_setmode(ic, ic->ic_curmode);
> + if (mode != ic->ic_curmode)
> + ieee80211_setmode(ic, mode);
>  
>   return (ic->ic_curmode);
>  }
> @@ -1058,26 +1075,41 @@ ieee80211_next_mode(struct ifnet *ifp)
>   * work here assumes how things work elsewhere in this code.
>   *
>   * Because the result of this function is ultimately used to select a
> - * rate from the rate set of the returned mode, it must not return
> - * IEEE80211_MODE_11N, which uses MCS instead of rates for unicast frames.
> + * rate from the rate set of the returned mode, it must return one of the
> + * legacy 11a/b/g modes; 11n and 11ac modes use MCS instead of rate sets.
>   */
>  enum ieee80211_phymode
>  ieee80211_chan2mode(struct ieee80211com *ic,
>  const struct ieee80211_channel *chan)
>  {
>   /*
> +  * Are we fixed in 11a/b/g mode?
>* NB: this assumes the channel would not be supplied to us
>* unless it was already compatible with the current mode.
>  

Re: efiboot: allow bigger ucodes

2019-05-27 Thread Theo de Raadt
Stuart Henderson  wrote:

> On 2019/05/20 10:46, Paul de Weerd wrote:
> > However, library_aslr delays the boot sequence (because libraries must
> > be completed before the system can boot up) while kernel_aslr does not
> > - it only introduces a bit of extra load on your machine.
> 
> That depends if reorder_kernel can run without killing the machine,
> it doesn't do very well on my alixes.

I have some nickels lying around, I'll send you one.





Re: snake: unveil + pledge earlier

2019-05-27 Thread Theo de Raadt
Ted Unangst  wrote:

> Jake Champlin wrote:
> > -   readscores(1);
> > penalty = loot = 0;
> > initscr();
> > +   if (unveil(scorepath, "rwc") == -1)
> > +   err(1, "unveil");
> > +#ifdef LOGGING
> > +   if (unveil(logpath, "rwc") == -1)
> > +   err(1, "unveil");
> > +   logfile = fopen(logpath, "a");
> > +#endif
> > +   readscores(1);
> > 
> > if (pledge("stdio tty", NULL) == -1)
> > err(1, "pledge");
> 
> We're unveiling the same file we're going to immediately open. And then we
> never open it later, as proved by pledge without rpath. There doesn't seem to
> be any benefit in this case.
> 
> If we needed to reopen these files at some later point, this would be the
> right thing.

I've seen this poor pattern a few times, so I let me make a few comments.

unveil(path, "r");
open(path, O_RDONLY)

This is more expensive than just doing open().  After the open() is finished,
the kernel still has to remember the vnode.

Secondly, it has a subtle race.  Both of those system calls are traversing the
path.  That's a form of TOCTOU.  Always try to traverse a path once.

Third, installing unveil's without unveil(NULL,NULL) or dropping pledge "unveil"
has on security benefit.  In the sample above, a bug in the readscores() code
can read anywhere in the filesystem.

Please think carefully about what I've mentioned.  I think a common pattern
is for people to read the unveil() manual page and determine they know how to
use unveil correctly.  It is better to read many uses of unveil() throughout
the source tree, since the usage pattern is highly idiomatic and beyond the
scope the manual page can describe.  This idiomatic pattern just isn't ingrained
in everyone's minds yet, so do read other code...



Re: update sysupgrade manpage

2019-05-27 Thread Theo de Raadt
There are plans to adapt sysupgrade for upgrading to arbitrary snapshots
from the archives, to help everyone do bisect.

When that comes, all these proposed changes will be backwards.

Otto Moerbeek  wrote:

> On Mon, May 27, 2019 at 04:16:01AM +0200, giovani...@tuta.io wrote:
> 
> > Hello,
> > 
> > I tried to make sysupgrade man page more readable and fixed a small 
> > mistake. The man page stated:
> > 
> > > .It Fl s
> > > Upgrade to a snapshot.
> > > The default is to find out if the system is running a release or a 
> > > snapshot.
> > > In case of release> .Nm
> > > downloads the next release.
> > 
> > But if SNAP is set, even in release systems, sysupgrade targets snapshots:
> 
> Yes, but the sentence describes the default beahviour as I read it.
> Your chanche is equally confusing, imo.
> 
> I think it is better to move the description of the default behaviour
> to the start and only describe the non-default with the options.
> 
> The rest of your changes I'll leave to a native speaker.
> 
>   -Otto
> 
> > 
> > > if $SNAP; then
> > >     URL=${MIRROR}/snapshots/${ARCH}/
> > > else
> > >     URL=${MIRROR}/${NEXT_VERSION}/${ARCH}/
> > > fi
> > 
> > Here is the patch:
> > 
> > Index: usr.sbin/sysupgrade/sysupgrade.8
> > ===
> > RCS file: /cvs/src/usr.sbin/sysupgrade/sysupgrade.8,v
> > retrieving revision 1.8
> > diff -u -p -u -p -r1.8 sysupgrade.8
> > --- usr.sbin/sysupgrade/sysupgrade.8    9 May 2019 21:09:37 -    1.8
> > +++ usr.sbin/sysupgrade/sysupgrade.8    27 May 2019 00:07:11 -
> > @@ -19,7 +19,7 @@
> >  .Os
> >  .Sh NAME
> >  .Nm sysupgrade
> > -.Nd upgrade system to the next release or a new snapshot
> > +.Nd upgrade system to the next release or latest snapshot
> >  .Sh SYNOPSIS
> >  .Nm
> >  .Op Fl fkn
> > @@ -29,7 +29,7 @@
> >  .Nm
> >  is a utility to upgrade
> >  .Ox
> > -to the next release or a new snapshot if available.
> > +to the next release or latest snapshot, if available.
> >  .Pp
> >  .Nm
> >  downloads the necessary files to
> > @@ -39,8 +39,9 @@ verifies them with
> >  and copies bsd.rd to
> >  .Pa /bsd.upgrade .
> >  .Pp
> > +Then, by default,
> >  .Nm
> > -by default then reboots the system.
> > +reboots the system.
> >  The bootloader will automatically choose
> >  .Pa /bsd.upgrade ,
> >  triggering a one-shot upgrade using the files in
> > @@ -55,23 +56,22 @@ This option has no effect on releases.
> >  .It Fl k
> >  Keep the files in
> >  .Pa /home/_sysupgrade .
> > -By default they will be deleted after the upgrade.
> > +By default, they are deleted after the upgrade.
> >  .It Fl n
> > -Fetch and verify the files and create
> > -.Pa /bsd.upgrade
> > -but do not reboot.
> > +Do not reboot the system after creating 
> > +.Pa /bsd.upgrade .
> >  .It Fl r
> >  Upgrade to the next release.
> >  The default is to find out if the system is running a release or a 
> > snapshot.
> > -In case of release
> > +In case of release,
> >  .Nm
> >  downloads the next release.
> >  .It Fl s
> >  Upgrade to a snapshot.
> >  The default is to find out if the system is running a release or a 
> > snapshot.
> > -In case of release
> > +In case of release,
> >  .Nm
> > -downloads the next release.
> > +downloads the latest snapshot.
> >  .El
> >  .Sh FILES
> >  .Bl -tag -width "/home/_sysupgrade" -compact
> > 
> > 
> > 
> 



Possible bug in LibreSSL

2019-05-27 Thread Renaud Allard

Hello,

I had some problems connecting to my SSL enabled pure-ftpd server with 
filezilla 3.42 (on windows) which uses GnuTLS 3.6.7. I am running 
OpenBSD 6.5.


I opened a thread on filezilla forum and the developer claims this is 
due to a bug in LibreSSL.

The thread is here:
https://forum.filezilla-project.org/viewtopic.php?p=169140#p169140

Basically, here is what he says:
the Client Hello does not contain a server_name extension, whereas the 
Server Hello does contain a server_name extension.


From RFC 5246: "An extension type MUST NOT appear in the ServerHello 
unless the same extension type appeared in the corresponding 
ClientHello. If a client receives an extension type in ServerHello that 
it did not request in the associated ClientHello, it MUST abort the 
handshake with an unsupported_extension fatal alert."


From RFC 6066: "When resuming a session, the server MUST NOT include a 
server_name extension in the server hello."



Best Regards



smime.p7s
Description: S/MIME Cryptographic Signature


mail program for patches (was: Re: vmd(8): slight NS8250 fix)

2019-05-27 Thread Stefan Sperling
On Sat, May 25, 2019 at 01:43:43AM -0500, Katherine Rohl wrote:
> (Side note, what console email program is
> the best for submitting these patches anyway?)

It doesn't really matter what tooling you use as long as it does not
mangle patches; typically, whitespace reformatting and line-wrapping
pose a problem. Copy-pasting patches into a browser window is quite
likely to break them so that should be avoided. Reading patch files
directly into an editor buffer will generally work well.

One neat trick is sending a large patch to yourself and trying to apply
it yourself, and tweaking your tooling / workflow until this works.