diff: fix LCP keepalive failures on L2TP.

2012-01-30 Thread YASUOKA Masahiko
pipex hook in udp_usrreq() mistakenly assumed that `inp' is
connected.  The hook could not use the destination address properly,
so it failed to find the pipex session.  This bug caused LCP keepalive
failures on L2TP from client that does LCP keepalive and uses sequence
number on the L2TP data channel (xl2tpd + pppd).

The diff includes kernel header file changes.

ok?

Index: sys/net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.25
diff -u -p -r1.25 pipex.c
--- sys/net/pipex.c 23 Jan 2012 03:36:21 -  1.25
+++ sys/net/pipex.c 30 Jan 2012 12:11:16 -
@@ -2210,7 +2210,7 @@ pipex_l2tp_userland_lookup_session_ipv6(
 }
 #endif
 
-Static struct pipex_session *
+struct pipex_session *
 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
 {
struct pipex_l2tp_header l2tp;
Index: sys/net/pipex.h
===
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.11
diff -u -p -r1.11 pipex.h
--- sys/net/pipex.h 23 Jan 2012 03:36:21 -  1.11
+++ sys/net/pipex.h 30 Jan 2012 12:11:16 -
@@ -210,6 +210,7 @@ struct pipex_session  *pipex_pptp_lookup
 struct mbuf   *pipex_pptp_input (struct mbuf *, struct pipex_session 
*);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv4 (struct mbuf *, 
struct in_addr);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv6 (struct mbuf *, 
struct in6_addr);
+struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf *, 
struct sockaddr *);
 struct mbuf   *pipex_pptp_userland_output (struct mbuf *, struct 
pipex_session *);
 struct pipex_session  *pipex_l2tp_lookup_session (struct mbuf *, int);
 struct mbuf   *pipex_l2tp_input (struct mbuf *, int off, struct 
pipex_session *);
Index: sys/net/pipex_local.h
===
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.14
diff -u -p -r1.14 pipex_local.h
--- sys/net/pipex_local.h   25 Nov 2011 13:05:06 -  1.14
+++ sys/net/pipex_local.h   30 Jan 2012 12:11:16 -
@@ -406,7 +406,6 @@ Static struct pipex_session  *pipex_pptp
 
 #ifdef PIPEX_L2TP
 Static void  pipex_l2tp_output (struct mbuf *, struct 
pipex_session *);
-Static struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf 
*, struct sockaddr *);
 #endif
 
 #ifdef PIPEX_MPPE
Index: sys/netinet/udp_usrreq.c
===
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.145
diff -u -p -r1.145 udp_usrreq.c
--- sys/netinet/udp_usrreq.c8 Jul 2011 18:30:17 -   1.145
+++ sys/netinet/udp_usrreq.c30 Jan 2012 12:11:17 -
@@ -1198,6 +1198,12 @@ udp_usrreq(struct socket *so, int req, s
 #ifdef PIPEX
if (inp-inp_pipex) {
struct pipex_session *session;
+
+   if (addr != NULL) 
+   session =
+   pipex_l2tp_userland_lookup_session(m,
+   mtod(addr, struct sockaddr *));
+   else
 #ifdef INET6
if (inp-inp_flags  INP_IPV6)
session =



Re: diff: fix LCP keepalive failures on L2TP.

2012-01-30 Thread YASUOKA Masahiko
On Mon, 30 Jan 2012 22:49:22 +0900 (JST)
YASUOKA Masahiko yasu...@yasuoka.net wrote:
 pipex hook in udp_usrreq() mistakenly assumed that `inp' is
 connected.  The hook could not use the destination address properly,
 so it failed to find the pipex session.  This bug caused LCP keepalive
 failures on L2TP from client that does LCP keepalive and uses sequence
 number on the L2TP data channel (xl2tpd + pppd).
 
 The diff includes kernel header file changes.
 
 ok?

Oops.  Let me update the diff.

The given struct sockaddr object of
pipex_l2tp_userland_lookup_session() became passed from the userland,
so its address family must be checked.

ok?

Index: sys/net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.25
diff -u -p -r1.25 pipex.c
--- sys/net/pipex.c 23 Jan 2012 03:36:21 -  1.25
+++ sys/net/pipex.c 30 Jan 2012 14:37:31 -
@@ -2210,13 +2210,16 @@ pipex_l2tp_userland_lookup_session_ipv6(
 }
 #endif
 
