Re: POSIX-compliant page fault error codes

2014-06-24 Thread Theo de Raadt
Matthew -- fine, you collected information.  Thank you.

It is quite clear that POSIX set in stone an accident, a significant
error in my opinion.  Anyone with enough expertise can recognize this
is an accident in the SVR4 codebase, which ended up being "ratified"
(in quotes, because the more mistakes you make, the less value there
is).  This specific refinement may help a few pieces of code which
require specific detail in siginfo, but it introduces a lot more
accidental risk in those which only use the signal number/handler.

It is complicated enough that it requires experts to review how
(typically poorly) programs (written by non-experts) use signals to
deal with this added kernel behaviour.

As in, it is bad enough that I am scared even for the way that SIGBUS
and SIGSEGV handlers in crap programs in base handle it.  The issue of
unsafe terminal signal handlers returns IN FORCE, and we need to cope
with those.  Nothing ever changes, noone ever learns, noone cares.

Where we go from continues to be a big question mark.  Compatible?
one issue.. not compatible?   another issue..  Thanks POSIX, whoever
you are.  What favors did you do us recently?



Re: POSIX-compliant page fault error codes

2014-06-24 Thread Matthew Dempsky
On Tue, Jun 24, 2014 at 11:04:10AM -0700, Matthew Dempsky wrote:
>   SIGBUS/BUS_ADRERR: Accessing a mapped page that exceeds the end of
>   the underlying mapped file.

Generating SIGBUS for this case has proven controversial due to
concern that this is Linux invented behavior and not compatible with
Solaris, so I decided to collect some more background information on
the subject.

- SunOS 4.1.3's mmap() manual specifies: "Any reference to addresses
beyond the end of the object, however, will result in the delivery of
a SIGBUS signal." This wording was relaxed to "SIGBUS or SIGSEGV" in
SunOS 5.6 and remains in current manuals. (I'm not sure, but I suspect
this may be to simply reflect that memory protection violations take
priority over bounds checking.)

  SunOS 4.1.3: 
http://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2&manpath=SunOS+4.1.3
  SunOS 5.6: 
http://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2&manpath=SunOS+5.6
  Solaris 11: http://docs.oracle.com/cd/E23824_01/html/821-1463/mmap-2.html

- Many other SVR-derived OSes similarly document SIGBUS in their
mmap() manuals too:

  AIX: 
http://www-01.ibm.com/support/knowledgecenter/ssw_aix_53/com.ibm.aix.basetechref/doc/basetrf1/mmap.htm?lang=en
  HPUX: 
http://h20566.www2.hp.com/portal/site/hpsc/template.BINARYPORTLET/public/kb/docDisplay/resource.process/?spf_p.tpst=kbDocDisplay_ws_BI&spf_p.rid_kbDocDisplay=docDisplayResURL&javax.portlet.begCacheTok=com.vignette.cachetoken&spf_p.rst_kbDocDisplay=wsrp-resourceState%3DdocId%253Demr_na-c02261243-2%257CdocLocale%253D&javax.portlet.endCacheTok=com.vignette.cachetoken
  UnixWare: http://uw714doc.sco.com/en/man/html.2/mmap.2.html

- This behavior has been (awkwardly) specified for mmap() since SUSv2:
"References within the address range starting at pa and continuing for
len bytes to whole pages following the end of an object shall result
in delivery of a SIGBUS signal." Later versions of POSIX have the same
wording.

  SUSv2: http://pubs.opengroup.org/onlinepubs/007908799/xsh/mmap.html
  POSIX.2001: http://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html
  POSIX.2008: 
http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html

- More generally, POSIX explains the SIGBUS/SIGSEGV distinction
thusly: "When an object is mapped, various application accesses to the
mapped region may result in signals. In this context, SIGBUS is used
to indicate an error using the mapped object, and SIGSEGV is used to
indicate a protection violation or misuse of an address." Specific
examples are provided too:

  Memory Protection: 
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_03_03



Re: audio(9) manual page

2014-06-24 Thread Alexander Polakov
* Jason McIntyre  [140625 00:41]:
> On Tue, Jun 24, 2014 at 09:13:47AM +0200, Alexandre Ratchov wrote:
> > I see what you mean. As the manual describes the interface between
> > two layers we may need to be more precise about who calls who.
> > Wouldn't the following be less ambigous?
> > 
> > When the hardware is ready to accept more samples the driver shall
> > call the
> > .Fa intr
> > function with the argument
> > .Fa intrarg .
> > 
> 
> the use of "will" is perfectly fine here - it's basically a conditional
> sentence structure.
> 
> "shall" sounds awful. it sounds formal, dated, and like a document
> produced by posix. please don;t make this change.
> 
> what is simpler, i think, and easier for most folks to understand, is
> using a present tense:
> 
>   When the hardware is ready to accept more samples,
>   the driver calls the
>   .Fa intr
>   function with the argument
>   .Fa intrarg .
>   
> it's all a matter of taste, i suppose, but present tense structure does
> seem to be easier to read for non-native speakers (in my experience).

I agree, this one looks even better.



newfs_msdos: proper boot signature

2014-06-24 Thread Tobias Stoeckmann
Hi,

time to merge another fix from NetBSD (and FreeBSD who applied it too):

If sector size is not 512, the boot signature is placed at a wrong
position.  It always has to be at offset 510/511, not sector size - 2.

# dd if=/dev/zero of=fat.iso bs=1M count=1
# vnconfig vnd0c fat.iso
# newfs_msdos -S 4096 vnd0c
/dev/rvnd0c: 2041 sectors in 2041 FAT12 clusters (4096 bytes/cluster)
bps=4096 spc=1 res=1 nft=2 rde=512 sec=2048 mid=0xf0 spf=1 spt=63 hds=1 hid=0
# fsck_msdos vnd0c
** /dev/rvnd0c (vnd0c)
Invalid signature in boot block: 

Also, the minimum allowed sector size is 512.


NetBSD (Revision 1.24):
Don't use negative offsets from "bpb.bps" when writing out values such
as DOSMAGIC in the MBR. In non-512 byte media, the MBR is still 512
bytes in length.

Based on the patches provided in PR kern/17398 by Trevin Beattie.

FreeBSD (Revision 170166):
The newfs_msdos utility does not store the boot signature in the
correct place on large sector disks.  The boot signature should be at
offset 0x1fe in the BPB; newfs_msdos currently stores it 2 bytes from
the end of the sector.

Taken from: NetBSD


Tobias

