Re: Fix error code for ELF

2013-11-21 Thread Maxime Villard
Le 05/10/2013 23:10, Todd C. Miller a écrit :
> That looks reasonable to me.  I can't think of a reason to not
> return the proper errno values, especially as things like ENOMEM
> are already documented for execve(2).
> 
>  - todd
> 

up...



Re: [PATCH] ELF: ensure PT_INTERP strings are NULL-terminated

2013-11-21 Thread Maxime Villard
Le 06/10/2013 01:09, Kenneth R Westerback a écrit :
> On Sat, Oct 05, 2013 at 03:22:36PM -0600, Todd C. Miller wrote:
>> On Wed, 28 Aug 2013 22:34:26 -0400, Kenneth R Westerback wrote:
>>
 @@ -552,11 +552,16 @@ ELFNAME2(exec,makecmds)(struct proc *p, 
  
for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) {
if (pp->p_type == PT_INTERP && !interp) {
 -  if (pp->p_filesz >= MAXPATHLEN)
 +  if (pp->p_filesz < 2 || pp->p_filesz >= MAXPATHLEN)
>>>
>>> Still think you're depriving yourself of one character out by using
>>> ">=" instead of ">".
>>
>> I'm not sure about this.  We want to limit the path length to
>> MAXPATHLEN-1 since we include the NUL terminator in MAXPATHLEN.
>> The buffer we get from namei_pool is MAXPATHLEN long and the
>> read_from() function just calls vn_rdwr().  If we allow interp to
>> be MAXPATHLEN, is there any guarantee that it will end in a NUL
>> byte?
>>
>>  - todd

since get_pool() is not given PR_ZERO, interp won't be zeroed. So even
with the '>=', there's no guarantee that it will end in a NUL byte.

p_filesz includes the last '\0'; there's no problem with changing '>='
to '>'.

> 
> My reading at the time convinced me that p_filesz also includes the NUL. So
> using >= left room for two NULs.
> 
> But I am not trying to hold up either version, since I don't really
> understand the relevant code. :-)
> 
>  Ken
> 



Re: hiding struct ifnet diff #4v1: if_var.h

2013-11-21 Thread Stuart Henderson
On 2013/11/21 16:51, Mike Belopuhov wrote:
> any objections for this to go in?  any ok's?
> 
> i've looked through some of the ports and it's not that bad since
> freebsd already has an if_var.h so lots of ports have logic to
> pick it up (e.g. net-snmp)

I'm starting a test ports build soon with this in.



Re: wpi(4) fatal firmware error workaround

2013-11-21 Thread Chris Cappuccio
Mark Kettenis [mark.kette...@xs4all.nl] wrote:
> Now that wpi(4) does 802.11a, and I'm using my old laptop to test
> inteldrm(4) diffs, I got annoyed that from time to time wpi(4) craps
> out and I have to get out of my lazy chair to bring the interface back
> up.  So here's a diff that automatically reinitializes the hardware if
> this happens. 
> 
> ok?
> 

I love you.



wpi(4) fatal firmware error workaround

2013-11-21 Thread Mark Kettenis
Now that wpi(4) does 802.11a, and I'm using my old laptop to test
inteldrm(4) diffs, I got annoyed that from time to time wpi(4) craps
out and I have to get out of my lazy chair to bring the interface back
up.  So here's a diff that automatically reinitializes the hardware if
this happens. 

ok?

P.S. I'm planning to make similar changes to the related drivers for
  other Intel wireless chips once this has been reviewed.

Index: if_wpi.c
===
RCS file: /cvs/src/sys/dev/pci/if_wpi.c,v
retrieving revision 1.115
diff -u -p -r1.115 if_wpi.c
--- if_wpi.c16 Nov 2013 12:46:29 -  1.115
+++ if_wpi.c21 Nov 2013 20:10:21 -
@@ -75,7 +75,8 @@ void  wpi_radiotap_attach(struct wpi_sof
 #endif
 intwpi_detach(struct device *, int);
 intwpi_activate(struct device *, int);
-void   wpi_resume(void *, void *);
+void   wpi_resume(struct wpi_softc *);
+void   wpi_init_task(void *, void *);
 intwpi_nic_lock(struct wpi_softc *);
 intwpi_read_prom_data(struct wpi_softc *, uint32_t, void *, int);
 intwpi_dma_contig_alloc(bus_dma_tag_t, struct wpi_dma_info *,
@@ -189,8 +190,6 @@ wpi_attach(struct device *parent, struct
sc->sc_pcitag = pa->pa_tag;
sc->sc_dmat = pa->pa_dmat;
 
-   task_set(&sc->sc_resume_t, wpi_resume, sc, NULL);
-
/*
 * Get the offset of the PCI Express Capability Structure in PCI
 * Configuration Space (the vendor driver hard-codes it as E0h.)
@@ -327,6 +326,7 @@ wpi_attach(struct device *parent, struct
wpi_radiotap_attach(sc);
 #endif
timeout_set(&sc->calib_to, wpi_calib_timeout, sc);
+   task_set(&sc->init_task, wpi_init_task, sc, NULL);
return;
 
/* Free allocated memory if something failed during attachment. */
@@ -364,6 +364,7 @@ wpi_detach(struct device *self, int flag
int qid;
 
timeout_del(&sc->calib_to);
+   task_del(systq, &sc->init_task);
 
/* Uninstall interrupt handler. */
if (sc->sc_ih != NULL)
@@ -396,7 +397,7 @@ wpi_activate(struct device *self, int ac
wpi_stop(ifp, 0);
break;
case DVACT_RESUME:
-   task_add(systq, &sc->sc_resume_t);
+   wpi_resume(sc);
break;
}
 
@@ -404,24 +405,31 @@ wpi_activate(struct device *self, int ac
 }
 
 void
-wpi_resume(void *arg1, void *arg2)
+wpi_resume(struct wpi_softc *sc)
 {
-   struct wpi_softc *sc = arg1;
-   struct ifnet *ifp = &sc->sc_ic.ic_if;
pcireg_t reg;
-   int s;
 
/* Clear device-specific "PCI retry timeout" register (41h). */
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
reg &= ~0xff00;
pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg);
 
+   task_add(systq, &sc->init_task);
+}
+
+void
+wpi_init_task(void *arg1, void *args2)
+{
+   struct wpi_softc *sc = arg1;
+   struct ifnet *ifp = &sc->sc_ic.ic_if;
+   int s;
+
s = splnet();
while (sc->sc_flags & WPI_FLAG_BUSY)
tsleep(&sc->sc_flags, 0, "wpipwr", 0);
sc->sc_flags |= WPI_FLAG_BUSY;
 
-   if (ifp->if_flags & IFF_UP)
+   if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
wpi_init(ifp);
 
sc->sc_flags &= ~WPI_FLAG_BUSY;
@@ -1620,8 +1628,8 @@ wpi_intr(void *arg)
printf("%s: fatal firmware error\n", sc->sc_dev.dv_xname);
/* Dump firmware error log and stop. */
wpi_fatal_intr(sc);
-   ifp->if_flags &= ~IFF_UP;
wpi_stop(ifp, 1);
+   task_add(systq, &sc->init_task);
return 1;
}
if ((r1 & (WPI_INT_FH_RX | WPI_INT_SW_RX)) ||
Index: if_wpivar.h
===
RCS file: /cvs/src/sys/dev/pci/if_wpivar.h,v
retrieving revision 1.24
diff -u -p -r1.24 if_wpivar.h
--- if_wpivar.h 14 Nov 2013 12:34:30 -  1.24
+++ if_wpivar.h 21 Nov 2013 20:10:21 -
@@ -166,6 +166,8 @@ struct wpi_softc {
struct timeout  calib_to;
int calib_cnt;
 
+   struct task init_task;
+
struct wpi_fw_info  fw;
uint32_terrptr;
 
@@ -180,7 +182,6 @@ struct wpi_softc {
int8_t  maxpwr[IEEE80211_CHAN_MAX];
 
int sc_tx_timer;
-   struct task sc_resume_t;
 
 #if NBPFILTER > 0
caddr_t sc_drvbpf;



Re: hiding struct ifnet diff #4v1: if_var.h

2013-11-21 Thread Mike Belopuhov
On Mon, Nov 18, 2013 at 19:07 +0100, Mike Belopuhov wrote:
> This diff splits kernel visible parts away from if.h into a separate
> header if_var.h.  As a compatibility goo for the kernel if.h will
> also include if_var.h under _KERNEL.  The benefit of going this way
> is that we don't need to define _KERNEL in the netstat & friends
> (a tradeoff is that they will have to include if_var.h directly)
> and that if.h doesn't become a mess.  I will post a different diff
> later (v2) that will keep all the parts in one header under ifdefs.
> However the extent of changes will be essentially the same.  Then
> we'll pick whichever we like best.
> 

and since it turns out that this diff is winning the race, we can
improve it a little bit by hiding IF_* macros under _KERNEL.

any objections for this to go in?  any ok's?

i've looked through some of the ports and it's not that bad since
freebsd already has an if_var.h so lots of ports have logic to
pick it up (e.g. net-snmp)

diff --git sys/net/if.h sys/net/if.h
index b7d1b3c..d11ace2 100644
--- sys/net/if.h
+++ sys/net/if.h
@@ -1,10 +1,9 @@
 /* $OpenBSD: if.h,v 1.152 2013/11/09 06:38:42 dlg Exp $*/
 /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $  */
 
 /*
- * Copyright (c) 2012-2013 Henning Brauer 
  * Copyright (c) 1982, 1986, 1989, 1993
  * The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -58,69 +57,10 @@ voidif_freenameindex(struct if_nameindex *);
 __END_DECLS
 #endif
 
 #if __BSD_VISIBLE
 
-#include 
-#include 
-#include 
-#ifdef _KERNEL
-#include 
-#endif
-
-/*
- * Structures defining a network interface, providing a packet
- * transport mechanism (ala level 0 of the PUP protocols).
- *
- * Each interface accepts output datagrams of a specified maximum
- * length, and provides higher level routines with input datagrams
- * received from its medium.
- *
- * Output occurs when the routine if_output is called, with four parameters:
- * (*ifp->if_output)(ifp, m, dst, rt)
- * Here m is the mbuf chain to be sent and dst is the destination address.
- * The output routine encapsulates the supplied datagram if necessary,
- * and then transmits it on its medium.
- *
- * On input, each interface unwraps the data received by it, and either
- * places it on the input queue of an internetwork datagram routine
- * and posts the associated software interrupt, or passes the datagram to a raw
- * packet input routine.
- *
- * Routines exist for locating interfaces by their addresses
- * or for locating an interface on a certain network, as well as more general
- * routing and gateway routines maintaining information used to locate
- * interfaces.  These routines live in the files if.c and route.c
- */
-
-#include 
-
-struct mbuf;
-struct proc;
-struct rtentry;
-struct socket;
-struct ether_header;
-struct arpcom;
-struct rt_addrinfo;
-struct ifnet;
-struct hfsc_if;
-
-/*
- * Structure describing a `cloning' interface.
- */
-struct if_clone {
-   LIST_ENTRY(if_clone) ifc_list;  /* on list of cloners */
-   const char *ifc_name;   /* name of device, e.g. `gif' */
-   size_t ifc_namelen; /* length of name */
-
-   int (*ifc_create)(struct if_clone *, int);
-   int (*ifc_destroy)(struct ifnet *);
-};
-
-#defineIF_CLONE_INITIALIZER(name, create, destroy) 
\
-   { { 0 }, name, sizeof(name) - 1, create, destroy }
-
 /*
  * Structure used to query names of interface cloners.
  */
 struct if_clonereq {
int ifcr_total; /* total cloners (out) */
@@ -173,26 +113,10 @@ structif_data {
 #define IFQ_NQUEUES8
 #define IFQ_MAXPRIOIFQ_NQUEUES - 1
 #define IFQ_DEFPRIO3
 
 /*
- * Structure defining a queue for a network interface.
- * XXX keep in sync with struct ifaltq.
- */
-struct ifqueue {
-   struct {
-   struct  mbuf *head;
-   struct  mbuf *tail;
-   }ifq_q[IFQ_NQUEUES];
-   int  ifq_len;
-   int  ifq_maxlen;
-   int  ifq_drops;
-   struct hfsc_if  *ifq_hfsc;
-   struct timeout  *ifq_congestion;
-};
-
-/*
  * Values for if_link_state.
  */
 #define LINK_STATE_UNKNOWN 0   /* link unknown */
 #define LINK_STATE_INVALID 1   /* link invalid */
 #define LINK_STATE_DOWN2   /* link is down */
@@ -214,12 +138,11 @@ struct if_status_description {
 };
 
 #define LINK_STATE_DESC_MATCH(_ifs, _t, _s)\
(((_ifs)->ifs_type == (_t) || (_ifs)->ifs_type == 0) && \
(_ifs)->ifs_state == (_s))
-   
-   
+
 
 #define LINK_STATE_DESCRIPTIONS {  \
{ IFT_ETHER, LINK_STATE_DOWN, "no carrier" },

Re: new queue support for systat(1)

2013-11-21 Thread Alexey E. Suslikov
Arto Jonsson  kapsi.fi> writes:

> the following adds new queue support for systat(1). Both old and new
> queues are shown in the same display (newqs are shown first). Majority
> of the code taken from pfctl.

I would love to see prio support too :)



new queue support for systat(1)

2013-11-21 Thread Arto Jonsson
Hi,

the following adds new queue support for systat(1). Both old and new
queues are shown in the same display (newqs are shown first). Majority
of the code taken from pfctl.

For new queues the BW field only shows the target bandwidth (no burst
info for example).

Index: pftop.c
===
RCS file: /cvs/src/usr.bin/systat/pftop.c,v
retrieving revision 1.21
diff -u -p -r1.21 pftop.c
--- pftop.c 12 Oct 2013 12:17:32 -  1.21
+++ pftop.c 21 Nov 2013 10:23:10 -
@@ -46,6 +46,8 @@
 #include 
 #include 
 
+#include 
+
 #include 
 #include 
 #include 
@@ -115,6 +117,7 @@ u_int32_t num_states = 0;
 u_int32_t num_states_all = 0;
 u_int32_t num_rules = 0;
 u_int32_t num_queues = 0;
+u_int32_t num_altqs = 0;
 int cachestates = 0;
 
 char *filter_string = NULL;
@@ -303,7 +306,7 @@ union class_stats {
struct hfsc_classstats  hfsc_stats;
 };
 
-struct queue_stats {
+struct altq_stats {
union class_statsdata;
struct timeval   timestamp;
u_int8_t valid;
@@ -314,12 +317,28 @@ struct pf_altq_node {
struct pf_altq_node *next;
struct pf_altq_node *children;
struct pf_altq_node *next_flat;
-   struct queue_stats   qstats;
-   struct queue_stats   qstats_last;
+   struct altq_statsqstats;
+   struct altq_statsqstats_last;
u_int8_t depth;
u_int8_t visited;
 };
 
+/* queue structures from pfctl */
+
+struct queue_stats {
+   struct hfsc_class_stats  data;
+   int  valid;
+   struct timeval   timestamp;
+};
+
+struct pfctl_queue_node {
+   TAILQ_ENTRY(pfctl_queue_node)   entries;
+   struct pf_queuespec qs;
+   struct queue_stats  qstats;
+   struct queue_stats  qstats_last;
+   int depth;
+};
+TAILQ_HEAD(qnodes, pfctl_queue_node) qnodes = TAILQ_HEAD_INITIALIZER(qnodes);
 
 /* ordering functions */
 
@@ -1515,7 +1534,7 @@ pfctl_find_altq_node(struct pf_altq_node
 
 void
 pfctl_insert_altq_node(struct pf_altq_node **root,
-const struct pf_altq altq, const struct queue_stats qstats)
+const struct pf_altq altq, const struct altq_stats qstats)
 {
struct pf_altq_node *node;
 
@@ -1569,14 +1588,106 @@ pfctl_set_next_flat(struct pf_altq_node 
}
 }
 
+struct pfctl_queue_node *
+pfctl_find_queue_node(const char *qname, const char *ifname)
+{
+   struct pfctl_queue_node *node;
+
+   TAILQ_FOREACH(node, &qnodes, entries)
+   if (!strcmp(node->qs.qname, qname)
+   && !(strcmp(node->qs.ifname, ifname)))
+   return (node);
+   return (NULL);
+}
+
+void
+pfctl_insert_queue_node(const struct pf_queuespec qs,
+const struct queue_stats qstats)
+{
+   struct pfctl_queue_node *node, *parent;
+
+   node = calloc(1, sizeof(struct pfctl_queue_node));
+   if (node == NULL)
+   err(1, "pfctl_insert_queue_node: calloc");
+   memcpy(&node->qs, &qs, sizeof(qs));
+   memcpy(&node->qstats, &qstats, sizeof(qstats));
+
+   if (node->qs.parent[0]) {
+   parent = pfctl_find_queue_node(node->qs.parent,
+   node->qs.ifname);
+   if (parent)
+   node->depth = parent->depth + 1;
+   }
+
+   TAILQ_INSERT_TAIL(&qnodes, node, entries);
+}
+
+int
+pfctl_update_qstats(void)
+{
+   struct pfctl_queue_node *node;
+   struct pfioc_queue   pq;
+   struct pfioc_qstats  pqs;
+   u_int32_tmnr, nr;
+   struct queue_stats   qstats;
+   static u_int32_t last_ticket;
+
+   memset(&pq, 0, sizeof(pq));
+   memset(&pqs, 0, sizeof(pqs));
+   memset(&qstats, 0, sizeof(qstats));
+
+   if (pf_dev < 0)
+   return (-1);
+
+   if (ioctl(pf_dev, DIOCGETQUEUES, &pq)) {
+   error("DIOCGETQUEUES: %s", strerror(errno));
+   return (-1);
+   }
+
+   /* if a new set is found, start over */
+   if (pq.ticket != last_ticket)
+   while ((node = TAILQ_FIRST(&qnodes)) != NULL)
+   TAILQ_REMOVE(&qnodes, node, entries);
+   last_ticket = pq.ticket;
+
+   num_queues = mnr = pq.nr;
+   for (nr = 0; nr < mnr; ++nr) {
+   pqs.nr = nr;
+   pqs.ticket = pq.ticket;
+   pqs.buf = &qstats.data;
+   pqs.nbytes = sizeof(qstats.data);
+   if (ioctl(pf_dev, DIOCGETQSTATS, &pqs)) {
+   error("DIOCGETQSTATS: %s", strerror(errno));
+   return (-1);
+   }
+   if (pqs.queue.qname[0] != '_') {
+   if (pqs.queue.parent[0] && pqs.queue.parent[0] == '_')
+   pqs.queue.parent[0] = '\0';
+   qstats.v

Re: sem_open value

2013-11-21 Thread Vadim Zhukov
2013/11/21 Ted Unangst :
> Read the standard again and discovered some more missing features.
>
> 1. sem_open allows setting the value via a fourth argument. Fixed.
>
> 2. Multiple sem_open calls of the same path in the same process are
> supposed to return the same pointer. Not the same semaphore, the same
> pointer. This is mind boggling and hard to accomplish with this
> implementation. Not fixed.
>
> 3. There are also some requirements that sem_open be atomic in
> ways that it is not. We're publishing, via the filesystem, the new
> semaphore before we're done initializing it. This is fixable, but
> requires bizarro filesystem rename hijinks. Maybe another diff.

And we also could return some errors that are not specified in POSIX,
too (I've added XXX for the path I found, there could be others). Not
sure, what's worse: not following standard or hiding errors.

> Index: rthread_sem.c
> ===
> RCS file: /cvs/src/lib/librthread/rthread_sem.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 rthread_sem.c
> --- rthread_sem.c   20 Nov 2013 23:18:17 -  1.13
> +++ rthread_sem.c   21 Nov 2013 03:34:03 -
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -315,12 +316,22 @@ sem_open(const char *name, int oflag, ..
> int created = 0, fd, oerrno;
> sem_t sem;
> sem_t *semp = SEM_FAILED;
> +   mode_t unusedmode;
> +   unsigned value = 0;
>
> if (oflag & ~(O_CREAT | O_EXCL)) {
> errno = EINVAL;
> return (semp);
> }
>
> +   if (oflag & O_CREAT) {
> +   va_list ap;
> +   va_start(ap, oflag);
> +   unusedmode = va_arg(ap, mode_t);
> +   value = va_arg(ap, unsigned);
> +   va_end(ap);
> +   }
> +
> makesempath(name, sempath, sizeof(sempath));
> fd = open(sempath, O_RDWR | O_NOFOLLOW | oflag, 0600);
> if (fd == -1)
> @@ -363,8 +374,10 @@ sem_open(const char *name, int oflag, ..
> errno = oerrno;
> return (semp);
> }
> -   if (created)
> +   if (created) {
> sem->lock = _SPINLOCK_UNLOCKED_ASSIGN;
> +   sem->value = value;
> +   }
> sem->shared = 1;
> semp = malloc(sizeof(*semp));
> if (!semp) {
> @@ -382,7 +395,7 @@ int
>  sem_close(sem_t *semp)
>  {
> sem_t sem;
> -
> +
> if (!semp || !(sem = *semp) || !sem->shared) {
> errno = EINVAL;
> return (-1);
>

okay zhuk@