-Static struct pipex_session *
+struct pipex_session *
 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
 {
struct pipex_l2tp_header l2tp;
struct pipex_hash_head *list;
struct pipex_session *session;
uint16_t session_id, tunnel_id, flags;
+
+   if (sa-sa_family != AF_INET  sa-sa_family != AF_INET6)
+   return (NULL);
 
/* pullup */
if (m0-m_pkthdr.len  sizeof(l2tp)) {
Index: sys/net/pipex.h
===
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.11
diff -u -p -r1.11 pipex.h
--- sys/net/pipex.h 23 Jan 2012 03:36:21 -  1.11
+++ sys/net/pipex.h 30 Jan 2012 14:37:31 -
@@ -210,6 +210,7 @@ struct pipex_session  *pipex_pptp_lookup
 struct mbuf   *pipex_pptp_input (struct mbuf *, struct pipex_session 
*);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv4 (struct mbuf *, 
struct in_addr);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv6 (struct mbuf *, 
struct in6_addr);
+struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf *, 
struct sockaddr *);
 struct mbuf   *pipex_pptp_userland_output (struct mbuf *, struct 
pipex_session *);
 struct pipex_session  *pipex_l2tp_lookup_session (struct mbuf *, int);
 struct mbuf   *pipex_l2tp_input (struct mbuf *, int off, struct 
pipex_session *);
Index: sys/net/pipex_local.h
===
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.14
diff -u -p -r1.14 pipex_local.h
--- sys/net/pipex_local.h   25 Nov 2011 13:05:06 -  1.14
+++ sys/net/pipex_local.h   30 Jan 2012 14:37:31 -
@@ -406,7 +406,6 @@ Static struct pipex_session  *pipex_pptp
 
 #ifdef PIPEX_L2TP
 Static void  pipex_l2tp_output (struct mbuf *, struct 
pipex_session *);
-Static struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf 
*, struct sockaddr *);
 #endif
 
 #ifdef PIPEX_MPPE
