Re: ifmedia_ioctl: ignore ENETRESET from ifm_change()

2019-04-20 Thread Jonathan Matthew
On Mon, Apr 15, 2019 at 04:48:02PM +0200, Stefan Sperling wrote:
> ieee80211_media_change() will return ENETRESET if the interface is
> switched into 11a/b/g/n mode from any other mode.
> ifmedia_ioctl() considers this an error and reverts ifmedia's state
> to the previous setting, even though net80211 has actually succeeded.
> The result is that if_media and net80211 have conflicting ideas about the
> current media mode of the interface, which can be observed with ifconfig.

Diff makes sense to me.  Currently we have some drivers with media_change
functions returning the errno from ieee80211_media_change (iwn, iwm) and some
just returning 0 at the end (run, rtwn, ral).  The ones returning 0 are mostly
ignoring possible errors from x_init() so I'm leaning towards making them more
like iwn/m.

> 
> The commands below were run while the interface is down.
> Note how 'ifconfig mode' needs to be run twice to get consistent results:
> 
>   # ifconfig iwm0 | grep media:
>   media: IEEE802.11 autoselect
>   # ifconfig iwm0 mode 11b 
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect (autoselect mode 11b)
>   # ifconfig iwm0 mode 11b  
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect mode 11b
>   # ifconfig iwm0 mode 11g  
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect mode 11b (autoselect mode 11g)
>   # ifconfig iwm0 mode 11g  
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect mode 11g
> 
> The diff below fixes this issue for me:
> 
>   # ifconfig iwm0 | grep media:
>   media: IEEE802.11 autoselect
>   # ifconfig iwm0 mode 11b 
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect mode 11b
>   # ifconfig iwm0 mode 11g  
>   # ifconfig iwm0 | grep media: 
>   media: IEEE802.11 autoselect mode 11g
> 
> OK?
> 
> diff 23a4e4a1e8913390694e35727d2131b2938cb472 /usr/src
> blob - 5168b074cbdd5a95f9945134cdd47c0649ad76a1
> file + sys/net/if_media.c
> --- sys/net/if_media.c
> +++ sys/net/if_media.c
> @@ -277,7 +277,7 @@ ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, st
>   ifm->ifm_cur = match;
>   ifm->ifm_media = newmedia;
>   error = (*ifm->ifm_change)(ifp);
> - if (error) {
> + if (error && error != ENETRESET) {
>   ifm->ifm_cur = oldentry;
>   ifm->ifm_media = oldmedia;
>   }
> 



Re: Tighten nl(1) pledge(2) a bit

2019-04-20 Thread Theo de Raadt
Rafael Neves  wrote:

> Hi tech@,
> 
> The Patch 1 below tighten pledge(2) promises to stdio, after the
> freopen(3) call,

I've commited this.

> and replaces an exit(3) call to return, so the
> stack protector could be used. 

I'm still not a huge fan of those.  I don't recall ever seeing
an overflow in such a circumstance.

> I verify that after pledge stdio, there are only calls to: 
> getline(3), memcmp(3), regexec(3), printf(3), fwrite(3), fputs(3),
> ferror(3), free(3), and err(3). All this functions do not need
> the rpath promise.
> 
> The Patch 2, includes Patch 1 and uses unveil(2) when the user supply
> a file. A prior version of this patch used unveil("/dev/null", "r")
> after the first pledge call, to forbid any filesystem access, except
> the file supplied. But it seemed like a hack.

Doing 1 unveil before 1 open, is pointless.  Instead, drop all path
pledges immediately afterwards.  Which is what "stdio" is about.



Re: libevent: Protect integer multiplications (min_heap)

2019-04-20 Thread Ted Unangst
Tobias Stoeckmann wrote:
> I would like to protect min_heap_push against integer overflows,
> which could either be triggered on a 64 bit system with massive
> amounts of RAM (to overflow s->n) or on a 32 bit system with tight
> memory layout (overflowing a * sizeof *p).
> 
> Both cases are basically not possible to be triggered, but I prefer
> to have reallocarray in place to be sure about it.

ok, so back to this. here's a diff which solves this by using appropriate
size_t types.

Note the first chunk changes the size of struct event, so this is a library
ABI change. (Maybe it's padded? I don't feel like digging that deep.)

Index: event.h
===
RCS file: /cvs/src/lib/libevent/event.h,v
retrieving revision 1.30
diff -u -p -r1.30 event.h
--- event.h 5 Jan 2015 23:14:36 -   1.30
+++ event.h 20 Apr 2019 23:28:09 -
@@ -196,7 +196,7 @@ struct event {
TAILQ_ENTRY (event) ev_next;
TAILQ_ENTRY (event) ev_active_next;
TAILQ_ENTRY (event) ev_signal_next;
-   unsigned int min_heap_idx;  /* for managing timeouts */
+   size_t min_heap_idx;/* for managing timeouts */
 
struct event_base *ev_base;
 
Index: min_heap.h
===
RCS file: /cvs/src/lib/libevent/min_heap.h,v
retrieving revision 1.5
diff -u -p -r1.5 min_heap.h
--- min_heap.h  20 Apr 2019 23:22:28 -  1.5
+++ min_heap.h  20 Apr 2019 23:28:09 -
@@ -33,7 +33,7 @@
 
 typedef struct min_heap {
struct event **p;
-   unsigned n, a;
+   size_t n, a;
 } min_heap_t;
 
 static inline void min_heap_ctor(min_heap_t * s);
@@ -41,14 +41,14 @@ static inline void min_heap_dtor(min_hea
 static inline void min_heap_elem_init(struct event * e);
 static inline int min_heap_elem_greater(struct event * a, struct event * b);
 static inline int min_heap_empty(min_heap_t * s);
-static inline unsigned min_heap_size(min_heap_t * s);
+static inline size_t min_heap_size(min_heap_t * s);
 static inline struct event *min_heap_top(min_heap_t * s);
-static inline int min_heap_reserve(min_heap_t * s, unsigned n);
+static inline int min_heap_reserve(min_heap_t * s, size_t n);
 static inline int min_heap_push(min_heap_t * s, struct event * e);
 static inline struct event *min_heap_pop(min_heap_t * s);
 static inline int min_heap_erase(min_heap_t * s, struct event * e);
-static inline void min_heap_shift_up_(min_heap_t * s, unsigned hole_index, 
struct event * e);
-static inline void min_heap_shift_down_(min_heap_t * s, unsigned hole_index, 
struct event * e);
+static inline void min_heap_shift_up_(min_heap_t * s, size_t hole_index, 
struct event * e);
+static inline void min_heap_shift_down_(min_heap_t * s, size_t hole_index, 
struct event * e);
 
 int 
 min_heap_elem_greater(struct event * a, struct event * b)
@@ -77,7 +77,7 @@ min_heap_empty(min_heap_t * s)
 {
return 0u == s->n;
 }
-unsigned 
+size_t 
 min_heap_size(min_heap_t * s)
 {
return s->n;
@@ -112,9 +112,9 @@ min_heap_pop(min_heap_t * s)
 int 
 min_heap_erase(min_heap_t * s, struct event * e)
 {
-   if (((unsigned int)-1) != e->min_heap_idx) {
+   if (e->min_heap_idx != -1) {
struct event *last = s->p[--s->n];
-   unsigned parent = (e->min_heap_idx - 1) / 2;
+   size_t parent = (e->min_heap_idx - 1) / 2;
/*
 * we replace e with the last element in the heap.  We might
 * need to shift it upward if it is less than its parent, or
@@ -133,14 +133,14 @@ min_heap_erase(min_heap_t * s, struct ev
 }
 
 int 
-min_heap_reserve(min_heap_t * s, unsigned n)
+min_heap_reserve(min_heap_t * s, size_t n)
 {
if (s->a < n) {
struct event **p;
-   unsigned a = s->a ? s->a * 2 : 8;
+   size_t a = s->a ? s->a * 2 : 8;
if (a < n)
a = n;
-   if (!(p = realloc(s->p, a * sizeof *p)))
+   if (!(p = reallocarray(s->p, a, sizeof *p)))
return -1;
s->p = p;
s->a = a;
@@ -149,9 +149,9 @@ min_heap_reserve(min_heap_t * s, unsigne
 }
 
 void 
-min_heap_shift_up_(min_heap_t * s, unsigned hole_index, struct event * e)
+min_heap_shift_up_(min_heap_t * s, size_t hole_index, struct event * e)
 {
-   unsigned parent = (hole_index - 1) / 2;
+   size_t parent = (hole_index - 1) / 2;
while (hole_index && min_heap_elem_greater(s->p[parent], e)) {
s->p[hole_index] = s->p[parent];
s->p[hole_index]->min_heap_idx = hole_index;
@@ -163,9 +163,9 @@ min_heap_shift_up_(min_heap_t * s, unsig
 }
 
 void 
-min_heap_shift_down_(min_heap_t * s, unsigned hole_index, struct event * e)
+min_heap_shift_down_(min_heap_t * s, size_t hole_index, struct event * e)
 {
-   unsigned min_child = 2 * (hole_index + 1);
+   size_t min_child = 2 * (hole_index + 1);

Tighten nl(1) pledge(2) a bit

2019-04-20 Thread Rafael Neves
Hi tech@,

The Patch 1 below tighten pledge(2) promises to stdio, after the
freopen(3) call, and replaces an exit(3) call to return, so the
stack protector could be used. 

I verify that after pledge stdio, there are only calls to: 
getline(3), memcmp(3), regexec(3), printf(3), fwrite(3), fputs(3),
ferror(3), free(3), and err(3). All this functions do not need
the rpath promise.

The Patch 2, includes Patch 1 and uses unveil(2) when the user supply
a file. A prior version of this patch used unveil("/dev/null", "r")
after the first pledge call, to forbid any filesystem access, except
the file supplied. But it seemed like a hack.


Comments?

Regards,
Rafael Neves




Patch 1 (just pledge):

Index: usr.bin/nl/nl.c
===
RCS file: /cvs/src/usr.bin/nl/nl.c,v
retrieving revision 1.6
diff -u -p -r1.6 nl.c
--- usr.bin/nl/nl.c 9 Oct 2015 01:37:08 -   1.6
+++ usr.bin/nl/nl.c 20 Apr 2019 21:27:39 -
@@ -218,6 +218,9 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
 
+   if (pledge("stdio", NULL) == -1)
+   err(1, "pledge");
+
/* Generate the delimiter sequence */
memcpy(delim, delim1, delim1len);
memcpy(delim + delim1len, delim2, delim2len);
@@ -226,7 +229,7 @@ main(int argc, char *argv[])
/* Do the work. */
filter();
 
-   exit(EXIT_SUCCESS);
+   return(EXIT_SUCCESS);
 }
 
 void



Pledge 2 (pledge and unveil):

Index: usr.bin/nl/nl.c
===
RCS file: /cvs/src/usr.bin/nl/nl.c,v
retrieving revision 1.6
diff -u -p -r1.6 nl.c
--- usr.bin/nl/nl.c 9 Oct 2015 01:37:08 -   1.6
+++ usr.bin/nl/nl.c 20 Apr 2019 21:28:44 -
@@ -118,7 +118,7 @@ main(int argc, char *argv[])
 
(void)setlocale(LC_ALL, "");
 
-   if (pledge("stdio rpath", NULL) == -1)
+   if (pledge("stdio unveil rpath", NULL) == -1)
err(1, "pledge");
 
while ((c = getopt(argc, argv, "pb:d:f:h:i:l:n:s:v:w:")) != -1) {
@@ -209,8 +209,14 @@ main(int argc, char *argv[])
case 0:
break;
case 1:
-   if (strcmp(argv[0], "-") != 0 &&
-   freopen(argv[0], "r", stdin) == NULL)
+   if (strcmp(argv[0], "-") == 0)
+   break;
+
+   /* Let freopen(3) check deal with permission problems. */
+   if (unveil(argv[0], "r") == -1 && errno != ENOENT)
+   err(1, "unveil");
+
+   if (freopen(argv[0], "r", stdin) == NULL)
err(EXIT_FAILURE, "%s", argv[0]);
break;
default:
@@ -218,6 +224,9 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
 
+   if (pledge("stdio", NULL) == -1)
+   err(1, "pledge");
+
/* Generate the delimiter sequence */
memcpy(delim, delim1, delim1len);
memcpy(delim + delim1len, delim2, delim2len);
@@ -226,7 +235,7 @@ main(int argc, char *argv[])
/* Do the work. */
filter();
 
-   exit(EXIT_SUCCESS);
+   return(EXIT_SUCCESS);
 }
 
 void