login_fbtab glob

2022-04-14 Thread joshua stein
login_fbtab(3) supports wildcards but only for every file in a 
directory (/path/*).

This makes it use glob(3) so it can also support more specific 
wildcards like /path/file*


diff --git lib/libutil/login_fbtab.c lib/libutil/login_fbtab.c
index 5eacf4f65ff..39621a0cde4 100644
--- lib/libutil/login_fbtab.c
+++ lib/libutil/login_fbtab.c
@@ -61,8 +61,8 @@
 #include 
 
 #include 
-#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -134,49 +134,32 @@ login_fbtab(const char *tty, uid_t uid, gid_t gid)
 static void
 login_protect(const char *path, mode_t mask, uid_t uid, gid_t gid)
 {
-   charbuf[PATH_MAX];
-   size_t  pathlen = strlen(path);
-   DIR *dir;
-   struct  dirent *ent;
+   glob_t  g;
+   size_t  n;
+   char*gpath;
 
-   if (pathlen >= sizeof(buf)) {
+   if (strlen(path) > PATH_MAX) {
errno = ENAMETOOLONG;
syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path);
return;
}
 
-   if (strcmp("/*", path + pathlen - 2) != 0) {
-   if (chmod(path, mask) && errno != ENOENT)
-   syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path);
-   if (chown(path, uid, gid) && errno != ENOENT)
-   syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path);
-   } else {
-   /*
-* This is a wildcard directory (/path/to/whatever/ * ).
-* Make a copy of path without the trailing '*' (but leave
-* the trailing '/' so we can append directory entries.)
-*/
-   memcpy(buf, path, pathlen - 1);
-   buf[pathlen - 1] = '\0';
-   if ((dir = opendir(buf)) == NULL) {
-   syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB,
-   path);
-   return;
-   }
+   g.gl_offs = 0;
+   if (glob(path, GLOB_DOOFFS, NULL, ) != 0) {
+   if (errno != ENOENT)
+   syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path);
+   globfree();
+   return;
+   }
 
-   while ((ent = readdir(dir)) != NULL) {
-   if (strcmp(ent->d_name, ".")  != 0 &&
-   strcmp(ent->d_name, "..") != 0) {
-   buf[pathlen - 1] = '\0';
-   if (strlcat(buf, ent->d_name, sizeof(buf))
-   >= sizeof(buf)) {
-   errno = ENAMETOOLONG;
-   syslog(LOG_ERR, "%s: %s: %m",
-   _PATH_FBTAB, path);
-   } else
-   login_protect(buf, mask, uid, gid);
-   }
-   }
-   closedir(dir);
+   for (n = 0; n < g.gl_matchc; n++) {
+   gpath = g.gl_pathv[n];
+
+   if (chmod(gpath, mask) && errno != ENOENT)
+   syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, 
gpath);
+   if (chown(gpath, uid, gid) && errno != ENOENT)
+   syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, 
gpath);
}
+
+   globfree();
 }



Re: dwctwo(4) fix panic

2022-04-14 Thread Mark Kettenis
> Date: Thu, 14 Apr 2022 20:16:13 +0200
> From: Marcus Glocker 
> 
> I did hit this panic when trying to stream audio through
> uaudio(4) / dwctwo(4):
> 
>   panic: _dmamap_sync: ran off map!
>   Stopped at  panic+0x160:cmp w21, #0x0
>   TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
>   *421282  69103  0 0x2  0x4000K ld
>   db_enter() at panic+0x15c
>   panic() at _dmamap_sync+0x10c
>   _dmamap_sync() at dwc2_xfercomp_isoc_split_in+0xe0
>   dwc2_xfercomp_isoc_split_in() at dwc2_hc_xfercomp_intr+0xf4
>   dwc2_hc_xfercomp_intr() at dwc2_hc_n_intr+0x1d4
>   dwc2_hc_n_intr() at dwc2_handle_hcd_intr+0x1e4
>   dwc2_handle_hcd_intr() at dwc2_intr+0xb8
> 
> Obviously usb_syncmem() expects an integer offset as second argument,
> not a memory address.  Looks like a typo to me ...
> 
> OK?

Hmm, that doesn't look right.