Index: sys/netinet/udp_usrreq.c
===
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.145
diff -u -p -r1.145 udp_usrreq.c
--- sys/netinet/udp_usrreq.c8 Jul 2011 18:30:17 -   1.145
+++ sys/netinet/udp_usrreq.c30 Jan 2012 14:37:32 -
@@ -1198,6 +1198,12 @@ udp_usrreq(struct socket *so, int req, s
 #ifdef PIPEX
if (inp-inp_pipex) {
struct pipex_session *session;
+
+   if (addr != NULL) 
+   session =
+   pipex_l2tp_userland_lookup_session(m,
+   mtod(addr, struct sockaddr *));
+   else
 #ifdef INET6
if (inp-inp_flags  INP_IPV6)
session =



Keycode print mode (-r) for wsconsctl(8)

2012-01-30 Thread Steffen Daode Nurpmeso
It doesn't offer any information from the generated keysym.h or
anything, but only prints the plain keycode.
If it's of any use for a user to see 'keycode 83' and not being
able to say 'keyboard.map+=keycode 83=Home' is a different
story.

--steffen

Index: sbin/wsconsctl/Makefile
===
RCS file: /cvs/src/sbin/wsconsctl/Makefile,v
retrieving revision 1.34
diff -a -p -u -r1.34 Makefile
--- sbin/wsconsctl/Makefile 30 Jan 2010 20:48:50 -  1.34
+++ sbin/wsconsctl/Makefile 30 Jan 2012 15:17:46 -
@@ -12,7 +12,7 @@
 ${MACHINE} == zaurus
 
 PROG=  wsconsctl
-SRCS=  display.c keyboard.c keysym.c map_parse.y map_scan.l \
+SRCS=  display.c keyboard.c keycode.c keysym.c map_parse.y map_scan.l \
mouse.c util.c wsconsctl.c
 
 CPPFLAGS+= -I${.CURDIR} -I.
Index: sbin/wsconsctl/keycode.c
===
RCS file: sbin/wsconsctl/keycode.c
diff -N sbin/wsconsctl/keycode.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ sbin/wsconsctl/keycode.c30 Jan 2012 15:18:12 -
@@ -0,0 +1,133 @@
+/* $OpenBSD$   */
+
+/*
+ * Copyright (c) 2012 Steffen Daode Nurpmeso.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include dev/wscons/wsconsio.h
+#include dev/wscons/wsksymdef.h
+#include err.h
+#include errno.h
+#include signal.h
+#include stdio.h
+#include stdlib.h
+#include sys/ioctl.h
+#include sys/time.h
+#include termios.h
+#include unistd.h
+#include wsconsctl.h
+
+static struct termios  tios_orig, tios_raw;
+
+static voidonsig(int sig);
+static voidraw_on(void), raw_off(void);
+
+static void
+onsig(int sig)
+{
+   raw_off();
+   exit(sig != SIGALRM);
+}
+
+static void
+raw_on(void)
+{
+   int arg = WSKBD_RAW;
+
+   if (tcsetattr(STDIN_FILENO, TCSANOW, tios_raw)  0)
+   err(1, Can't set terminal attributes);
+   if (ioctl(STDIN_FILENO, WSKBDIO_SETMODE, arg)  0) {
+   arg = errno;
+   (void)tcsetattr(STDIN_FILENO, TCSANOW, tios_orig);
+   errno = arg;
+   err(1, ((arg == ENOTTY)
+   ? This mode won't work on pseudo terminals
+   : Can't put keyboard in raw mode (the 
+ WSDISPLAY_COMPAT_RAWKBD kernel option is required)));
+   }
+   return;
+}
+
+static void
+raw_off(void)
+{
+   int arg = WSKBD_TRANSLATED;
+
+   (void)ioctl(STDIN_FILENO, WSKBDIO_SETMODE, arg);
+   (void)tcsetattr(STDIN_FILENO, TCSANOW, tios_orig);
+   return;
+}
+
+void
+keycode_mode(void)
+{
+   ssize_t i, skip;
+   struct sigaction sa;
+   struct itimerval it;
+   unsigned char *cursor, buffer[64];
+
+   if (tcgetattr(STDIN_FILENO, tios_orig)  0)
+   err(1, Can't query terminal attributes);
+   tios_raw = tios_orig;
+   (void)cfmakeraw(tios_raw);
+
+   sa.sa_handler = onsig;
+   sa.sa_flags = 0;
+   (void)sigfillset(sa.sa_mask);
+   for (i = 0; i  NSIG; ++i)
+   if (sigaction((int)i + 1, sa, NULL)  0  i == SIGALRM)
+   err(1, Can't install SIGALRM signal handler);
+
+   printf(You may now use the keyboard.\n
+   After five seconds of inactivity the program terminates\n);
+   for (i = skip = 0;;) {
+   it.it_value.tv_sec = 5;
+   it.it_value.tv_usec = 0;
+   it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
+   if (setitimer(ITIMER_REAL, it, NULL)  0)
+   err(3, Can't install wakeup timer);
+
+   raw_on();
+   i = read(STDIN_FILENO, buffer + skip, sizeof(buffer) - skip);
+   raw_off();
+
+   it.it_value.tv_sec = it.it_value.tv_usec = 0;
+   (void)setitimer(ITIMER_REAL, it, NULL);
+
+   if (i = 0)
+   exit(1);
+   i += skip;
+
+   for (cursor = buffer; --i = 0;) {
+   unsigned int k = *cursor++;
+   if ((k  0xF0) == 0xE0 || (k  0xF8) == 0xF0) {
+   if (--i  0) {
+   buffer[0] = (unsigned char)k;
+   skip = 1;
+

man segfault diff

2012-01-30 Thread Tobias Ulmer
- Remove confusing unused len fields from TAG and ENTRY
- Remove a couple of internal unused variables
- Prevent parse_path() from inserting empty ENTRYs into the list,
  leading to a crash due to negative array access later on.

From what I can tell, changing config.h affects man, whatis and apropos
only. In my testing none of them used the len fields.

The crash can be reproduced with this extreme example:
man -m ::: test

It's occasionally triggered by git $command --help.

Index: config.h
===
RCS file: /home/vcs/cvs/openbsd/src/usr.bin/man/config.h,v
retrieving revision 1.5
diff -u -p -r1.5 config.h
--- config.h15 Sep 2004 22:20:03 -  1.5
+++ config.h31 Jan 2012 03:14:47 -
@@ -38,13 +38,11 @@ typedef struct _tag {
 
TAILQ_HEAD(tqh, _entry) list;   /* Queue of entries. */
char *s;/* Associated string. */
-   size_t len; /* Length of 's'. */
 } TAG;
 typedef struct _entry {
TAILQ_ENTRY(_entry) q;  /* Queue of entries. */
 
char *s;/* Associated string. */
-   size_t len; /* Length of 's'. */
 } ENTRY;
 
 TAILQ_HEAD(_head, _tag);
Index: man.c
===
RCS file: /home/vcs/cvs/openbsd/src/usr.bin/man/man.c,v
retrieving revision 1.44
diff -u -p -r1.44 man.c
--- man.c   5 Jan 2012 21:46:15 -   1.44
+++ man.c   31 Jan 2012 03:14:47 -
@@ -95,7 +95,6 @@ main(int argc, char *argv[])
extern char *optarg;
extern int optind;
TAG *searchlist;
-   ENTRY *ep;
glob_t pg;
size_t len;
int ch, f_cat, f_how, found;
@@ -339,6 +338,10 @@ parse_path(TAG *t, char *path)
char *p, *slashp;
 
while ((p = strsep(path, :)) != NULL) {
+   /* Skip emtpy fields */
+   if (*p == '\0')
+   continue;
+
if ((ep = malloc(sizeof(ENTRY))) == NULL)
err(1, NULL);
 
@@ -434,7 +437,7 @@ manual(char *page, TAG *tag, glob_t *pg)
 {
ENTRY *ep, *e_sufp, *e_tag;
TAG *missp, *sufp;
-   int anyfound, cnt, found, globres;
+   int anyfound, cnt, found;
char *p, buf[MAXPATHLEN];
 
anyfound = 0;