httpd: mess with PATH_INFO (again)
Hello, I am running Flask apps with uWSGI as a middleware, communicating with httpd via FastCGI sockets. Ever since OpenBSD 6.1 I started running into problems with all of my Flask apps. They would get caught in a redirect loop for root paths (see [1]). I did some debugging, and it seems that Flasks routing engine Werkzeug has an option called `strict_slashes`[2], which will append a slash and redirect to directory requests without a trailing slash. When the root URL of an app is requested, e.g. "http://foo.bar;, PATH_INFO will be set to an empty string. This causes Werkzeug to respond with a redirect, but the next request will still come in with PATH_INFO as "", resulting in a redirect loop. Attached diff causes PATH_INFO to be "/" in such a case, effectively fixing the problem for me. However, I am not well versed with the httpd code-base. Maybe it should be corrected with a different approach. Just sending this in to get the ball rolling. The CGI RFC[3] states that "/" and "" are valid paths. I would assume that for applications mounted at root, PATH_INFO should be "/" instead of "" when requesting the index. [1]: https://github.com/reyk/httpd/issues/71 [2]: http://werkzeug.pocoo.org/docs/0.14/routing/#werkzeug.routing.Rule [3]: https://tools.ietf.org/html/rfc3875#section-4.1.5 Index: httpd.c === RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v retrieving revision 1.67 diff -u -p -r1.67 httpd.c --- httpd.c 28 May 2017 10:37:26 - 1.67 +++ httpd.c 18 Jan 2018 07:20:58 - @@ -722,8 +722,12 @@ path_info(char *path) *p = ch; /* Break if the initial path component was found */ - if (ret == 0) + if (ret == 0) { + /* ensure leading / if path component is a directory */ + if (S_ISDIR(st.st_mode)) + return (p - start - 1); break; + } } return (p - start);
Re: Basic SHA3 support (cryptographic discussion)
Daniel Loebenberger: > - The construction of SHA3 differs considerably from the SHA2 > constructions > - SHA3's design principles are far better understood than the ones of > SHA2. I hear you, but you are missing the point. > - A possible migration away from SHA2 will be > faster when including SHA3 in OpenBSD now if it should happen that major > cryptanalytic advances attacking SHA2 pop up in the future. You are arguing for cryptographic algorithm agility. That is a concept the OpenBSD project has become increasingly critical of, because it adds complexity and code size for questionable gain. SHA-2 is baked into numerous protocols. Off the top of my head: * signify(1) * all non-legacy SSH key exchange and authentication methods * all non-legacy TLS cipher suites and certificates For all of those, a switchover to SHA-3 would require defining new protocol variants and then deploying them throughout the ecosystem. Having a SHA-3 implementation in libc is a rather small part of the overall effort. And there is no practical algorithm agility until you get to the point where you already HAVE deployed the new protocol variants. SHA-3 may be better, but so far SHA-2 is good enough. Algorithm agility is a questionable goal. So let me repeat the question: What do you want to USE your SHA-3 implementation for? -- Christian "naddy" Weisgerber na...@mips.inka.de
Re: malloc.c: correlation between random choices
On Wed, Jan 17, 2018 at 01:59:21PM +, kshe wrote: > Hi, > > In malloc_bytes(), the choice of the chunk_info list to use is > correlated with that of the offset at which the search for a free chunk > begins, because both use the same random source. This is easy to avoid, > for example by doing something like the diff below. > > --- malloc.c.orig Sun Jan 14 11:18:10 2018 > +++ malloc.c Tue Jan 16 12:31:29 2018 > @@ -954,7 +954,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f) > wrterror(d, "chunk info corrupted"); > > if (bp->free > 1) > - bp->rotor += r; > + bp->rotor += getrbyte(d); > i = bp->rotor++ & (bp->total - 1); > > /* start somewhere in a short */ This has been done to save a random byte. The correlation does not hurt. > > On a related note, however, I have some doubts about the usefulness of > this "randomisation rotor". > > First, it currently does not really randomise anything, since on most > architectures the total number of chunks always divides 256, so that > using merely `r' as the random offset instead of `bp->rotor + r' would > not change the distribution for the random variable thus obtained. > Moreover, in the rare cases where it actually has a noticeable effect, > this distribution is no longer uniform (and very biased) anyway, so the > proper way to randomise these choices would be to call getrbyte() twice, > not to add one random byte to a previously used random byte. The point is that on some arch there are more than 256 chunks in a page. e.g. on sparc64 (pagesize is 8k) for 16 bytes chunks. So using just a byte is not enough to count all chunks. That's why I'm collecting more bits by adding them to previously generated bits. Bias is not a big deal here as well. > > Second, it was introduced to "remember the position of the last free bit > in chunk_info", but it does not do that at all. In fact, when chunks > are allocated uniformly (which is always the case on amd64 for example), > once only two free slots are left, if the search for the first of these > two takes n steps, the search for the second and last one is then > guaranteed to take at least n steps, as it will systematically repeat > the last n-1 unsuccessful steps of the previous one, which is actually > worse than simply starting at a random offset or, for that matter, from > the beginning of the bitmap. Looking at this code again I see your point. I seems some assignment to the rotor has been lost in the refactoring. I'll revisit. -Otto > > More precisely, if n is the total number of chunks, the average number > of bits to check in order to find the last two free chunks is > > (n + 1) / 3 + (n + 1) / 2 > > if both starting offsets are chosen randomly and independently from each > other. On the other hand, the current average number of bits that will > be checked is n, or more explicitly > > (n + 1) / 3 + 2 * (n + 1) / 3 - 1, > > or even more explicitly > > (sum for i = 1 to n of > i * 2 * (n - i) / (n * (n - 1))) + > (sum for i = 1 to n of > i * 2 * (i - 1) / (n * (n - 1))) - 1. > > This indeed becomes worse than the above for all n greater than 5, that > is for all cases except the two least important ones (n = 2 and n = 4), > where no optimisation is necessary anyway. > > Therefore, I think this variable should be removed from chunk_info, as > it currently does more harm than good. If this is agreed with, I could > also provide a diff for it (but the solution, by the way, is not to > revert to the previous version of this code, which did not make much > sense either). > > Regards, > > kshe
Re: malloc.c: correlation between random choices
On Wed, Jan 17, 2018 at 08:52:36AM -0700, Theo de Raadt wrote: > So the attacker has numerous small hurdles. There's a banana on the > road, but there's snare wire above it. Okay, now, I can't stop thinking of a Will.E. Coyote-shaped Theo unboxing his ACME ordered snare wire at xmas...
Re: malloc.c: correlation between random choices
> On a related note, however, I have some doubts about the usefulness of > this "randomisation rotor". > > First, it currently does not really randomise anything, since on most > architectures the total number of chunks always divides 256, so that > using merely `r' as the random offset instead of `bp->rotor + r' would > not change the distribution for the random variable thus obtained. > Moreover, in the rare cases where it actually has a noticeable effect, > this distribution is no longer uniform (and very biased) anyway, so the > proper way to randomise these choices would be to call getrbyte() twice, > not to add one random byte to a previously used random byte. Many minor randomizations are surprisingly effective because an attacker only gets 1 attack try. Why? Because other layers have also perturbed their addresses, or other addresses which an attacker needs. So the attacker has numerous small hurdles. There's a banana on the road, but there's snare wire above it. It is too easy to fall into the trap of "I'm looking at the only defense".
Re: elf.h: define SHT_SYMTAB_SHNDX
On 16/01/18(Tue) 14:17, Karel Gardas wrote: > [...] > The patch looks good if you are OK with adding values which are no longer in > spec. IMHO I do not see value in those, What if somebody use them in their code? Removing them would break their app for free. That's why I see value in those ;) > so I would kill everything which is not in spec and does not break OpenBSD > build or any of ports. Related comments below. Updated diff, does it work for you? Index: sys/exec_elf.h === RCS file: /cvs/src/sys/sys/exec_elf.h,v retrieving revision 1.78 diff -u -p -r1.78 exec_elf.h --- sys/exec_elf.h 9 Dec 2017 06:35:08 - 1.78 +++ sys/exec_elf.h 17 Jan 2018 11:11:19 - @@ -106,15 +106,20 @@ typedef __uint16_tElf64_Quarter; #define ELFOSABI_HURD 4 /* GNU/Hurd */ #define ELFOSABI_86OPEN5 /* 86Open common IA32 ABI */ #define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_MONTEREY 7 /* Monterey */ +#define ELFOSABI_AIX 7 /* AIX */ #define ELFOSABI_IRIX 8 /* IRIX */ #define ELFOSABI_FREEBSD 9 /* FreeBSD */ #define ELFOSABI_TRU64 10 /* TRU64 UNIX */ #define ELFOSABI_MODESTO 11 /* Novell Modesto */ #define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_OPENVMS 13 /* Open VMS */ +#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE255 /* Standalone (embedded) application */ +#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */ +#define ELFOSABI_MONTEREY ELFOSABI_AIX/* Monterey */ + /* e_ident */ #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ @@ -164,8 +169,10 @@ typedef struct { #define ET_DYN 3 /* shared object file */ #define ET_CORE4 /* core file */ #define ET_NUM 5 /* number of types */ -#define ET_LOPROC 0xff00 /* reserved range for processor */ -#define ET_HIPROC 0x /* specific e_type */ +#define ET_LOOS0xfe00 /* First operating system specific. */ +#define ET_HIOS0xfeff /* Last operating system-specific. */ +#define ET_LOPROC 0xff00 /* First processor-specific. */ +#define ET_HIPROC 0x /* Last processor-specific. */ /* e_machine */ #define EM_NONE0 /* No Machine */ @@ -241,25 +248,31 @@ typedef struct { #define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ #define SHN_LOPROC 0xff00 /* reserved range for processor */ #define SHN_HIPROC 0xff1f /* specific section indexes */ +#define SHN_LOOS 0xff20 /* First operating system-specific. */ +#define SHN_HIOS 0xff3f /* Last operating system-specific. */ #define SHN_ABS0xfff1 /* absolute value */ #define SHN_COMMON 0xfff2 /* common symbol */ #define SHN_XINDEX 0x /* Escape -- index stored elsewhere. */ #define SHN_HIRESERVE 0x /* upper bounds of reserved indexes */ /* sh_type */ -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends*/ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL9 /* relation section without addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_NUM12 /* number of section types */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL9 /* relation section
Re: [patch] config(8) and KARL usage
On 17/01/18 11:40 +0100, Martin Pieuchot wrote: > Hello Sebastien, > > On 17/01/18(Wed) 10:19, Sebastien Marie wrote: > > [...] > > kernel modification is desirable in some cases, at least for disabling > > ulpt(4) when using cups with USB printer. > > Sorry to hijack your thread, but if somebody wants to fix this ulpt(4) > problem permanently here's the plan: > > - Add the USBD_EXCLUSIVE_USE to usbd_open_pipe() in ulptopen(). >Actually this flag should be the default everywhere. This should >prevent open(2) on /dev/ulpt? to work if a userland driver is using >your printer. > > - Do some plumbing between libusb/ugen(4)/usb(4) to make it possible >to submit bulk transfer via /dev/usb?. The logic in ugenopen() >should also have the USBD_EXCLUSIVE_USE flag such that it will fail >if the corresponding /dev/ultp? has already been opened. > > That should be enough to have CUPS work with GENERIC kernels without > having to disable anything. I'm here to help/review diffs but since > I don't have a printer myself, I can't do the work. > Oh yes please.
Re: [patch] config(8) and KARL usage
Hello Sebastien, On 17/01/18(Wed) 10:19, Sebastien Marie wrote: > [...] > kernel modification is desirable in some cases, at least for disabling > ulpt(4) when using cups with USB printer. Sorry to hijack your thread, but if somebody wants to fix this ulpt(4) problem permanently here's the plan: - Add the USBD_EXCLUSIVE_USE to usbd_open_pipe() in ulptopen(). Actually this flag should be the default everywhere. This should prevent open(2) on /dev/ulpt? to work if a userland driver is using your printer. - Do some plumbing between libusb/ugen(4)/usb(4) to make it possible to submit bulk transfer via /dev/usb?. The logic in ugenopen() should also have the USBD_EXCLUSIVE_USE flag such that it will fail if the corresponding /dev/ultp? has already been opened. That should be enough to have CUPS work with GENERIC kernels without having to disable anything. I'm here to help/review diffs but since I don't have a printer myself, I can't do the work.
[patch] config(8) and KARL usage
Hi, I would like to know if a patch for supporting kernel modification (using config(8)) along with KARL would be accepted ? Currently, both are incompatibles. kernel modification is desirable in some cases, at least for disabling ulpt(4) when using cups with USB printer. KARL is desirable too. I would like to add such support in the following way: - add an argument to config(8) to support non-interactive use. Basically, it would be "read from file instead read from stdin". - add a line in kernel Makefile to do kernel modification (only if file /etc/ukc.conf is present) as part of KARL process (after relinking and before checksuming). Please note the place of the config(8) call: the kernel modification would occurs only when KARL is invoked during boot process ("newbsd" target), and not when the kernel is first generated (during the release(8) process). Missing part in the diff is the ukc.conf man page. It would be provided if the direction seems good. Please note that I don't have tested full release(8) process (it would be mandatory for such change). The config(8) changes in detail: config(8) will use scriptfile as input stream (instead of `stdin') if provided. When non-interactive is in use, the following things changes: - on EOF : assume "quit" command (save and exit) instead of err(3) - on bad command : exit(1) instead of ignoring the error and asking for new command. For testing the diff: - compile and install (patched) config(8) first - don't omit the "make config" before building and installing new kernel Some example: # cat /etc/ukc.conf disable ulpt* # /usr/libexec/reorder_kernel # cat /usr/share/relink/kernel/GENERIC.MP/relink.log (SHA256) /bsd: OK LD="ld" sh makegap.sh 0x ld -T ld.script -X --warn-common -nopie -o newbsd ${SYSTEM_HEAD} vers.o ${OBJS} textdatabss dec hex 8173928 2380088 1093632 11647648b1baa0 mv newbsd newbsd.gdb ctfstrip -S -o newbsd newbsd.gdb if [ -f /etc/ukc.conf ]; then config -f -F /etc/ukc.conf -e newbsd; fi OpenBSD 6.2-current (GENERIC.MP) #85: Wed Jan 17 09:39:30 CET 2018 semarie@bert.local:/home/openbsd/src/sys/arch/i386/compile/GENERIC.MP Enter 'help' for information ukc> disable ulpt* 398 ulpt* disabled ukc> quit Saving modified kernel. mv -f newbsd bsd umask 077 && cp bsd /nbsd && mv /nbsd /bsd && sha256 -h /var/db/kernel.SHA256 /bsd Kernel has been relinked and is active on next reboot. SHA256 (/bsd) = 81a4916b8b81f0986d6fd63aad83c7fa4e742faa86c436756f1f79731c7ea184 -- Sebastien Marie Index: config.8 === RCS file: /cvs/src/usr.sbin/config/config.8,v retrieving revision 1.65 diff -u -p -r1.65 config.8 --- config.87 Oct 2017 06:41:43 - 1.65 +++ config.817 Jan 2018 09:15:47 - @@ -45,6 +45,7 @@ .Nm config .Op Fl u .Op Fl f | o Ar outfile +.Op Fl F Ar scriptfile .Fl e .Ar infile .Sh DESCRIPTION @@ -121,6 +122,12 @@ should be given to specify an alternate .It Fl o Ar outfile Write the modified kernel to .Ar outfile . +.It Fl F Ar scriptfile +Use +.Ar scriptfile +as source of commands for kernel modification. +.Ic quit +is assumed on eof. .It Fl u Check to see if the kernel configuration was modified at boot-time (i.e.\& Index: main.c === RCS file: /cvs/src/usr.sbin/config/main.c,v retrieving revision 1.59 diff -u -p -r1.59 main.c --- main.c 22 Jun 2017 15:57:16 - 1.59 +++ main.c 17 Jan 2018 09:15:48 - @@ -82,7 +82,7 @@ usage(void) fprintf(stderr, "usage: %s [-p] [-b builddir] [-s srcdir] [config-file]\n" - " %s [-u] [-f | -o outfile] -e infile\n", + " %s [-u] [-f | -o outfile] [-F scriptfile] -e infile\n", __progname, __progname); exit(1); @@ -92,6 +92,7 @@ int pflag = 0; char *sflag = NULL; char *bflag = NULL; char *startdir; +FILE *input = stdin; int main(int argc, char *argv[]) @@ -105,7 +106,7 @@ main(int argc, char *argv[]) err(1, "pledge"); pflag = eflag = uflag = fflag = 0; - while ((ch = getopt(argc, argv, "epfb:s:o:u")) != -1) { + while ((ch = getopt(argc, argv, "epfF:b:s:o:u")) != -1) { switch (ch) { case 'o': @@ -146,6 +147,12 @@ main(int argc, char *argv[]) case 's': sflag = optarg; srcdir = optarg; + break; + + case 'F': + input = fopen(optarg, "r"); + if (input == NULL) + err(2, "cannot read %s", optarg); break; default: Index: misc.c === RCS file: /cvs/src/usr.sbin/config/misc.c,v retrieving revision 1.9 diff -u -p -r1.9 misc.c --- misc.c 2 Oct 2011
Re: Add "-c command" option to script(1)
ping Anyone? Buehler? :) Paul On Mon, Dec 25, 2017 at 12:23:44PM +0100, Paul de Weerd wrote: | Hi all, | | Sorry to keep harping on this script stuff, but I'd really like to see | this committed. I've just upgraded my laptop while doing some | vlan-bridging debugging and suddenly script(1) lost my new favorite | feature. | | The manpage bits are OK jmc@; job@ and ian@ (off-list) OK'd the diff. | Is anyone willing to commit it with those? | | Thanks, | | Paul | | On Sat, Dec 16, 2017 at 09:45:02AM +0100, Paul de Weerd wrote: | | On Fri, Dec 15, 2017 at 12:24:45PM +0100, Paul de Weerd wrote: | | | I've updated the diff to add this example as per jmc's suggestion. It | | | now has: | | | | | | - add the `-c command` feature | | | - updates usage | | | - removes /* ARGSUSED */ lint comments | | | - documents the -c feature | | | - adds an example to the manpage | | | | jmc@ pointed out a missing colon at the end of the example. Apologies | | for the extra noise. Updated diff (still covers the above five | | changes) included. | | | | Cheers, | | | | Paul | | | | | | Index: script.1 | | === | | RCS file: /cvs/src/usr.bin/script/script.1,v | | retrieving revision 1.14 | | diff -u -p -r1.14 script.1 | | --- script.115 Jan 2012 20:06:40 - 1.14 | | +++ script.116 Dec 2017 08:42:24 - | | @@ -39,6 +39,7 @@ | | .Sh SYNOPSIS | | .Nm script | | .Op Fl a | | +.Op Fl c Ar command | | .Op Ar file | | .Sh DESCRIPTION | | .Nm | | @@ -65,9 +66,14 @@ Append the output to | | or | | .Pa typescript , | | retaining the prior contents. | | +.It Fl c Ar command | | +Run | | +.Ar command | | +instead of an interactive shell. | | +To run a command with arguments, enclose both in quotes. | | .El | | .Pp | | -The script ends when the forked shell exits (a control-D | | +The script ends when the forked program exits (a control-D | | .Pq Ql ^D | | to exit | | the Bourne shell | | @@ -102,6 +108,11 @@ Name of the shell to be forked by | | If not set, the Bourne shell is assumed. | | (Most shells set this variable automatically.) | | .El | | +.Sh EXAMPLES | | +Start a virtual machine and log all console output to a file: | | +.Bd -literal -offset indent | | +$ script -c "vmctl start myvm -c" myvm.typescript | | +.Ed | | .Sh HISTORY | | A predecessor called | | .Nm dribble | | Index: script.c | | === | | RCS file: /cvs/src/usr.bin/script/script.c,v | | retrieving revision 1.33 | | diff -u -p -r1.33 script.c | | --- script.c12 Apr 2017 14:49:05 - 1.33 | | +++ script.c14 Dec 2017 07:34:10 - | | @@ -89,7 +89,7 @@ int istty; | | | | __dead void done(int); | | void dooutput(void); | | -void doshell(void); | | +void doshell(char *); | | void fail(void); | | void finish(int); | | void scriptflush(int); | | @@ -102,17 +102,23 @@ main(int argc, char *argv[]) | | struct sigaction sa; | | struct winsize win; | | char ibuf[BUFSIZ]; | | + char *cmd; | | ssize_t cc, off; | | int aflg, ch; | | | | + cmd = NULL; | | aflg = 0; | | - while ((ch = getopt(argc, argv, "a")) != -1) | | + while ((ch = getopt(argc, argv, "ac:")) != -1) | | switch(ch) { | | case 'a': | | aflg = 1; | | break; | | + case 'c': | | + cmd = optarg; | | + break; | | default: | | - fprintf(stderr, "usage: %s [-a] [file]\n", __progname); | | + fprintf(stderr, "usage: %s [-a] [-c command] [file]\n", | | + __progname); | | exit(1); | | } | | argc -= optind; | | @@ -163,7 +169,7 @@ main(int argc, char *argv[]) | | if (child) | | dooutput(); | | else | | - doshell(); | | + doshell(cmd); | | } | | | | bzero(, sizeof sa); | | @@ -196,7 +202,6 @@ main(int argc, char *argv[]) | | done(sigdeadstatus); | | } | | | | -/* ARGSUSED */ | | void | | finish(int signo) | | { | | @@ -215,7 +220,6 @@ finish(int signo) | | errno = save_errno; | | } | | | | -/* ARGSUSED */ | | void | | handlesigwinch(int signo) | | { | | @@ -294,7 +298,6 @@ dooutput(void) | | done(0); | | } | | | | -/* ARGSUSED */ | | void | | scriptflush(int signo) | | { | | @@ -302,9 +305,10 @@ scriptflush(int signo) | | } | | | | void | | -doshell(void) | | +doshell(char *cmd) | | { | | char *shell; | | + char *argp[] = {"sh", "-c", NULL, NULL}; | | | | shell = getenv("SHELL"); | | if (shell == NULL) | | @@ -313,8 +317,15 @@ doshell(void) | | (void)close(master); | | (void)fclose(fscript); | | login_tty(slave); | | - execl(shell, shell, "-i", (char *)NULL); | | - warn("%s", shell); | | + |