Index: newfs_msdos.8
===
RCS file: /cvs/src/sbin/newfs_msdos/newfs_msdos.8,v
retrieving revision 1.24
diff -u -p -r1.24 newfs_msdos.8
--- newfs_msdos.8   16 Jul 2013 09:45:28 -  1.24
+++ newfs_msdos.8   24 Jun 2014 19:20:35 -
@@ -134,7 +134,7 @@ Number of hidden sectors.
 Number of reserved sectors.
 .It Fl S Ar sector-size
 Number of bytes per sector.
-Acceptable values are powers of 2 in the range 128 through 32768.
+Acceptable values are powers of 2 in the range 512 through 32768.
 .It Fl s Ar total
 File system size.
 .It Fl u Ar track-size
Index: newfs_msdos.c
===
RCS file: /cvs/src/sbin/newfs_msdos/newfs_msdos.c,v
retrieving revision 1.22
diff -u -p -r1.22 newfs_msdos.c
--- newfs_msdos.c   22 Nov 2013 04:14:01 -  1.22
+++ newfs_msdos.c   24 Jun 2014 19:20:35 -
@@ -50,7 +50,7 @@
 #define NPB  2 /* nibbles per byte */
 
 #define DOSMAGIC  0xaa55   /* DOS magic number */
-#define MINBPS   128   /* minimum bytes per sector */
+#define MINBPS   512   /* minimum bytes per sector */
 #define MAXSPC   128   /* maximum sectors per cluster */
 #define MAXNFT   16/* maximum number of FATs */
 #define DEFBLK   4096  /* default block size */
@@ -617,17 +617,17 @@ main(int argc, char *argv[])
setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
   sizeof(bs->oem));
memcpy(img + x1, bootcode, sizeof(bootcode));
-   mk2(img + bpb.bps - 2, DOSMAGIC);
+   mk2(img + MINBPS - 2, DOSMAGIC);
}
} else if (fat == 32 && bpb.infs != MAXU16 &&
   (lsn == bpb.infs ||
(bpb.bkbs != MAXU16 &&
 lsn == bpb.bkbs + bpb.infs))) {
mk4(img, 0x41615252);
-   mk4(img + bpb.bps - 28, 0x61417272);
-   mk4(img + bpb.bps - 24, 0x);
-   mk4(img + bpb.bps - 20, bpb.rdcl);
-   mk2(img + bpb.bps - 2, DOSMAGIC);
+   mk4(img + MINBPS - 28, 0x61417272);
+   mk4(img + MINBPS - 24, 0x);
+   mk4(img + MINBPS - 20, bpb.rdcl);
+   mk2(img + MINBPS - 2, DOSMAGIC);
} else if (lsn >= bpb.res && lsn < dir &&
   !((lsn - bpb.res) %
 (bpb.spf ? bpb.spf : bpb.bspf))) {



POSIX-compliant page fault error codes

2014-06-24 Thread Matthew Dempsky
POSIX specifies these error cases for memory faults:

  SIGSEGV/SEGV_MAPERR: Accessing an unmapped page.

  SIGSEGV/SEGV_ACCERR: Reading from a non-readable or writing to a
  non-writable page. 

  SIGBUS/BUS_ADRERR: Accessing a mapped page that exceeds the end of
  the underlying mapped file.

I added a regress test at regress/sys/kern/siginfo-fault to cover
these cases, but unfortunately we're non-compliant in a few ways, and
fixing it is somewhat MD.  With the diff below, the tests pass on
amd64, but other platforms will need similar changes.

Currently VM_PAGER_BAD is only returned by pgo_get() in the case of
uvn_get() trying to access a page beyond the end of the file, so this
diff changes uvm_fault() to recognize this and return ENOSPC
(arbitrary unused error code) and then the MD trap() code needs to
know to map this error to BUS_ADRERR.

Additionally, some MD trap()s already know to map EACCES to
SEGV_ACCERR instead of SEGV_MAPERR, but amd64 wasn't one of them.  So
this diff fixes that too.


Index: uvm/uvm_fault.c
===
RCS file: /home/matthew/cvs-mirror/cvs/src/sys/uvm/uvm_fault.c,v
retrieving revision 1.73
diff -u -p -r1.73 uvm_fault.c
--- uvm/uvm_fault.c 8 May 2014 20:08:50 -   1.73
+++ uvm/uvm_fault.c 23 Jun 2014 21:29:24 -
@@ -1125,7 +1125,8 @@ Case2:
goto ReFault;
}
 
-   return (EACCES); /* XXX i/o error */
+   /* XXX i/o error */
+   return (result == VM_PAGER_BAD ? ENOSPC : EACCES);
}
 
/* re-verify the state of the world.  */
Index: arch/amd64/amd64/trap.c
===
RCS file: /home/matthew/cvs-mirror/cvs/src/sys/arch/amd64/amd64/trap.c,v
retrieving revision 1.40
diff -u -p -r1.40 trap.c
--- arch/amd64/amd64/trap.c 15 Jun 2014 11:43:24 -  1.40
+++ arch/amd64/amd64/trap.c 23 Jun 2014 21:38:31 -
@@ -387,9 +387,6 @@ faultcommon:
KERNEL_UNLOCK();
goto out;
}
-   if (error == EACCES) {
-   error = EFAULT;
-   }
 