> 
> 
> Index: sys/dev/usb/dwc2/dwc2_hcdintr.c
> ===
> RCS file: /cvs/src/sys/dev/usb/dwc2/dwc2_hcdintr.c,v
> retrieving revision 1.13
> diff -u -p -u -p -r1.13 dwc2_hcdintr.c
> --- sys/dev/usb/dwc2/dwc2_hcdintr.c   4 Sep 2021 10:19:28 -   1.13
> +++ sys/dev/usb/dwc2/dwc2_hcdintr.c   14 Apr 2022 17:48:08 -
> @@ -975,11 +975,11 @@ STATIC int dwc2_xfercomp_isoc_split_in(s
>  
>   if (chan->align_buf) {
>   dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
> - usb_syncmem(qtd->urb->usbdma, chan->qh->dw_align_buf_dma,
> + usb_syncmem(qtd->urb->usbdma, 0,
>   chan->qh->dw_align_buf_size, BUS_DMASYNC_POSTREAD);
>   memcpy(qtd->urb->buf + frame_desc->offset +
>  qtd->isoc_split_offset, chan->qh->dw_align_buf, len);
> - usb_syncmem(qtd->urb->usbdma, chan->qh->dw_align_buf_dma,
> + usb_syncmem(qtd->urb->usbdma, 0,
>   chan->qh->dw_align_buf_size, BUS_DMASYNC_PREREAD);
>   }

When chan->align_buf is set we're doing DMA into dw_align_buf, and I
think that means we need to use dw_align_buf_usbdma as the first
argument to usb_syncmem since we need to make sure that the memory
we're doing DMA into is coherent with the cache.  So I think this
should be something like:

if (chan->align_buf) {
struct usb_dma *ud = >qh->dw_align_buf_usbdma;

dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
usb_syncmem(ud, 0, chan->qh->dw_align_buf_size,
BUS_DMASYNC_POSTREAD);
memcpy(qtd->urb->buf + frame_desc->offset +
   qtd->isoc_split_offset, chan->qh->dw_align_buf, len);
usb_syncmem(qtd->urb->usbdma, chan->qh->dw_align_buf_dma,
usb_syncmem(ud, 0, chan->qh->dw_align_buf_size,
BUS_DMASYNC_PREREAD);

I think that means the code in dwc2_update_uwb_state() is wrong too.
But then I never fully understood this code...



dwctwo(4) fix panic

2022-04-14 Thread Marcus Glocker
I did hit this panic when trying to stream audio through
uaudio(4) / dwctwo(4):

panic: _dmamap_sync: ran off map!
Stopped at  panic+0x160:cmp w21, #0x0
TIDPIDUID PRFLAGS PFLAGS  CPU  COMMAND
*421282  69103  0 0x2  0x4000K ld
db_enter() at panic+0x15c
panic() at _dmamap_sync+0x10c
_dmamap_sync() at dwc2_xfercomp_isoc_split_in+0xe0
dwc2_xfercomp_isoc_split_in() at dwc2_hc_xfercomp_intr+0xf4
dwc2_hc_xfercomp_intr() at dwc2_hc_n_intr+0x1d4
dwc2_hc_n_intr() at dwc2_handle_hcd_intr+0x1e4
dwc2_handle_hcd_intr() at dwc2_intr+0xb8

Obviously usb_syncmem() expects an integer offset as second argument,
not a memory address.  Looks like a typo to me ...

OK?


Index: sys/dev/usb/dwc2/dwc2_hcdintr.c
===
RCS file: /cvs/src/sys/dev/usb/dwc2/dwc2_hcdintr.c,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 dwc2_hcdintr.c
--- sys/dev/usb/dwc2/dwc2_hcdintr.c 4 Sep 2021 10:19:28 -   1.13
+++ sys/dev/usb/dwc2/dwc2_hcdintr.c 14 Apr 2022 17:48:08 -
@@ -975,11 +975,11 @@ STATIC int dwc2_xfercomp_isoc_split_in(s
 
if (chan->align_buf) {
dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
-   usb_syncmem(qtd->urb->usbdma, chan->qh->dw_align_buf_dma,
+   usb_syncmem(qtd->urb->usbdma, 0,
chan->qh->dw_align_buf_size, BUS_DMASYNC_POSTREAD);
memcpy(qtd->urb->buf + frame_desc->offset +
   qtd->isoc_split_offset, chan->qh->dw_align_buf, len);
-   usb_syncmem(qtd->urb->usbdma, chan->qh->dw_align_buf_dma,
+   usb_syncmem(qtd->urb->usbdma, 0,
chan->qh->dw_align_buf_size, BUS_DMASYNC_PREREAD);
}
 



Re: rate limit uvn_flush warning

2022-04-14 Thread Theo de Raadt
> If I understand correctly, the problem is that writing to memory
> of an mmap(2)ed file has no error handling.  If the file system is
> full, userland cannot be informed.  So someone invented this message
> in the kernel.

If you cannot return an error to the program, deciding to print a message
to the console doesn't fix anything. The program doesn't see the problem.
The program cannot cope.  The user sees an irrelevant message which doesn't
give them any action they can take.  Not even root will know what to do.

> What is the correct behavior?

The correct error might be to deliver SIGSEGV.

No really, I am serious.  Let's talk about that.

>  Should close(2) after munmap(2) fail?

That doesn't help anyone.  Noone checks for error on close, because
close is effectively a "void" function.  (It was a mistake for POSIX
to add error conditions to close, because noone can act upon the error.
At the same time, they failed to define what happens to the fd.  If the
fd is deallocated, how can you recover if the data is only on the object
that was referred to?  If the fd is not deallocated, it becomes a leak
in every program that calls close and doesn't check for failure, and
do what, spin until close succeeds?)



Re: rate limit uvn_flush warning

2022-04-14 Thread Alexander Bluhm
On Wed, Apr 13, 2022 at 02:22:00PM -0600, Theo de Raadt wrote:
> I think we should fix the bug and/or DELETE the message entirely

I don't see the bug.  The message was added in the initial NetBSD
uvm commit.
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/uvm/uvm_vnode.c?annotate=1.1

With a major refactoring the whole function with the message
disappeared in 2001.
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/uvm/uvm_vnode.c#rev1.52

If I understand correctly, the problem is that writing to memory
of an mmap(2)ed file has no error handling.  If the file system is
full, userland cannot be informed.  So someone invented this message
in the kernel.

What is the correct behavior?  Should close(2) after munmap(2) fail?
According to ktrace close returns 0 and ld exits with 0.  It does
not see any error although newbsd was not written correctly.

This is the output when ld fails:

../GENERIC# make newbsd  
LD="ld" sh makegap.sh 0x gapdummy.o
ld -T ld.script -X --warn-common -nopie -o newbsd ${SYSTEM_HEAD} vers.o ${OBJS}

/usr: write failed, file system is full
textdatabss dec hex
0   0   0   0   0
mv newbsd newbsd.gdb
ctfstrip -S -o newbsd newbsd.gdb
strip: there are no sections to be copied!
rm -f bsd.gdb
mv -f newbsd bsd
mv: newbsd: No such file or directory
*** Error 1 in /usr/share/relink/kernel/GENERIC (Makefile:1934 'newbsd')

The "/usr: write failed, file system is full" message is printed
by ffs to the controlling tty with rate limiting.  So error reporting
happens.

Deleting uvm message is easy.  While there use __func__ for easier
function grepping.

bluhm

Index: uvm/uvm_vnode.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_vnode.c,v
retrieving revision 1.121
diff -u -p -r1.121 uvm_vnode.c
--- uvm/uvm_vnode.c 15 Dec 2021 12:53:53 -  1.121
+++ uvm/uvm_vnode.c 14 Apr 2022 17:34:01 -
@@ -744,7 +744,7 @@ ReTry:
 */
 #ifdef DIAGNOSTIC
if (flags & PGO_SYNCIO)
-   panic("uvn_flush: PGO_SYNCIO return 'try again' error (impossible)");
+   panic("%s: PGO_SYNCIO return 'try again' error (impossible)", __func__);
 #endif
flags |= PGO_SYNCIO;
if (flags & PGO_FREE)
@@ -807,17 +807,8 @@ ReTry:
}
} else if (flags & PGO_FREE &&
result != VM_PAGER_PEND) {
-   if (result != VM_PAGER_OK) {
-   printf("uvn_flush: obj=%p, "
-  "offset=0x%llx.  error "
-  "during pageout.\n",
-   pp->uobject,
-   (long long)pp->offset);
-   printf("uvn_flush: WARNING: "
-   "changes to page may be "
-   "lost!\n");
+   if (result != VM_PAGER_OK)
retval = FALSE;
-   }
pmap_page_protect(ptmp, PROT_NONE);
uvm_pageclean(ptmp);
TAILQ_INSERT_TAIL(, ptmp, pageq);



Re: kbd -l error message

2022-04-14 Thread Alexander Bluhm
On Thu, Apr 14, 2022 at 04:44:10PM +0200, Marc Espie wrote:
> I'm not quite fond of the error reports, though... they could be more specific
> - we keep track of the first error, so it should probably talk 
> about /dev/wskbd0 directly ?

I wanted to show that more than one device is envolved.
But actually the error is always from /dev/wskbd0.

> - by comparison, the message for the WSKBDIO_GTYPE doesn't mention the
> device name. I think err(1, "WKBDIO_GTYPE on %s", device) might be slightly
> more helpful.

# kbd -l
kbd: WSKBDIO_GTYPE /dev/wskbd0: Bad address

> I don't see the need for the word "open "in the message.

$ ./kbd -l
kbd: /dev/wskbd0: Permission denied

ok?

Index: sbin/kbd/kbd_wscons.c
===
RCS file: /data/mirror/openbsd/cvs/src/sbin/kbd/kbd_wscons.c,v
retrieving revision 1.34
diff -u -p -r1.34 kbd_wscons.c
--- sbin/kbd/kbd_wscons.c   22 Jan 2020 06:24:07 -  1.34
+++ sbin/kbd/kbd_wscons.c   14 Apr 2022 15:59:26 -
@@ -150,7 +150,7 @@ kbd_list(void)
 {
int kbds[SA_MAX];
struct wskbd_encoding_data encs[SA_MAX];
-   int fd, i, kbtype, t;
+   int fd, i, kbtype, t, error = 0;
chardevice[PATH_MAX];
 
memset(kbds, 0, sizeof(kbds));
@@ -162,9 +162,16 @@ kbd_list(void)
fd = open(device, O_WRONLY);
if (fd == -1)
fd = open(device, O_RDONLY);
-   if (fd >= 0) {
+   if (fd == -1) {
+   /* remember the first error number */
+   if (error == 0)
+   error = errno;
+   } else {
+   /* at least one success, do not print error */
+   error = -1;
+
if (ioctl(fd, WSKBDIO_GTYPE, ) == -1)
-   err(1, "WSKBDIO_GTYPE");
+   err(1, "WSKBDIO_GTYPE %s", device);
switch (kbtype) {
case WSKBD_TYPE_PC_XT:
case WSKBD_TYPE_PC_AT:
@@ -207,6 +214,10 @@ kbd_list(void)
}
close(fd);
}
+   }
+   if (error > 0) {
+   errno = error;
+   err(1, "/dev/wskbd0");
}
 
for (i = 0; i < SA_MAX; i++)



Re: kbd -l error message

2022-04-14 Thread Theo de Raadt
I don't see the need for the word "open "in the message.

Alexander Bluhm  wrote:

> Hi,
> 
> When kbd -l is executed as regular user, it fails silently.
> 
> $ kbd -l
> $ echo $?
> 0
> 
> Error handling is a bit tricky.  We want the first error if no
> device is available.
> 
> $ ./kbd -l 
> kbd: open /dev/wskbd[0-9]: Permission denied
> $ echo $?
> 1
> 
> ok?
> 
> bluhm
> 
> Index: sbin/kbd/kbd_wscons.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 kbd_wscons.c
> --- sbin/kbd/kbd_wscons.c 22 Jan 2020 06:24:07 -  1.34
> +++ sbin/kbd/kbd_wscons.c 14 Apr 2022 14:21:17 -
> @@ -150,7 +150,7 @@ kbd_list(void)
>  {
>   int kbds[SA_MAX];
>   struct wskbd_encoding_data encs[SA_MAX];
> - int fd, i, kbtype, t;
> + int fd, i, kbtype, t, error = 0;
>   chardevice[PATH_MAX];
>  
>   memset(kbds, 0, sizeof(kbds));
> @@ -162,7 +162,14 @@ kbd_list(void)
>   fd = open(device, O_WRONLY);
>   if (fd == -1)
>   fd = open(device, O_RDONLY);
> - if (fd >= 0) {
> + if (fd == -1) {
> + /* remember the first error number */
> + if (error == 0)
> + error = errno;
> + } else {
> + /* at least one success, do not print error */
> + error = -1;
> +
>   if (ioctl(fd, WSKBDIO_GTYPE, ) == -1)
>   err(1, "WSKBDIO_GTYPE");
>   switch (kbtype) {
> @@ -207,6 +214,10 @@ kbd_list(void)
>   }
>   close(fd);
>   }
> + }
> + if (error > 0) {
> + errno = error;
> + err(1, "open /dev/wskbd[0-9]");
>   }
>  
>   for (i = 0; i < SA_MAX; i++)
> 



Re: kbd -l error message

2022-04-14 Thread Marc Espie
On Thu, Apr 14, 2022 at 04:28:37PM +0200, Alexander Bluhm wrote:
> Hi,
> 
> When kbd -l is executed as regular user, it fails silently.
> 
> $ kbd -l
> $ echo $?
> 0
> 
> Error handling is a bit tricky.  We want the first error if no
> device is available.
> 
> $ ./kbd -l 
> kbd: open /dev/wskbd[0-9]: Permission denied
> $ echo $?
> 1
> 
> ok?
> 
> bluhm
> 
> Index: sbin/kbd/kbd_wscons.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sbin/kbd/kbd_wscons.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 kbd_wscons.c
> --- sbin/kbd/kbd_wscons.c 22 Jan 2020 06:24:07 -  1.34
> +++ sbin/kbd/kbd_wscons.c 14 Apr 2022 14:21:17 -
> @@ -150,7 +150,7 @@ kbd_list(void)
>  {
>   int kbds[SA_MAX];
>   struct wskbd_encoding_data encs[SA_MAX];
> - int fd, i, kbtype, t;
> + int fd, i, kbtype, t, error = 0;
>   chardevice[PATH_MAX];
>  
>   memset(kbds, 0, sizeof(kbds));
> @@ -162,7 +162,14 @@ kbd_list(void)
>   fd = open(device, O_WRONLY);
>   if (fd == -1)
>   fd = open(device, O_RDONLY);
> - if (fd >= 0) {
> + if (fd == -1) {
> + /* remember the first error number */
> + if (error == 0)
> + error = errno;
> + } else {
> + /* at least one success, do not print error */
> + error = -1;
> +
>   if (ioctl(fd, WSKBDIO_GTYPE, ) == -1)
>   err(1, "WSKBDIO_GTYPE");
>   switch (kbtype) {
> @@ -207,6 +214,10 @@ kbd_list(void)
>   }
>   close(fd);
>   }
> + }
> + if (error > 0) {
> + errno = error;
> + err(1, "open /dev/wskbd[0-9]");
>   }
>  
>   for (i = 0; i < SA_MAX; i++)
> 
> 
I was annoyed by this as well, so I welcome better code.  It looks 99% okay
for me. 

I'm not quite fond of the error reports, though... they could be more specific
about which device is doing what.

- we keep track of the first error, so it should probably talk 
about /dev/wskbd0 directly ?

- by comparison, the message for the WSKBDIO_GTYPE doesn't mention the
device name. I think err(1, "WKBDIO_GTYPE on %s", device) might be slightly
more helpful.



kbd -l error message

2022-04-14 Thread Alexander Bluhm
Hi,

When kbd -l is executed as regular user, it fails silently.

$ kbd -l
$ echo $?
0

Error handling is a bit tricky.  We want the first error if no
device is available.

$ ./kbd -l 
kbd: open /dev/wskbd[0-9]: Permission denied
$ echo $?
1

ok?

bluhm

Index: sbin/kbd/kbd_wscons.c
===
RCS file: /data/mirror/openbsd/cvs/src/sbin/kbd/kbd_wscons.c,v
retrieving revision 1.34
diff -u -p -r1.34 kbd_wscons.c
--- sbin/kbd/kbd_wscons.c   22 Jan 2020 06:24:07 -  1.34
+++ sbin/kbd/kbd_wscons.c   14 Apr 2022 14:21:17 -
@@ -150,7 +150,7 @@ kbd_list(void)
 {
int kbds[SA_MAX];
struct wskbd_encoding_data encs[SA_MAX];
-   int fd, i, kbtype, t;
+   int fd, i, kbtype, t, error = 0;
chardevice[PATH_MAX];
 
memset(kbds, 0, sizeof(kbds));
@@ -162,7 +162,14 @@ kbd_list(void)
fd = open(device, O_WRONLY);
if (fd == -1)
fd = open(device, O_RDONLY);
-   if (fd >= 0) {
+   if (fd == -1) {
+   /* remember the first error number */
+   if (error == 0)
+   error = errno;
+   } else {
+   /* at least one success, do not print error */
+   error = -1;
+
if (ioctl(fd, WSKBDIO_GTYPE, ) == -1)
err(1, "WSKBDIO_GTYPE");
switch (kbtype) {
@@ -207,6 +214,10 @@ kbd_list(void)
}
close(fd);
}
+   }
+   if (error > 0) {
+   errno = error;
+   err(1, "open /dev/wskbd[0-9]");
}
 
for (i = 0; i < SA_MAX; i++)