if (type == T_PAGEFLT) {
if (pcb->pcb_onfault != 0) {
@@ -407,13 +404,23 @@ faultcommon:
sv.sival_ptr = (void *)fa;
trapsignal(p, SIGKILL, T_PAGEFLT, SEGV_MAPERR, sv);
} else {
+   int signo, code;
+   if (error == ENOSPC) {
+   signo = SIGBUS;
+   code = BUS_ADRERR;
+   } else {
+   signo = SIGSEGV;
+   code = (error == EACCES) ? SEGV_ACCERR :
+   SEGV_MAPERR;
+   }
 #ifdef TRAP_SIGDEBUG
-   printf("pid %d (%s): SEGV at rip %lx addr %lx\n",
-   p->p_pid, p->p_comm, frame->tf_rip, fa);
+   printf("pid %d (%s): %s at rip %lx addr %lx\n",
+   p->p_pid, p->p_comm, (signo == SIGBUS) ?
+   "BUS" : "SEGV", frame->tf_rip, fa);
frame_dump(frame);
 #endif
sv.sival_ptr = (void *)fa;
-   trapsignal(p, SIGSEGV, T_PAGEFLT, SEGV_MAPERR, sv);
+   trapsignal(p, signo, T_PAGEFLT, code, sv);
}
KERNEL_UNLOCK();
break;



Re: PATCH: ftp: allow @ in username for Basic Auth

2014-06-24 Thread Philip Guenther
On Tue, Jun 24, 2014 at 9:01 AM, Sébastien Marie <
semarie-open...@latrappe.fr> wrote:

> As I see not activity or feedback for this one line patch, I think it
> need more explain ?
>

Sorry, the patch is incorrect; per RFC 3986, the parser is correct to split
the authority on the first '@'.  The correct method to include an '@' in
the userinfo part is to percent-encode it as %40.


Philip Guenther


Re: Undefined symbol in ld.so

2014-06-24 Thread William Orr
Whoops! Sorry for the confusion; disregard.

On Jun 24, 2014, at 3:31 AM, Otto Moerbeek  wrote:

> On Tue, Jun 24, 2014 at 01:30:55AM -0700, William Orr wrote:
> 
>> ld.so in -current isn't building right now, due to an undefined reference to
>> _dl_realloc caused by the recent addition of _dl_reallocarray. The following
>> diff implements _dl_realloc, largely copied from the implementation in
>> lib/libc/stdlib/malloc.c.
> 
> There are cvssync problems. The code in curent compiles fine.
> 
>   -Otto
> 
>> 
>> tested on amd64
>> 
>> Index: malloc.c
>> ===
>> RCS file: /cvs/src/libexec/ld.so/malloc.c,v
>> retrieving revision 1.1
>> diff -u -b -w -p -r1.1 malloc.c
>> --- malloc.c 5 Jun 2014 08:39:07 -   1.1
>> +++ malloc.c 24 Jun 2014 08:24:43 -
>> @@ -78,6 +78,12 @@
>> #define MMAP(sz) _dl_mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
>> MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
>> 
>> +#define MMAPA(a,sz) _dl_mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
>> +MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
>> +
>> +#define MQUERY(a, sz)   _dl_mquery((a), (size_t)(sz), PROT_READ | 
>> PROT_WRITE, \
>> +MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0)
>> +
>> #define MMAP_ERROR(p)(_dl_mmap_error(p) ? MAP_FAILED : (p))
>> 
>> struct region_info {
>> @@ -277,6 +283,26 @@ unmap(struct dir_info *d, void *p, size_
>>  wrterror("malloc cache overflow");
>> }
>> 
>> +static void
>> +zapcacheregion(struct dir_info *d, void *p, size_t len)
>> +{
>> +u_int i;
>> +struct region_info *r;
>> +size_t rsz;
>> +
>> +for (i = 0; i < mopts.malloc_cache; i++) {
>> +r = &d->free_regions[i];
>> +if (r->p >= p && r->p <= (void *)((char *)p + len)) {
>> +rsz = r->size << MALLOC_PAGESHIFT;
>> +if (_dl_munmap(r->p, rsz))
>> +wrterror("munmap");
>> +r->p = NULL;
>> +d->free_regions_size -= r->size;
>> +r->size = 0;
>> +}
>> +}
>> +}
>> +
>> static void *
>> map(struct dir_info *d, size_t sz, int zero_fill)
>> {
>> @@ -987,6 +1013,119 @@ _dl_free(void *ptr)
>>  malloc_active--;
>> }
>> 
>> +static void *
>> +orealloc(void *p, size_t newsz)
>> +{
>> +struct region_info *r;
>> +size_t oldsz, goldsz, gnewsz;
>> +void *q;
>> +
>> +if (p == NULL)
>> +return omalloc(newsz, 0);
>> +
>> +r = find(g_pool, p);
>> +if (r == NULL) {
>> +wrterror("bogus pointer (double free?)");
>> +return NULL;
>> +}
>> +if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE)
>> +return NULL;
>> +
>> +REALSIZE(oldsz, r);
>> +goldsz = oldsz;
>> +if (oldsz > MALLOC_MAXCHUNK) {
>> +if (oldsz < mopts.malloc_guard)
>> +wrterror("guard size");
>> +oldsz -= mopts.malloc_guard;
>> +}
>> +
>> +gnewsz = newsz;
>> +if (gnewsz > MALLOC_MAXCHUNK)
>> +gnewsz += mopts.malloc_guard;
>> +
>> +if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p) {
>> +size_t roldsz = PAGEROUND(goldsz);
>> +size_t rnewsz = PAGEROUND(gnewsz);
>> +
>> +if (rnewsz > roldsz) {
>> +if (!mopts.malloc_guard) {
>> +void *hint = (char *)p + roldsz;
>> +size_t needed = rnewsz - roldsz;
>> +
>> +zapcacheregion(g_pool, hint, needed);
>> +q = MQUERY(hint, needed);
>> +if (q == hint)
>> +q = MMAPA(hint, needed);
>> +else
>> +q = MAP_FAILED;
>> +if (q == hint) {
>> +if (mopts.malloc_junk == 2)
>> +_dl_memset(q, SOME_JUNK, 
>> needed);
>> +r->size = newsz;
>> +return p;
>> +} else if (q != MAP_FAILED) {
>> +if (_dl_munmap(q, needed))
>> +wrterror("munmap");
>> +}
>> +}
>> +} else if (rnewsz < roldsz) {
>> +if (mopts.malloc_guard) {
>> +if (_dl_mprotect((char *)p + roldsz -
>> +mopts.malloc_guard, mopts.malloc_guard,
>> +PROT_READ | PROT_WRITE))
>> +wrterror("mprotect");
>> +if (_dl_mprotect((char *)p + rnewsz -
>> +mopts.malloc_guard, mopts.malloc_guard,
>> +PROT_NO

Re: PATCH: ftp: allow @ in username for Basic Auth

2014-06-24 Thread Sébastien Marie
Hi,

As I see not activity or feedback for this one line patch, I think it
need more explain ?

Currently, when you pass an URL with user/pass embed, the code parse it
badly.

For example:
https://mym...@example.com:my-passw...@another-domain.example.com/blabla

Just before the code search if the supplied URL contains a user/pass,
the variables are:

scheme = "https://";
host = "mym...@example.com:my-passw...@another-domain.example.com"

The code use strchr(3) on host in order to find '@' in host variable,
and separate the user/pass component and the host component.

But, with strchr the result is:
p = "mymail"
host = "example.com:my-passw...@another-domain.example.com"

The patch replace strchr(3) by strrchr(3) to obtain:
p = "mym...@example.com:my-password"
host = "another-domain.example.com"

As the hostname should not contains '@' char, and user/pass may contains
it, (as defined by rfc1738), this patch make ftp(1) to more respect
standard.

Thanks.
-- 
Sébastien Marie

On Mon, Jun 23, 2014 at 10:15:25AM +0200, Sébastien Marie wrote:
> Hi,
> 
> Using ftp(1) with HTTP(S) scheme and Basic auth, it is currently not
> possible to have username (or password) with a '@' inner.
> 
> For example, this URI is badly parsed:
> ftp https://mym...@example.com:my-passw...@another-domain.example.com/blabla
> 
> According to RFC2617, '@' is a valid character in user-id or password:
>   user-pass   = userid ":" password
>   userid  = *
>   password= *TEXT
> 
> Here a patch to search the last '@' in the string (which don't contains
> the path at this time).
> 
> -- 
> Sébastien Marie
> 
> Index: fetch.c
> ===
> RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
> retrieving revision 1.122
> diff -u -p -r1.122 fetch.c
> --- fetch.c   20 May 2014 01:25:23 -  1.122
> +++ fetch.c   23 Jun 2014 07:46:33 -
> @@ -474,7 +474,7 @@ noslash:
>*/
>   if (proxyenv == NULL &&
>   (!strcmp(scheme, HTTP_URL) || !strcmp(scheme, HTTPS_URL))) {
> - if ((p = strchr(host, '@')) != NULL) {
> + if ((p = strrchr(host, '@')) != NULL) {
>   size_t authlen = (strlen(host) + 5) * 4 / 3;
>   *p = 0; /* Kill @ */
>   if ((auth = malloc(authlen)) == NULL)
> 



Re: infnan.3

2014-06-24 Thread Ingo Schwarze
Hi,

Theo de Raadt wrote on Tue, Jun 24, 2014 at 09:09:49AM -0600:
> Ingo Schwarze wrote:

>> It's obvious that whole page needs a content update by a VAX expert.

> that is correct.  All the rest of the discussion is moot.
> 
> Only miod and martynas can swing this the right way.
> 
> I disagree with Ted about making this a seperate page,

As i said before, infnan(3/vax) already *is* a separate,
architecture-specific, VAX-only page.

It is cross-referenced from various machine independent pages,
though.  I cannot miss the opportunity to show this off:

ischwarze@isnote $ apropos Xr=infnan
atanh, atanhf, atanhl(3) - inverse hyperbolic tangent functions
gamma, gammaf, lgamma, lgammaf, lgammal, tgamma, tgammaf, tgammal(3) - log 
gamma functions
exp, exp2, exp2f, exp2l, expf, expl, expm1, expm1f, expm1l, log, log10, log10f, 
log10l, log1p, log1pf, log1pl, log2, log2f, log2l, logf, logl, pow, powf, 
powl(3) - exponential, logarithm, power functions
asinh, asinhf, asinhl(3) - inverse hyperbolic sine functions
acosh, acoshf, acoshl(3) - inverse hyperbolic cosine functions

Yours,
  Ingo

> since that would remove a vital component of floating point
> knowledge from programmers, that being: not all floating point
> is the same, not all of it is ieee, and not even ieee implementaiton
> is consistant.  Some visibility must remain to show that there is
> sausage being made here.



Re: infnan.3

2014-06-24 Thread Theo de Raadt
> It's obvious that whole page needs a content update by a VAX expert.

that is correct.  All the rest of the discussion is moot.

Only miod and martynas can swing this the right way.

I disagree with Ted about making this a seperate page, since that
would remove a vital component of floating point knowledge from
programmers, that being: not all floating point is the same, not all
of it is ieee, and not even ieee implementaiton is consistant.  Some
visibility must remain to show that there is sausage being made here.



Re: pfctl: stricter redirect specs

2014-06-24 Thread Stuart Henderson
On 2014/06/24 15:07, Mike Belopuhov wrote:
> I propose to avoid the confusion by flagging such situations as
> errors, e.g.:
> 
>  % echo 'pass out nat-to { ::1 1.1.1.1 }' | ./obj/pfctl -o none -vnf - 
>  stdin:1: translation spec contains addresses with different address families
>  stdin:1: skipping rule due to errors
>  stdin:1: rule expands to no valid combination
> 
> While previously it would pick only one of them (the first one):

I agree with this change, it does need a warning in current.html to
avoid users being bitten by it (mostly this is likely when using interface
names e.g. "echo 'pass out nat-to lo0' | pfctl -vnf -"), however the
recent change to disabling ipv6 by default should reduce the impact of
this.



Re: pfctl: stricter redirect specs

2014-06-24 Thread Mike Belopuhov
On Tue, Jun 24, 2014 at 15:07 +0200, Mike Belopuhov wrote:
> I have carefully tested that and do not expect any unrelated
> fallout.  And for the reasons stated above I don't believe
> anyone is using this since it's largely error prone.
> 

and a regress chunk that avoids using such combination.

note that this diff basically finishes previous attemts at
modifying tests to match present syntax.

diff --git regress/sbin/pfctl/pf48.in regress/sbin/pfctl/pf48.in
index 540711a..a0dd143 100644
--- regress/sbin/pfctl/pf48.in
+++ regress/sbin/pfctl/pf48.in
@@ -1,12 +1,12 @@
 table < regress > { 1.2.3.4 !5.6.7.8 10/8 lo0 }
 table  const { ::1 fe80::/64 }
 table  { 1.2.3.4 !5.6.7.8 } { ::1 ::2 ::3 } file "/dev/null" const 
{ 4.3.2.1 }
-match out on lo0 from < regress.1> to  nat-to lo0:0
+match out on lo0 inet from < regress.1> to  nat-to lo0:0
 match out on !lo0 inet from ! to  nat-to lo0:0
 match in on lo0 inet6 from  to  rdr-to lo0:0
-match in on !lo0 from !< regress.1 > to  rdr-to lo0:0
+match in on !lo0 inet6 from !< regress.1 > to  rdr-to lo0:0
 match in from {  ! } to any
 match out from any to { !,  }
 pass in from  to any
 pass out from any to 
 pass in from {   } to any
diff --git regress/sbin/pfctl/pf48.loaded regress/sbin/pfctl/pf48.loaded
index 68b9854..cfdc8a2 100644
--- regress/sbin/pfctl/pf48.loaded
+++ regress/sbin/pfctl/pf48.loaded
@@ -1,7 +1,7 @@
-@0 match out on lo0 inet6 from  to  nat-to ::1
-  [ Skip steps: d=2 p=end da=4 sp=end dp=end ]
+@0 match out on lo0 inet from  to  nat-to 127.0.0.1
+  [ Skip steps: d=2 f=2 p=end da=4 sp=end dp=end ]
   [ queue: qname= qid=0 pqname= pqid=0 ]
   [ Evaluations: 0 Packets: 0 Bytes: 0   States: 0 
]
 @1 match out on ! lo0 inet from !  to  nat-to 
127.0.0.1
   [ Skip steps: p=end da=4 sp=end dp=end ]
   [ queue: qname= qid=0 pqname= pqid=0 ]
diff --git regress/sbin/pfctl/pf48.ok regress/sbin/pfctl/pf48.ok
index 5f6e6ab..aeccfcf 100644
--- regress/sbin/pfctl/pf48.ok
+++ regress/sbin/pfctl/pf48.ok
@@ -1,9 +1,9 @@
 table  { 1.2.3.4 !5.6.7.8 10.0.0.0/8 ::1 fe80::1 127.0.0.1 }
 table  const { ::1 fe80::/64 }
 table  const { 1.2.3.4 !5.6.7.8 ::1 ::2 ::3 } file "/dev/null" { 
4.3.2.1 }
-match out on lo0 inet6 from  to  nat-to ::1
+match out on lo0 inet from  to  nat-to 127.0.0.1
 match out on ! lo0 inet from !  to  nat-to 127.0.0.1
 match in on lo0 inet6 from  to  rdr-to ::1
 match in on ! lo0 inet6 from !  to  rdr-to ::1
 match in from  to any
 match in from !  to any
diff --git regress/sbin/pfctl/pf48.optimized regress/sbin/pfctl/pf48.optimized
index 63309a7..90e2036 100644
--- regress/sbin/pfctl/pf48.optimized
+++ regress/sbin/pfctl/pf48.optimized
@@ -1,7 +1,7 @@
-@0 match out on lo0 inet6 from  to  nat-to ::1
-  [ Skip steps: d=2 p=end da=4 sp=end dp=end ]
+@0 match out on lo0 inet from  to  nat-to 127.0.0.1
+  [ Skip steps: d=2 f=2 p=end da=4 sp=end dp=end ]
   [ queue: qname= qid=0 pqname= pqid=0 ]
   [ Evaluations: 0 Packets: 0 Bytes: 0   States: 0 
]
 @1 match out on ! lo0 inet from !  to  nat-to 
127.0.0.1
   [ Skip steps: p=end da=4 sp=end dp=end ]
   [ queue: qname= qid=0 pqname= pqid=0 ]
diff --git regress/sbin/pfctl/pf98.in regress/sbin/pfctl/pf98.in
index a18a491..a224f9e 100644
--- regress/sbin/pfctl/pf98.in
+++ regress/sbin/pfctl/pf98.in
@@ -1,4 +1,4 @@
 # Test rule order processing should pass (require-order no longer required)
 pass in on lo100 all
-match out on lo0 all nat-to lo0
+match out on lo0 inet6 all nat-to lo0
 



pfctl: stricter redirect specs

2014-06-24 Thread Mike Belopuhov
Hi,

Looking at some corner-cases I've realised that collapse_redirspec
does a poor job of weeding out incompatibilities in the redirect
pool specifications and hence inferring the rule address family
from it.

An example is a rule like this:

 pass out nat-to em0

Let's say that em0 has an IPv4 address 192.168.20.221 and an IPv6
link-local address fe80::221:86ff:fefa:5fc1.  What this rule is
supposed to do?  Since it cannot create two rules out of this
specification (the parser works), you have to choose whether this
will be an IPv4 rule or an IPv6 rule.  Quite some time ago for
some reasons it translated to an IPv4 rule:

 pass out inet nat-to 192.168.20.221

Then the behaviour was changed (rather silently) and now it
translates to an IPv6 rule:

 pass out inet6 nat-to fe80::221:86ff:fefa:5fc1

I think that both is somewhat unexpected, even less so the
current behaviour.

I propose to avoid the confusion by flagging such situations as
errors, e.g.:

 % echo 'pass out nat-to { ::1 1.1.1.1 }' | ./obj/pfctl -o none -vnf - 
 stdin:1: translation spec contains addresses with different address families
 stdin:1: skipping rule due to errors
 stdin:1: rule expands to no valid combination

While previously it would pick only one of them (the first one):

 % echo 'pass out nat-to { ::1 1.1.1.1 }' | pfctl -o none -vnf -  
 pass out inet6 all flags S/SA nat-to ::1

You are still able to use "em0" as a source/destination filter
however:

 % echo 'pass out from em0' | pfctl -o none -vnf -
 pass out on em0 inet6 from fe80::221:86ff:fefa:5fc1 to any flags S/SA
 pass out inet from 192.168.20.221 to any flags S/SA

meaning the diff only affects how nat-to/rdr-to pools are processed.

I have carefully tested that and do not expect any unrelated
fallout.  And for the reasons stated above I don't believe
anyone is using this since it's largely error prone.

OK?

P.S.

binat bzero'ing is actually necessary since otherwise it
contains garbage and we're now checking for it more carefully.

diff --git sbin/pfctl/parse.y sbin/pfctl/parse.y
index de9537e..ce80f8e 100644
--- sbin/pfctl/parse.y
+++ sbin/pfctl/parse.y
@@ -4295,11 +4295,11 @@ collapse_redirspec(struct pf_pool *rpool, struct 
pf_rule *r,
 struct redirspec *rs, u_int8_t allow_if)
 {
struct pf_opt_tbl *tbl = NULL;
struct node_host *h;
struct pf_rule_addr ra;
-   int i = 0;
+   int af = 0, i = 0;
 
if (!rs || !rs->rdr || rs->rdr->host == NULL) {
rpool->addr.type = PF_ADDR_NONE;
return (0);
}
@@ -4307,17 +4307,45 @@ collapse_redirspec(struct pf_pool *rpool, struct 
pf_rule *r,
if (r->rule_flag & PFRULE_AFTO)
r->naf = rs->af;
 
/* count matching addresses */
for (h = rs->rdr->host; h != NULL; h = h->next) {
-   if (!r->af || !h->af || rs->af || h->af == r->af) {
+   if (h->af) {
+   /* check that af-to target address has correct af */
+   if (rs->af && rs->af != h->af) {
+   yyerror("af mismatch in %s spec",
+   allow_if ? "routing" : "translation");
+   return (1);
+   }
+   /* skip if the rule af doesn't match redirect af */
+   if ((r->af && r->af != h->af) && /* exclude af-to */
+   !(r->naf && h->af == r->naf))
+   continue;
+   /*
+* fail if the chosen af is not universal for the
+* whole supplied redirect address pool
+*/
+   if (!r->af && af && af != h->af) {
+   yyerror("%s spec contains addresses with "
+   "different address families",
+   allow_if ? "routing" : "translation");
+   return (1);
+   }
+   if (!r->af)
+   af = h->af;
i++;
-   if (h->af && !r->af)
-   r->af = h->af;
-   } else if (r->naf && h->af == r->naf)
+   } else {
+   /*
+* we silently allow any not af-specific host specs,
+* e.g. (em0) and let the kernel deal with them
+*/
i++;
+   }
}
+   /* set rule af to one chosen above */
+   if (!r->af && af)
+   r->af = af;
 
if (i == 0) {   /* no pool address */
yyerror("af mismatch in %s spec",
allow_if ? "routing" : "translation");
return (1);
@@ -4695,10 +4723,11 @@ expand_rule(struct pf_rule *r, int keeprule, struct 
node_if *interfaces,
  

Re: Undefined symbol in ld.so

2014-06-24 Thread Otto Moerbeek
On Tue, Jun 24, 2014 at 01:30:55AM -0700, William Orr wrote:

> ld.so in -current isn't building right now, due to an undefined reference to
> _dl_realloc caused by the recent addition of _dl_reallocarray. The following
> diff implements _dl_realloc, largely copied from the implementation in
> lib/libc/stdlib/malloc.c.

There are cvssync problems. The code in curent compiles fine.

-Otto

> 
> tested on amd64
> 
> Index: malloc.c
> ===
> RCS file: /cvs/src/libexec/ld.so/malloc.c,v
> retrieving revision 1.1
> diff -u -b -w -p -r1.1 malloc.c
> --- malloc.c  5 Jun 2014 08:39:07 -   1.1
> +++ malloc.c  24 Jun 2014 08:24:43 -
> @@ -78,6 +78,12 @@
>  #define MMAP(sz) _dl_mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
>  MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
>  
> +#define MMAPA(a,sz)  _dl_mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
> +MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
> +
> +#define MQUERY(a, sz)_dl_mquery((a), (size_t)(sz), PROT_READ | 
> PROT_WRITE, \
> +MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0)
> +
>  #define MMAP_ERROR(p)(_dl_mmap_error(p) ? MAP_FAILED : (p))
>  
>  struct region_info {
> @@ -277,6 +283,26 @@ unmap(struct dir_info *d, void *p, size_
>   wrterror("malloc cache overflow");
>  }
>  
> +static void
> +zapcacheregion(struct dir_info *d, void *p, size_t len)
> +{
> + u_int i;
> + struct region_info *r;
> + size_t rsz;
> +
> + for (i = 0; i < mopts.malloc_cache; i++) {
> + r = &d->free_regions[i];
> + if (r->p >= p && r->p <= (void *)((char *)p + len)) {
> + rsz = r->size << MALLOC_PAGESHIFT;
> + if (_dl_munmap(r->p, rsz))
> + wrterror("munmap");
> + r->p = NULL;
> + d->free_regions_size -= r->size;
> + r->size = 0;
> + }
> + }
> +}
> +
>  static void *
>  map(struct dir_info *d, size_t sz, int zero_fill)
>  {
> @@ -987,6 +1013,119 @@ _dl_free(void *ptr)
>   malloc_active--;
>  }
>  
> +static void *
> +orealloc(void *p, size_t newsz)
> +{
> + struct region_info *r;
> + size_t oldsz, goldsz, gnewsz;
> + void *q;
> +
> + if (p == NULL)
> + return omalloc(newsz, 0);
> +
> + r = find(g_pool, p);
> + if (r == NULL) {
> + wrterror("bogus pointer (double free?)");
> + return NULL;
> + }
> + if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE)
> + return NULL;
> +
> + REALSIZE(oldsz, r);
> + goldsz = oldsz;
> + if (oldsz > MALLOC_MAXCHUNK) {
> + if (oldsz < mopts.malloc_guard)
> + wrterror("guard size");
> + oldsz -= mopts.malloc_guard;
> + }
> +
> + gnewsz = newsz;
> + if (gnewsz > MALLOC_MAXCHUNK)
> + gnewsz += mopts.malloc_guard;
> +
> + if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p) {
> + size_t roldsz = PAGEROUND(goldsz);
> + size_t rnewsz = PAGEROUND(gnewsz);
> +
> + if (rnewsz > roldsz) {
> + if (!mopts.malloc_guard) {
> + void *hint = (char *)p + roldsz;
> + size_t needed = rnewsz - roldsz;
> +
> + zapcacheregion(g_pool, hint, needed);
> + q = MQUERY(hint, needed);
> + if (q == hint)
> + q = MMAPA(hint, needed);
> + else
> + q = MAP_FAILED;
> + if (q == hint) {
> + if (mopts.malloc_junk == 2)
> + _dl_memset(q, SOME_JUNK, 
> needed);
> + r->size = newsz;
> + return p;
> + } else if (q != MAP_FAILED) {
> + if (_dl_munmap(q, needed))
> + wrterror("munmap");
> + }
> + }
> + } else if (rnewsz < roldsz) {
> + if (mopts.malloc_guard) {
> + if (_dl_mprotect((char *)p + roldsz -
> + mopts.malloc_guard, mopts.malloc_guard,
> + PROT_READ | PROT_WRITE))
> + wrterror("mprotect");
> + if (_dl_mprotect((char *)p + rnewsz -
> + mopts.malloc_guard, mopts.malloc_guard,
> + PROT_NONE))
> + wrterror("mprotect");
> + }
> + unmap(g_pool, (char *)p + rne

Re: audio(9) manual page

2014-06-24 Thread Jason McIntyre
On Tue, Jun 24, 2014 at 09:13:47AM +0200, Alexandre Ratchov wrote:
> On Tue, Jun 24, 2014 at 03:58:41AM +0400, Alexander Polakov wrote:
> > So I have been trying to write a new audio driver (for Xonar DS if
> > anyone interested) and therefore reading audio(9).
> > 
> > I was confused for a while by the use of "will" here. I think it's not
> > clear enough that these functions should be called by the driver code.
> > 
> > I'm not a native speaker, so may be it's just my lack of familiarity with
> > english idioms. Sorry for the noise if that's the case.
> > 
> 
> I see what you mean. As the manual describes the interface between
> two layers we may need to be more precise about who calls who.
> Wouldn't the following be less ambigous?
> 
> When the hardware is ready to accept more samples the driver shall
> call the
> .Fa intr
> function with the argument
> .Fa intrarg .
> 

the use of "will" is perfectly fine here - it's basically a conditional
sentence structure.

"shall" sounds awful. it sounds formal, dated, and like a document
produced by posix. please don;t make this change.

what is simpler, i think, and easier for most folks to understand, is
using a present tense:

When the hardware is ready to accept more samples,
the driver calls the
.Fa intr
function with the argument
.Fa intrarg .

it's all a matter of taste, i suppose, but present tense structure does
seem to be easier to read for non-native speakers (in my experience).

jmc

> > Index: audio.9
> > ===
> > RCS file: /cvs/src/share/man/man9/audio.9,v
> > retrieving revision 1.23
> > diff -u -r1.23 audio.9
> > --- audio.9 21 Jan 2014 03:15:46 -  1.23
> > +++ audio.9 23 Jun 2014 19:42:42 -
> > @@ -284,7 +284,7 @@
> >  has been initiated (normally with DMA).
> >  When the hardware is ready to accept more samples the function
> >  .Fa intr
> > -will be called with the argument
> > +shall be called with the argument
> >  .Fa intrarg .
> >  Calling
> >  .Fa intr
> > @@ -302,7 +302,7 @@
> >  has been initiated (normally with DMA).
> >  When the hardware is ready to deliver more samples the function
> >  .Fa intr
> > -will be called with the argument
> > +shall be called with the argument
> >  .Fa intrarg .
> >  Calling
> >  .Fa intr
> > @@ -437,7 +437,7 @@
> >  .Fa blksize
> >  sized block, the function
> >  .Fa intr
> > -will be called with the argument
> > +shall be called with the argument
> >  .Fa intrarg
> >  (typically from the audio hardware interrupt service routine).
> >  Once started, the transfer may be stopped using
> > @@ -459,7 +459,7 @@
> >  .Fa blksize
> >  sized block, the function
> >  .Fa intr
> > -will be called with the argument
> > +shall be called with the argument
> >  .Fa intrarg
> >  (typically from the audio hardware interrupt service routine).
> >  Once started, the transfer may be stopped using
> 



Re: Undefined symbol in ld.so

2014-06-24 Thread Nigel Taylor
On 06/24/14 09:30, William Orr wrote:
> ld.so in -current isn't building right now, due to an undefined reference to
> _dl_realloc caused by the recent addition of _dl_reallocarray. The following
> diff implements _dl_realloc, largely copied from the implementation in
> lib/libc/stdlib/malloc.c.
> 
> tested on amd64

There are issues with some CVS mirrors because of cvsync/commitid's, one
of those is issue is failure to update malloc.c, the current version is
1.3, you have version 1.1 your CVS source tree being incorrect is the
issue. Try a different CVS mirror or wait until issues have been fixed.

$ cvs log malloc.c

RCS file: /cvs/src/libexec/ld.so/malloc.c,v
Working file: malloc.c
head: 1.3
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 3; selected revisions: 3
description:

revision 1.3
date: 2014/06/21 08:00:23;  author: otto;  state: Exp;  lines: +47 -1;
commitid: wh9FTpEgwThWVeqE;
Move to a non-zeroing _dl_malloc, a _dl_calloc and _dl_reallocarry and
fix _dl_strdup to return NULL instead of crash; ok deraadt@

revision 1.2
date: 2014/06/15 06:48:30;  author: otto;  state: Exp;  lines: +2 -2;
commitid: zG8TjRrBxXrN0x6O;
move to a smaller rbytes buffer; ok miod@ deraadt@

revision 1.1
date: 2014/06/05 08:39:07;  author: otto;  state: Exp;  commitid:
PovK1yhVqujrpswl;
Move to (slightly stripped) version of libc malloc; ok deraadt@
=



> 
> Index: malloc.c
> ===
> RCS file: /cvs/src/libexec/ld.so/malloc.c,v
> retrieving revision 1.1
> diff -u -b -w -p -r1.1 malloc.c
> --- malloc.c  5 Jun 2014 08:39:07 -   1.1
> +++ malloc.c  24 Jun 2014 08:24:43 -
> @@ -78,6 +78,12 @@
>  #define MMAP(sz) _dl_mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
>  MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
>  
> +#define MMAPA(a,sz)  _dl_mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
> +MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
> +
> +#define MQUERY(a, sz)_dl_mquery((a), (size_t)(sz), PROT_READ | 
> PROT_WRITE, \
> +MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0)
> +
>  #define MMAP_ERROR(p)(_dl_mmap_error(p) ? MAP_FAILED : (p))
>  
>  struct region_info {
> @@ -277,6 +283,26 @@ unmap(struct dir_info *d, void *p, size_
>   wrterror("malloc cache overflow");
>  }
>  
> +static void
> +zapcacheregion(struct dir_info *d, void *p, size_t len)
> +{
> + u_int i;
> + struct region_info *r;
> + size_t rsz;
> +
> + for (i = 0; i < mopts.malloc_cache; i++) {
> + r = &d->free_regions[i];
> + if (r->p >= p && r->p <= (void *)((char *)p + len)) {
> + rsz = r->size << MALLOC_PAGESHIFT;
> + if (_dl_munmap(r->p, rsz))
> + wrterror("munmap");
> + r->p = NULL;
> + d->free_regions_size -= r->size;
> + r->size = 0;
> + }
> + }
> +}
> +
>  static void *
>  map(struct dir_info *d, size_t sz, int zero_fill)
>  {
> @@ -987,6 +1013,119 @@ _dl_free(void *ptr)
>   malloc_active--;
>  }
>  
> +static void *
> +orealloc(void *p, size_t newsz)
> +{
> + struct region_info *r;
> + size_t oldsz, goldsz, gnewsz;
> + void *q;
> +
> + if (p == NULL)
> + return omalloc(newsz, 0);
> +
> + r = find(g_pool, p);
> + if (r == NULL) {
> + wrterror("bogus pointer (double free?)");
> + return NULL;
> + }
> + if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE)
> + return NULL;
> +
> + REALSIZE(oldsz, r);
> + goldsz = oldsz;
> + if (oldsz > MALLOC_MAXCHUNK) {
> + if (oldsz < mopts.malloc_guard)
> + wrterror("guard size");
> + oldsz -= mopts.malloc_guard;
> + }
> +
> + gnewsz = newsz;
> + if (gnewsz > MALLOC_MAXCHUNK)
> + gnewsz += mopts.malloc_guard;
> +
> + if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p) {
> + size_t roldsz = PAGEROUND(goldsz);
> + size_t rnewsz = PAGEROUND(gnewsz);
> +
> + if (rnewsz > roldsz) {
> + if (!mopts.malloc_guard) {
> + void *hint = (char *)p + roldsz;
> + size_t needed = rnewsz - roldsz;
> +
> + zapcacheregion(g_pool, hint, needed);
> + q = MQUERY(hint, needed);
> + if (q == hint)
> + q = MMAPA(hint, needed);
> + else
> + q = MAP_FAILED;
> + if (q == hint) {
> + if (mopts.malloc_junk == 

Undefined symbol in ld.so

2014-06-24 Thread William Orr
ld.so in -current isn't building right now, due to an undefined reference to
_dl_realloc caused by the recent addition of _dl_reallocarray. The following
diff implements _dl_realloc, largely copied from the implementation in
lib/libc/stdlib/malloc.c.

tested on amd64

Index: malloc.c
===
RCS file: /cvs/src/libexec/ld.so/malloc.c,v
retrieving revision 1.1
diff -u -b -w -p -r1.1 malloc.c
--- malloc.c5 Jun 2014 08:39:07 -   1.1
+++ malloc.c24 Jun 2014 08:24:43 -
@@ -78,6 +78,12 @@
 #define MMAP(sz)   _dl_mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
 
+#define MMAPA(a,sz)_dl_mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
+MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
+
+#define MQUERY(a, sz)  _dl_mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
+MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0)
+
 #define MMAP_ERROR(p)  (_dl_mmap_error(p) ? MAP_FAILED : (p))
 
 struct region_info {
@@ -277,6 +283,26 @@ unmap(struct dir_info *d, void *p, size_
wrterror("malloc cache overflow");
 }
 
+static void
+zapcacheregion(struct dir_info *d, void *p, size_t len)
+{
+   u_int i;
+   struct region_info *r;
+   size_t rsz;
+
+   for (i = 0; i < mopts.malloc_cache; i++) {
+   r = &d->free_regions[i];
+   if (r->p >= p && r->p <= (void *)((char *)p + len)) {
+   rsz = r->size << MALLOC_PAGESHIFT;
+   if (_dl_munmap(r->p, rsz))
+   wrterror("munmap");
+   r->p = NULL;
+   d->free_regions_size -= r->size;
+   r->size = 0;
+   }
+   }
+}
+
 static void *
 map(struct dir_info *d, size_t sz, int zero_fill)
 {
@@ -987,6 +1013,119 @@ _dl_free(void *ptr)
malloc_active--;
 }
 
+static void *
+orealloc(void *p, size_t newsz)
+{
+   struct region_info *r;
+   size_t oldsz, goldsz, gnewsz;
+   void *q;
+
+   if (p == NULL)
+   return omalloc(newsz, 0);
+
+   r = find(g_pool, p);
+   if (r == NULL) {
+   wrterror("bogus pointer (double free?)");
+   return NULL;
+   }
+   if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE)
+   return NULL;
+
+   REALSIZE(oldsz, r);
+   goldsz = oldsz;
+   if (oldsz > MALLOC_MAXCHUNK) {
+   if (oldsz < mopts.malloc_guard)
+   wrterror("guard size");
+   oldsz -= mopts.malloc_guard;
+   }
+
+   gnewsz = newsz;
+   if (gnewsz > MALLOC_MAXCHUNK)
+   gnewsz += mopts.malloc_guard;
+
+   if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p) {
+   size_t roldsz = PAGEROUND(goldsz);
+   size_t rnewsz = PAGEROUND(gnewsz);
+
+   if (rnewsz > roldsz) {
+   if (!mopts.malloc_guard) {
+   void *hint = (char *)p + roldsz;
+   size_t needed = rnewsz - roldsz;
+
+   zapcacheregion(g_pool, hint, needed);
+   q = MQUERY(hint, needed);
+   if (q == hint)
+   q = MMAPA(hint, needed);
+   else
+   q = MAP_FAILED;
+   if (q == hint) {
+   if (mopts.malloc_junk == 2)
+   _dl_memset(q, SOME_JUNK, 
needed);
+   r->size = newsz;
+   return p;
+   } else if (q != MAP_FAILED) {
+   if (_dl_munmap(q, needed))
+   wrterror("munmap");
+   }
+   }
+   } else if (rnewsz < roldsz) {
+   if (mopts.malloc_guard) {
+   if (_dl_mprotect((char *)p + roldsz -
+   mopts.malloc_guard, mopts.malloc_guard,
+   PROT_READ | PROT_WRITE))
+   wrterror("mprotect");
+   if (_dl_mprotect((char *)p + rnewsz -
+   mopts.malloc_guard, mopts.malloc_guard,
+   PROT_NONE))
+   wrterror("mprotect");
+   }
+   unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz);
+   r->size = gnewsz;
+   return p;
+   } else {
+   if (newsz > oldsz && mopts.malloc_junk == 2)
+   _dl_memset((char *)p + newsz,

Re: audio(9) manual page

2014-06-24 Thread Alexandre Ratchov
On Tue, Jun 24, 2014 at 03:58:41AM +0400, Alexander Polakov wrote:
> So I have been trying to write a new audio driver (for Xonar DS if
> anyone interested) and therefore reading audio(9).
> 
> I was confused for a while by the use of "will" here. I think it's not
> clear enough that these functions should be called by the driver code.
> 
> I'm not a native speaker, so may be it's just my lack of familiarity with
> english idioms. Sorry for the noise if that's the case.
> 

I see what you mean. As the manual describes the interface between
two layers we may need to be more precise about who calls who.
Wouldn't the following be less ambigous?

When the hardware is ready to accept more samples the driver shall
call the
.Fa intr
function with the argument
.Fa intrarg .

> Index: audio.9
> ===
> RCS file: /cvs/src/share/man/man9/audio.9,v
> retrieving revision 1.23
> diff -u -r1.23 audio.9
> --- audio.9   21 Jan 2014 03:15:46 -  1.23
> +++ audio.9   23 Jun 2014 19:42:42 -
> @@ -284,7 +284,7 @@
>  has been initiated (normally with DMA).
>  When the hardware is ready to accept more samples the function
>  .Fa intr
> -will be called with the argument
> +shall be called with the argument
>  .Fa intrarg .
>  Calling
>  .Fa intr
> @@ -302,7 +302,7 @@
>  has been initiated (normally with DMA).
>  When the hardware is ready to deliver more samples the function
>  .Fa intr
> -will be called with the argument
> +shall be called with the argument
>  .Fa intrarg .
>  Calling
>  .Fa intr
> @@ -437,7 +437,7 @@
>  .Fa blksize
>  sized block, the function
>  .Fa intr
> -will be called with the argument
> +shall be called with the argument
>  .Fa intrarg
>  (typically from the audio hardware interrupt service routine).
>  Once started, the transfer may be stopped using
> @@ -459,7 +459,7 @@
>  .Fa blksize
>  sized block, the function
>  .Fa intr
> -will be called with the argument
> +shall be called with the argument
>  .Fa intrarg
>  (typically from the audio hardware interrupt service routine).
>  Once started, the transfer may be stopped using