Re: ftp: make use of getline(3)

2021-02-14 Thread Christian Weisgerber
Christian Weisgerber:

> > Make use of getline(3) in ftp(1).
> > 
> > Replace fparseln(3) with getline(3).  This removes the only use
> > of libutil.a(fparseln.o) from the ramdisk.
> > Replace a complicated fgetln(3) idiom with the much simpler getline(3).
> 
> OK?

ping?

I've been fetching distfiles with it, and I also built a bsd.rd and
performed a http install with it.

Index: distrib/special/ftp/Makefile
===
RCS file: /cvs/src/distrib/special/ftp/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- distrib/special/ftp/Makefile16 May 2019 12:44:17 -  1.14
+++ distrib/special/ftp/Makefile29 Jan 2021 18:05:46 -
@@ -6,7 +6,4 @@ PROG=   ftp
 SRCS=  fetch.c ftp.c main.c small.c util.c
 .PATH: ${.CURDIR}/../../../usr.bin/ftp
 
-LDADD+=-lutil
-DPADD+=${LIBUTIL}
-
 .include 
Index: usr.bin/ftp/Makefile
===
RCS file: /cvs/src/usr.bin/ftp/Makefile,v
retrieving revision 1.34
diff -u -p -r1.34 Makefile
--- usr.bin/ftp/Makefile27 Jan 2021 22:27:41 -  1.34
+++ usr.bin/ftp/Makefile29 Jan 2021 17:57:31 -
@@ -8,8 +8,8 @@ PROG=   ftp
 SRCS=  cmds.c cmdtab.c complete.c cookie.c domacro.c fetch.c ftp.c \
list.c main.c ruserpass.c small.c stringlist.c util.c
 
-LDADD+=-ledit -lcurses -lutil -ltls -lssl -lcrypto
-DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBUTIL} ${LIBTLS} ${LIBSSL} 
${LIBCRYPTO}
+LDADD+=-ledit -lcurses -ltls -lssl -lcrypto
+DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
 
 #COPTS+= -Wall -Wconversion -Wstrict-prototypes -Wmissing-prototypes
 
Index: usr.bin/ftp/cookie.c
===
RCS file: /cvs/src/usr.bin/ftp/cookie.c,v
retrieving revision 1.9
diff -u -p -r1.9 cookie.c
--- usr.bin/ftp/cookie.c16 May 2019 12:44:17 -  1.9
+++ usr.bin/ftp/cookie.c6 Feb 2021 16:23:32 -
@@ -58,10 +58,10 @@ void
 cookie_load(void)
 {
field_t  field;
-   size_t   len;
time_t   date;
char*line;
-   char*lbuf;
+   char*lbuf = NULL;
+   size_t   lbufsize = 0;
char*param;
const char  *estr;
FILE*fp;
@@ -75,19 +75,9 @@ cookie_load(void)
if (fp == NULL)
err(1, "cannot open cookie file %s", cookiefile);
date = time(NULL);
-   lbuf = NULL;
-   while ((line = fgetln(fp, )) != NULL) {
-   if (line[len - 1] == '\n') {
-   line[len - 1] = '\0';
-   --len;
-   } else {
-   if ((lbuf = malloc(len + 1)) == NULL)
-   err(1, NULL);
-   memcpy(lbuf, line, len);
-   lbuf[len] = '\0';
-   line = lbuf;
-   }
-   line[strcspn(line, "\r")] = '\0';
+   while (getline(, , fp) != -1) {
+   line = lbuf;
+   line[strcspn(line, "\r\n")] = '\0';
 
line += strspn(line, " \t");
if ((*line == '#') || (*line == '\0')) {
Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.200
diff -u -p -r1.200 fetch.c
--- usr.bin/ftp/fetch.c 2 Feb 2021 12:58:42 -   1.200
+++ usr.bin/ftp/fetch.c 2 Feb 2021 13:59:09 -
@@ -56,7 +56,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -76,7 +75,6 @@ static void   aborthttp(int);
 static charhextochar(const char *);
 static char*urldecode(const char *);
 static char*recode_credentials(const char *_userinfo);
-static char*ftp_readline(FILE *, size_t *);
 static voidftp_close(FILE **, struct tls **, int *);
 static const char *sockerror(struct tls *);
 #ifdef SMALL
@@ -330,6 +328,7 @@ url_get(const char *origline, const char
off_t hashbytes;
const char *errstr;
ssize_t len, wlen;
+   size_t bufsize;
char *proxyhost = NULL;
 #ifndef NOSSL
char *sslpath = NULL, *sslhost = NULL;
@@ -805,12 +804,13 @@ noslash:
free(buf);
 #endif /* !NOSSL */
buf = NULL;
+   bufsize = 0;
 
if (fflush(fin) == EOF) {
warnx("Writing HTTP request: %s", sockerror(tls));
goto cleanup_url_get;
}
-   if ((buf = ftp_readline(fin, )) == NULL) {
+   if ((len = getline(, , fin)) == -1) {
warnx("Receiving HTTP reply: %s", sockerror(tls));
goto cleanup_url_get;
}
@@ -885,11 +885,10 @@ noslash:
/*
 * Read the rest of the header.
 */
-   fr

Re: ftp: make use of getline(3)

2021-02-06 Thread Christian Weisgerber
Christian Weisgerber:

> Make use of getline(3) in ftp(1).
> 
> Replace fparseln(3) with getline(3).  This removes the only use
> of libutil.a(fparseln.o) from the ramdisk.
> Replace a complicated fgetln(3) idiom with the much simpler getline(3).

New diff that fixes a bug I introduced in cookie loading.

OK?

Index: distrib/special/ftp/Makefile
===
RCS file: /cvs/src/distrib/special/ftp/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- distrib/special/ftp/Makefile16 May 2019 12:44:17 -  1.14
+++ distrib/special/ftp/Makefile29 Jan 2021 18:05:46 -
@@ -6,7 +6,4 @@ PROG=   ftp
 SRCS=  fetch.c ftp.c main.c small.c util.c
 .PATH: ${.CURDIR}/../../../usr.bin/ftp
 
-LDADD+=-lutil
-DPADD+=${LIBUTIL}
-
 .include 
Index: usr.bin/ftp/Makefile
===
RCS file: /cvs/src/usr.bin/ftp/Makefile,v
retrieving revision 1.34
diff -u -p -r1.34 Makefile
--- usr.bin/ftp/Makefile27 Jan 2021 22:27:41 -  1.34
+++ usr.bin/ftp/Makefile29 Jan 2021 17:57:31 -
@@ -8,8 +8,8 @@ PROG=   ftp
 SRCS=  cmds.c cmdtab.c complete.c cookie.c domacro.c fetch.c ftp.c \
list.c main.c ruserpass.c small.c stringlist.c util.c
 
-LDADD+=-ledit -lcurses -lutil -ltls -lssl -lcrypto
-DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBUTIL} ${LIBTLS} ${LIBSSL} 
${LIBCRYPTO}
+LDADD+=-ledit -lcurses -ltls -lssl -lcrypto
+DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
 
 #COPTS+= -Wall -Wconversion -Wstrict-prototypes -Wmissing-prototypes
 
Index: usr.bin/ftp/cookie.c
===
RCS file: /cvs/src/usr.bin/ftp/cookie.c,v
retrieving revision 1.9
diff -u -p -r1.9 cookie.c
--- usr.bin/ftp/cookie.c16 May 2019 12:44:17 -  1.9
+++ usr.bin/ftp/cookie.c6 Feb 2021 16:23:32 -
@@ -58,10 +58,10 @@ void
 cookie_load(void)
 {
field_t  field;
-   size_t   len;
time_t   date;
char*line;
-   char*lbuf;
+   char*lbuf = NULL;
+   size_t   lbufsize = 0;
char*param;
const char  *estr;
FILE*fp;
@@ -75,19 +75,9 @@ cookie_load(void)
if (fp == NULL)
err(1, "cannot open cookie file %s", cookiefile);
date = time(NULL);
-   lbuf = NULL;
-   while ((line = fgetln(fp, )) != NULL) {
-   if (line[len - 1] == '\n') {
-   line[len - 1] = '\0';
-   --len;
-   } else {
-   if ((lbuf = malloc(len + 1)) == NULL)
-   err(1, NULL);
-   memcpy(lbuf, line, len);
-   lbuf[len] = '\0';
-   line = lbuf;
-   }
-   line[strcspn(line, "\r")] = '\0';
+   while (getline(, , fp) != -1) {
+   line = lbuf;
+   line[strcspn(line, "\r\n")] = '\0';
 
line += strspn(line, " \t");
if ((*line == '#') || (*line == '\0')) {
Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.200
diff -u -p -r1.200 fetch.c
--- usr.bin/ftp/fetch.c 2 Feb 2021 12:58:42 -   1.200
+++ usr.bin/ftp/fetch.c 2 Feb 2021 13:59:09 -
@@ -56,7 +56,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -76,7 +75,6 @@ static void   aborthttp(int);
 static charhextochar(const char *);
 static char*urldecode(const char *);
 static char*recode_credentials(const char *_userinfo);
-static char*ftp_readline(FILE *, size_t *);
 static voidftp_close(FILE **, struct tls **, int *);
 static const char *sockerror(struct tls *);
 #ifdef SMALL
@@ -330,6 +328,7 @@ url_get(const char *origline, const char
off_t hashbytes;
const char *errstr;
ssize_t len, wlen;
+   size_t bufsize;
char *proxyhost = NULL;
 #ifndef NOSSL
char *sslpath = NULL, *sslhost = NULL;
@@ -805,12 +804,13 @@ noslash:
free(buf);
 #endif /* !NOSSL */
buf = NULL;
+   bufsize = 0;
 
if (fflush(fin) == EOF) {
warnx("Writing HTTP request: %s", sockerror(tls));
goto cleanup_url_get;
}
-   if ((buf = ftp_readline(fin, )) == NULL) {
+   if ((len = getline(, , fin)) == -1) {
warnx("Receiving HTTP reply: %s", sockerror(tls));
goto cleanup_url_get;
}
@@ -885,11 +885,10 @@ noslash:
/*
 * Read the rest of the header.
 */
-   free(buf);
filesize = -1;
 
for (;;) {
-   if ((buf = ftp_rea

disklabel: make use of getline(3)

2021-01-31 Thread Christian Weisgerber
Replace fgetln(3) with getline(3).

Since getline() returns a C string, we don't need to carry around
the length separately.

OK?

Index: sbin/disklabel/editor.c
===
RCS file: /cvs/src/sbin/disklabel/editor.c,v
retrieving revision 1.364
diff -u -p -r1.364 editor.c
--- sbin/disklabel/editor.c 31 Jan 2021 14:18:44 -  1.364
+++ sbin/disklabel/editor.c 31 Jan 2021 14:35:03 -
@@ -172,7 +172,7 @@ voidzero_partitions(struct disklabel *)
 u_int64_t max_partition_size(struct disklabel *, int);
 void   display_edit(struct disklabel *, char);
 void   psize(u_int64_t sz, char unit, struct disklabel *lp);
-char   *get_token(char **, size_t *);
+char   *get_token(char **);
 intapply_unit(double, u_char, u_int64_t *);
 intparse_sizespec(const char *, double *, char **);
 intparse_sizerange(char *, u_int64_t *, u_int64_t *);
@@ -2331,8 +2331,8 @@ void
 parse_autotable(char *filename)
 {
FILE*cfile;
-   size_t   len;
-   char*buf, *t;
+   size_t   bufsize = 0;
+   char*buf = NULL, *t;
uint idx = 0, pctsum = 0;
struct space_allocation *sa;
 
@@ -2342,7 +2342,7 @@ parse_autotable(char *filename)
err(1, NULL);
alloc_table_nitems = 1;
 
-   while ((buf = fgetln(cfile, )) != NULL) {
+   while (getline(, , cfile) != -1) {
if ((alloc_table[0].table = reallocarray(alloc_table[0].table,
idx + 1, sizeof(*sa))) == NULL)
err(1, NULL);
@@ -2350,13 +2350,13 @@ parse_autotable(char *filename)
memset(sa, 0, sizeof(*sa));
idx++;
 
-   if ((sa->mp = get_token(, )) == NULL ||
+   if ((sa->mp = get_token()) == NULL ||
(sa->mp[0] != '/' && strcmp(sa->mp, "swap")))
errx(1, "%s: parse error on line %u", filename, idx);
-   if ((t = get_token(, )) == NULL ||
+   if ((t = get_token()) == NULL ||
parse_sizerange(t, >minsz, >maxsz) == -1)
errx(1, "%s: parse error on line %u", filename, idx);
-   if ((t = get_token(, )) != NULL &&
+   if ((t = get_token()) != NULL &&
parse_pct(t, >rate) == -1)
errx(1, "%s: parse error on line %u", filename, idx);
if (sa->minsz > sa->maxsz)
@@ -2367,29 +2367,27 @@ parse_autotable(char *filename)
if (pctsum > 100)
errx(1, "%s: sum of extra space allocation > 100%%", filename);
alloc_table[0].sz = idx;
+   free(buf);
fclose(cfile);
 }
 
 char *
-get_token(char **s, size_t *len)
+get_token(char **s)
 {
char*p, *r;
size_t   tlen = 0;
 
p = *s;
-   while (*len > 0 && !isspace((u_char)**s)) {
+   while (**s != '\0' && !isspace((u_char)**s)) {
(*s)++;
-   (*len)--;
tlen++;
}
if (tlen == 0)
return (NULL);
 
/* eat whitespace */
-   while (*len > 0 && isspace((u_char)**s)) {
+   while (isspace((u_char)**s))
(*s)++;
-   (*len)--;
-   }
 
if ((r = strndup(p, tlen)) == NULL)
err(1, NULL);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



fdisk: make use of getline(3)

2021-01-30 Thread Christian Weisgerber
Replace fgetln(3) with getline(3).

OK?

Index: sbin/fdisk/misc.c
===
RCS file: /cvs/src/sbin/fdisk/misc.c,v
retrieving revision 1.63
diff -u -p -r1.63 misc.c
--- sbin/fdisk/misc.c   3 Jul 2019 03:24:01 -   1.63
+++ sbin/fdisk/misc.c   30 Jan 2021 16:48:36 -
@@ -64,20 +64,18 @@ unit_lookup(char *units)
 int
 string_from_line(char *buf, size_t buflen)
 {
-   char *line;
-   size_t sz;
+   static char *line;
+   static size_t sz;
+   ssize_t len;
 
-   line = fgetln(stdin, );
-   if (line == NULL)
+   len = getline(, , stdin);
+   if (len == -1)
return (1);
 
-   if (line[sz - 1] == '\n')
-   sz--;
-   if (sz >= buflen)
-   sz = buflen - 1;
+   if (line[len - 1] == '\n')
+   line[len - 1] = '\0';
 
-   memcpy(buf, line, sz);
-   buf[sz] = '\0';
+   strlcpy(buf, line, buflen);
 
return (0);
 }
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



disklabel: pointer deref fix

2021-01-29 Thread Christian Weisgerber
Fix a pointer dereference in disklabel(8).

This looks like somebody wrote *s[0] in place of (*s)[0].
Which in this case happens to be equivalent, but it still looks
wrong.

OK?

Index: sbin/disklabel/editor.c
===
RCS file: /cvs/src/sbin/disklabel/editor.c,v
retrieving revision 1.363
diff -u -p -U6 -r1.363 editor.c
--- sbin/disklabel/editor.c 19 Nov 2019 06:20:37 -  1.363
+++ sbin/disklabel/editor.c 29 Jan 2021 23:50:24 -
@@ -2374,22 +2374,22 @@ char *
 get_token(char **s, size_t *len)
 {
char*p, *r;
size_t   tlen = 0;
 
p = *s;
-   while (*len > 0 && !isspace((u_char)*s[0])) {
+   while (*len > 0 && !isspace((u_char)**s)) {
(*s)++;
(*len)--;
tlen++;
}
if (tlen == 0)
return (NULL);
 
/* eat whitespace */
-   while (*len > 0 && isspace((u_char)*s[0])) {
+   while (*len > 0 && isspace((u_char)**s)) {
(*s)++;
(*len)--;
}
 
if ((r = strndup(p, tlen)) == NULL)
err(1, NULL);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



sed: make use of getline(3)

2021-01-29 Thread Christian Weisgerber
Replace fgetln(3) with getline(3) in sed.

The mf_fgets() part is from Johann Oskarsson for Illumos/FreeBSD.

Passes our sed regression tests.

OK?

Index: usr.bin/sed/main.c
===
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.41
diff -u -p -r1.41 main.c
--- usr.bin/sed/main.c  13 Oct 2020 06:07:54 -  1.41
+++ usr.bin/sed/main.c  29 Jan 2021 23:12:23 -
@@ -252,15 +252,9 @@ again:
goto again;
}
case ST_FILE:
-   if ((p = fgetln(f, )) != NULL) {
+   if (getline(outbuf, outsize, f) != -1) {
+   p = *outbuf;
linenum++;
-   if (len >= *outsize) {
-   free(*outbuf);
-   *outsize = ROUNDLEN(len + 1);
-   *outbuf = xmalloc(*outsize);
-   }
-   memcpy(*outbuf, p, len);
-   (*outbuf)[len] = '\0';
if (linenum == 1 && p[0] == '#' && p[1] == 'n')
nflag = 1;
return (*outbuf);
@@ -344,7 +338,8 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
struct stat sb;
size_t len;
char dirbuf[PATH_MAX];
-   char *p;
+   static char *p;
+   static size_t psize;
int c, fd;
static int firstfile;
 
@@ -429,13 +424,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
 * We are here only when infile is open and we still have something
 * to read from it.
 *
-* Use fgetln so that we can handle essentially infinite input data.
-* Can't use the pointer into the stdio buffer as the process space
-* because the ungetc() can cause it to move.
+* Use getline() so that we can handle essentially infinite input
+* data.  The p and psize are static so each invocation gives
+* getline() the same buffer which is expanded as needed.
 */
-   p = fgetln(infile, );
-   if (ferror(infile))
-   error(FATAL, "%s: %s", fname, strerror(errno ? errno : EIO));
+   len = getline(, , infile);
+   if ((ssize_t)len == -1)
+   error(FATAL, "%s: %s", fname, strerror(errno));
if (len != 0 && p[len - 1] == '\n') {
sp->append_newline = 1;
len--;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: ftp: make use of getline(3)

2021-01-29 Thread Christian Weisgerber
Hiltjo Posthuma:

> > @@ -75,19 +74,8 @@ cookie_load(void)
> > if (fp == NULL)
> > err(1, "cannot open cookie file %s", cookiefile);
> > date = time(NULL);
> > -   lbuf = NULL;
> > -   while ((line = fgetln(fp, )) != NULL) {
> > -   if (line[len - 1] == '\n') {
> > -   line[len - 1] = '\0';
> > -   --len;
> > -   } else {
> > -   if ((lbuf = malloc(len + 1)) == NULL)
> > -   err(1, NULL);
> > -   memcpy(lbuf, line, len);
> > -   lbuf[len] = '\0';
> > -   line = lbuf;
> > -   }
> > -   line[strcspn(line, "\r")] = '\0';
> > +   while (getline(, , fp) != -1) {
> > +   line[strcspn(line, "\r\n")] = '\0';
> >  
> 
> getline returns the number of characters read including the delimeter. This
> size could be used to '\0' terminate the string instead of a strcspn() call.

A strcspn() call is already there.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



ftp: make use of getline(3)

2021-01-29 Thread Christian Weisgerber
Make use of getline(3) in ftp(1).

Replace fparseln(3) with getline(3).  This removes the only use
of libutil.a(fparseln.o) from the ramdisk.
Replace a complicated fgetln(3) idiom with the much simpler getline(3).

OK?

Index: distrib/special/ftp/Makefile
===
RCS file: /cvs/src/distrib/special/ftp/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- distrib/special/ftp/Makefile16 May 2019 12:44:17 -  1.14
+++ distrib/special/ftp/Makefile29 Jan 2021 18:05:46 -
@@ -6,7 +6,4 @@ PROG=   ftp
 SRCS=  fetch.c ftp.c main.c small.c util.c
 .PATH: ${.CURDIR}/../../../usr.bin/ftp
 
-LDADD+=-lutil
-DPADD+=${LIBUTIL}
-
 .include 
Index: usr.bin/ftp/Makefile
===
RCS file: /cvs/src/usr.bin/ftp/Makefile,v
retrieving revision 1.34
diff -u -p -r1.34 Makefile
--- usr.bin/ftp/Makefile27 Jan 2021 22:27:41 -  1.34
+++ usr.bin/ftp/Makefile29 Jan 2021 17:57:31 -
@@ -8,8 +8,8 @@ PROG=   ftp
 SRCS=  cmds.c cmdtab.c complete.c cookie.c domacro.c fetch.c ftp.c \
list.c main.c ruserpass.c small.c stringlist.c util.c
 
-LDADD+=-ledit -lcurses -lutil -ltls -lssl -lcrypto
-DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBUTIL} ${LIBTLS} ${LIBSSL} 
${LIBCRYPTO}
+LDADD+=-ledit -lcurses -ltls -lssl -lcrypto
+DPADD+=${LIBEDIT} ${LIBCURSES} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
 
 #COPTS+= -Wall -Wconversion -Wstrict-prototypes -Wmissing-prototypes
 
Index: usr.bin/ftp/cookie.c
===
RCS file: /cvs/src/usr.bin/ftp/cookie.c,v
retrieving revision 1.9
diff -u -p -r1.9 cookie.c
--- usr.bin/ftp/cookie.c16 May 2019 12:44:17 -  1.9
+++ usr.bin/ftp/cookie.c29 Jan 2021 16:07:56 -
@@ -58,10 +58,9 @@ void
 cookie_load(void)
 {
field_t  field;
-   size_t   len;
time_t   date;
-   char*line;
-   char*lbuf;
+   char*line = NULL;
+   size_t   linesize = 0;
char*param;
const char  *estr;
FILE*fp;
@@ -75,19 +74,8 @@ cookie_load(void)
if (fp == NULL)
err(1, "cannot open cookie file %s", cookiefile);
date = time(NULL);
-   lbuf = NULL;
-   while ((line = fgetln(fp, )) != NULL) {
-   if (line[len - 1] == '\n') {
-   line[len - 1] = '\0';
-   --len;
-   } else {
-   if ((lbuf = malloc(len + 1)) == NULL)
-   err(1, NULL);
-   memcpy(lbuf, line, len);
-   lbuf[len] = '\0';
-   line = lbuf;
-   }
-   line[strcspn(line, "\r")] = '\0';
+   while (getline(, , fp) != -1) {
+   line[strcspn(line, "\r\n")] = '\0';
 
line += strspn(line, " \t");
if ((*line == '#') || (*line == '\0')) {
@@ -172,7 +160,7 @@ cookie_load(void)
} else
TAILQ_INSERT_TAIL(, ck, entry);
}
-   free(lbuf);
+   free(line);
fclose(fp);
 }
 
Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.199
diff -u -p -r1.199 fetch.c
--- usr.bin/ftp/fetch.c 1 Jan 2021 17:39:54 -   1.199
+++ usr.bin/ftp/fetch.c 29 Jan 2021 17:57:58 -
@@ -56,7 +56,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #ifndef NOSSL
@@ -75,7 +74,6 @@ static void   aborthttp(int);
 static charhextochar(const char *);
 static char*urldecode(const char *);
 static char*recode_credentials(const char *_userinfo);
-static char*ftp_readline(FILE *, size_t *);
 static voidftp_close(FILE **, struct tls **, int *);
 static const char *sockerror(struct tls *);
 #ifdef SMALL
@@ -329,6 +327,7 @@ url_get(const char *origline, const char
off_t hashbytes;
const char *errstr;
ssize_t len, wlen;
+   size_t bufsize;
char *proxyhost = NULL;
 #ifndef NOSSL
char *sslpath = NULL, *sslhost = NULL;
@@ -790,12 +789,13 @@ noslash:
free(buf);
 #endif /* !NOSSL */
buf = NULL;
+   bufsize = 0;
 
if (fflush(fin) == EOF) {
warnx("Writing HTTP request: %s", sockerror(tls));
goto cleanup_url_get;
}
-   if ((buf = ftp_readline(fin, )) == NULL) {
+   if ((len = getline(, , fin)) == -1) {
warnx("Receiving HTTP reply: %s", sockerror(tls));
goto cleanup_url_get;
}
@@ -867,11 +867,10 @@ noslash:
/*
 * Read the rest of the header.
 */
-   free(buf);
filesize = -1;
 
for (;;) {
-   if ((buf = 

Re: getopt.3 bugs section

2021-01-09 Thread Christian Weisgerber
Edgar Pettijohn:

> In the BUGS section for the getopt(3) manual it mentions not using
> single digits for options. I know spamd uses -4 and -6 there are
> probably others. Should they be changed? Or is the manual mistaken?

You misunderstand.  The manual warns against the use of digits to
pass numerical arguments.  This usage exists in some historical
cases, e.g. "nice -10" where <10> is the number 10.

The use of digits as flags characters, like -4 or -6 to indicate
IPv4 or IPv6, is perfectly fine.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Rename SIMPLEQ_ to STAILQ_, diff 1/7

2020-12-28 Thread Christian Weisgerber
Denis Fondras:

> This diff renames SIMPLEQ_* to STAILQ_* in /usr/src/sys/sys to unify with 
> FreeBSD and Linux.
> 
> I added aliases at the end of queue.h to avoid breaking base too much. they 
> will
> be removed as soon as diff 2,3,4,5,6,7 are commited.
> 
> net/sniproxy has a patch to define STAILQ_*, it may be removed later.

I applied diffs 1 and 2 and did a "make includes" to ensure that
_all_ header files were switched over to STAILQ.  I then ran a
package bulk build on amd64.

There were seven build failures.  Except for sniproxy those are all
programs developed on OpenBSD that use SIMPLEQ:

audio/morseplayer
devel/got
mail/pop3d
net/adsuck
net/oicb
net/sniproxy
x11/spectrwm

sniproxy breaks because the renamed s/SIMPLEQ/STAILQ/ macros lack
STAILQ_REMOVE().

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Rename SIMPLEQ_ to STAILQ_, diff 1/7

2020-12-26 Thread Christian Weisgerber
Theo de Raadt:

> What is lacking in this converstation is the justification.
> Why?

Providing STAILQ in OpenBSD will simplify porting to OpenBSD.
(Reality check: There is one port affected by this.)

Switching OpenBSD to STAILQ will simplify porting from OpenBSD.
(There are three or four FreeBSD ports affected by this.)

Having both SIMPLEQ and STAILQ will cause no disruption, but means
providing two APIs that are identical except for their name.

This appears to be a post-Berkeley divergence; 4.4BSD has neither
in .

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Rename SIMPLEQ_ to STAILQ_, diff 1/7

2020-12-26 Thread Christian Weisgerber
Denis Fondras:

> This diff renames SIMPLEQ_* to STAILQ_* in /usr/src/sys/sys to unify with 
> FreeBSD and Linux.
> 
> I added aliases at the end of queue.h to avoid breaking base too much. they 
> will
> be removed as soon as diff 2,3,4,5,6,7 are commited.

We'll need to run a ports bulk build without the aliases.  (I can
do that.) There will be some breakage.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



libcurses: --enable-const

2020-12-12 Thread Christian Weisgerber
ncurses has a configure option that adds a few more consts to its
headers by way of the NCURSES_CONST define.  Starting with version
6.0, this has become the default.  OpenBSD is still on ncurses 5.7,
but FreeBSD and I guess most Linux distributions have moved on.
I suggest we also enable the additional consts.  This eliminates
compiler warnings when sharing code with other platforms.

The diff below has successfully gone through a release build on
amd64, as well as a full amd64 package build.

OK?

Index: lib/libcurses/curses.h
===
RCS file: /cvs/src/lib/libcurses/curses.h,v
retrieving revision 1.61
diff -u -p -r1.61 curses.h
--- lib/libcurses/curses.h  6 Sep 2010 17:26:17 -   1.61
+++ lib/libcurses/curses.h  9 Dec 2020 22:56:31 -
@@ -101,7 +101,7 @@
  * doing so makes it incompatible with other implementations of X/Open Curses.
  */
 #undef  NCURSES_CONST
-#define NCURSES_CONST /*nothing*/
+#define NCURSES_CONST const
 
 #undef NCURSES_INLINE
 #define NCURSES_INLINE inline
Index: lib/libcurses/term.h
===
RCS file: /cvs/src/lib/libcurses/term.h,v
retrieving revision 1.15
diff -u -p -r1.15 term.h
--- lib/libcurses/term.h14 Nov 2015 23:56:49 -  1.15
+++ lib/libcurses/term.h9 Dec 2020 23:03:46 -
@@ -68,7 +68,7 @@ extern "C" {
  */
 
 #undef  NCURSES_CONST
-#define NCURSES_CONST /*nothing*/
+#define NCURSES_CONST const
 
 #undef  NCURSES_SBOOL
 #define NCURSES_SBOOL signed char
Index: lib/libcurses/termcap.h
===
RCS file: /cvs/src/lib/libcurses/termcap.h,v
retrieving revision 1.10
diff -u -p -r1.10 termcap.h
--- lib/libcurses/termcap.h 10 Dec 2013 20:33:51 -  1.10
+++ lib/libcurses/termcap.h 9 Dec 2020 23:03:54 -
@@ -62,7 +62,7 @@ extern "C"
 #include 
 
 #undef  NCURSES_CONST 
-#define NCURSES_CONST /*nothing*/ 
+#define NCURSES_CONST const
 
 #undef  NCURSES_OSPEED 
 #define NCURSES_OSPEED int 
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: rpki-client: use strndup instead of malloc + memcpy

2020-12-03 Thread Christian Weisgerber
Claudio Jeker:

> In tal_parse() use strndup() to create the tal descr instead of the more
> complex malloc, memcpy version. Result is the same but the strndup version
> is a lot nicer.

Yes, but...

> --- tal.c 11 Oct 2020 12:39:25 -  1.22
> +++ tal.c 3 Dec 2020 12:00:25 -
> @@ -198,10 +198,8 @@ tal_parse(const char *fn, char *buf)
>   dlen = strlen(d);
>   if (strcasecmp(d + dlen - 4, ".tal") == 0)
>   dlen -= 4;

That looks like a potential out-of-bounds access.  Are we guaranteed
that dlen >= 4 here?

> - if ((p->descr = malloc(dlen + 1)) == NULL)
> + if ((p->descr = strndup(d, dlen)) == NULL)
>   err(1, NULL);
> - memcpy(p->descr, d, dlen);
> - p->descr[dlen] = '\0';
>  
>   return p;
>  }

ok

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc lld fix

2020-11-15 Thread Christian Weisgerber
Mark Kettenis:

> What would the impact on ports of disabling base-gcc be on powerpc?

None.

$ cd /usr/ports
$ make ARCH=macppc MACHINE_ARCH=powerpc show=CHOSEN_COMPILER |grep -B1 base-gcc
$ 

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



basename(3) should have non-const arg, says POSIX

2020-10-19 Thread Christian Weisgerber
[Picking this up again after a month:]

Our basename(3) and dirname(3) take a const argument:

  char*basename(const char *);
  char*dirname(const char *);

POSIX says otherwise...

  char *basename(char *path);
  char *dirname(char *path);

... and explicitly says the functions may modify the input string.


Our functions were const-ified in 1999 by espie@:

  proper const semantics for dirname & basename.
  (this follows FreeBSD and Linux. Single Unix 2 is still illogical)

Well, four years ago, FreeBSD finally switched to the POSIX prototypes
https://svnweb.freebsd.org/base/head/include/libgen.h?revision=303451=markup
and in fact now has an implementation that modifies the string.

Linux (GNU libc) has a bizarro solution where you get a const basename()
and no dirname() if you just include , but POSIX basename()
and dirname() if you instead or also include .

This is a portability trap.  Code written on OpenBSD may not be
prepared for basename() or dirname() to splat a '\0' into the input
string, despite the warning in the man page.  This is not hypothetical.
Both Got and OpenCVS have fallen victim to the unportable assumption.


The patch below aligns the function prototypes with POSIX.  All
resulting warnings "passing 'const char *' to parameter of type
'char *' discards qualifiers" in the base system have been cleaned
up.  It successfully passes "make release".  For good measure I'm
also running a package bulk build with it as we speak.

OK?


Index: include/libgen.h
===
RCS file: /cvs/src/include/libgen.h,v
retrieving revision 1.9
diff -u -p -r1.9 libgen.h
--- include/libgen.h25 Jan 2019 00:19:25 -  1.9
+++ include/libgen.h11 Sep 2020 20:41:34 -
@@ -22,8 +22,8 @@
 #include 
 
 __BEGIN_DECLS
-char   *basename(const char *);
-char   *dirname(const char *);
+char   *basename(char *);
+char   *dirname(char *);
 __END_DECLS
 
 #endif /* _LIBGEN_H_ */
Index: lib/libc/gen/basename.3
===
RCS file: /cvs/src/lib/libc/gen/basename.3,v
retrieving revision 1.24
diff -u -p -r1.24 basename.3
--- lib/libc/gen/basename.3 25 Jan 2019 00:19:25 -  1.24
+++ lib/libc/gen/basename.3 11 Sep 2020 20:46:30 -
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn basename "const char *path"
+.Fn basename "char *path"
 .Sh DESCRIPTION
 The
 .Fn basename
Index: lib/libc/gen/basename.c
===
RCS file: /cvs/src/lib/libc/gen/basename.c,v
retrieving revision 1.16
diff -u -p -r1.16 basename.c
--- lib/libc/gen/basename.c 25 Jan 2019 00:19:25 -  1.16
+++ lib/libc/gen/basename.c 11 Sep 2020 20:43:13 -
@@ -22,7 +22,7 @@
 #include 
 
 char *
-basename(const char *path)
+basename(char *path)
 {
static char bname[PATH_MAX];
size_t len;
Index: lib/libc/gen/dirname.3
===
RCS file: /cvs/src/lib/libc/gen/dirname.3,v
retrieving revision 1.23
diff -u -p -r1.23 dirname.3
--- lib/libc/gen/dirname.3  8 Mar 2019 17:33:23 -   1.23
+++ lib/libc/gen/dirname.3  11 Sep 2020 20:47:08 -
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn dirname "const char *path"
+.Fn dirname "char *path"
 .Sh DESCRIPTION
 The
 .Fn dirname
Index: lib/libc/gen/dirname.c
===
RCS file: /cvs/src/lib/libc/gen/dirname.c,v
retrieving revision 1.16
diff -u -p -r1.16 dirname.c
--- lib/libc/gen/dirname.c  25 Jan 2019 00:19:25 -  1.16
+++ lib/libc/gen/dirname.c  11 Sep 2020 20:43:34 -
@@ -24,7 +24,7 @@
 /* A slightly modified copy of this file exists in libexec/ld.so */
 
 char *
-dirname(const char *path)
+dirname(char *path)
 {
static char dname[PATH_MAX];
size_t len;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



arm64 ddb: decode "udf" instruction

2020-10-19 Thread Christian Weisgerber
This decodes the UDF ("permanently undefined") instruction in ddb's
arm64 disassembler.  The particular immediate16 format appears to
be unique to this instruction.

OK?  Or don't bother?

Index: arch/arm64/arm64/disasm.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/disasm.c,v
retrieving revision 1.2
diff -u -p -r1.2 disasm.c
--- arch/arm64/arm64/disasm.c   11 Sep 2020 09:27:10 -  1.2
+++ arch/arm64/arm64/disasm.c   19 Oct 2020 16:17:55 -
@@ -3107,6 +3107,11 @@ OP4FUNC(op_tbz, b5, b40, imm14, Rt)
PRINTF("\n");
 }
 
+OP1FUNC(op_udf, imm16)
+{
+   PRINTF("udf\t#0x%"PRIx64"\n", imm16);
+}
+
 OP4FUNC(op_udiv, sf, Rm, Rn, Rd)
 {
PRINTF("udiv\t%s, %s, %s\n",
@@ -3668,6 +3673,8 @@ struct insn_info {
{{ 5,16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
 #define FMT_IMM16_LL   \
{{ 5,16}, { 0, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
+#define FMT_IMM16_UDF  \
+   {{ 0,16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
 #define FMT_OP0_OP1_CRN_CRM_OP2_RT \
{{19, 2}, {16, 3}, {12, 4}, { 8, 4}, { 5, 3}, { 0, 5}, { 0, 0}, { 0, 0}}
 #define FMT_IMM7_RT2_RN_RT \
@@ -3786,6 +3793,7 @@ static const struct insn_info insn_table
  { 0xd800, 0xdac1, FMT_Z_M_RN_RD,   op_pacia },
  { 0xcc00, 0x4e284800, FMT_M_D_RN_RD,   op_simd_aes },
  { 0x8c00, 0x5e280800, FMT_OP3_RN_RD,   op_simd_sha_reg2 },
+ { 0x, 0x, FMT_IMM16_UDF,   op_udf },
  { 0xfff8f01f, 0xd500401f, FMT_OP1_CRM_OP2, op_msr_imm },
  { 0xfff8, 0xd508, FMT_OP1_CRN_CRM_OP2_RT,  op_sys },
  { 0xfff8, 0xd528, FMT_OP1_CRN_CRM_OP2_RT,  op_sysl },
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



arm64, armv7: proper illegal instruction

2020-10-19 Thread Christian Weisgerber
Belatedly, ARM has taken a slice of the reserved opcode space and
assigned it as a properly defined illegal instruction, udf #imm16.
(Armv8 Architecture Reference Manual, edition F.c, section C6.2.335).
Clang already knows about it.

We really should use this instead of picking something ad-hoc out
of the opcode space.

I have verified that this builds on arm64, produces a SIGILL in
userland, and drops me into ddb in the kernel.

armv7 has an equivalent instruction.  kettenis@ confirms it builds
and SIGILLs there.

OK?

Index: lib/csu/aarch64/md_init.h
===
RCS file: /cvs/src/lib/csu/aarch64/md_init.h,v
retrieving revision 1.9
diff -u -p -r1.9 md_init.h
--- lib/csu/aarch64/md_init.h   15 Oct 2020 16:30:21 -  1.9
+++ lib/csu/aarch64/md_init.h   19 Oct 2020 11:57:02 -
@@ -115,5 +115,5 @@
"   svc #0  \n" \
"   dsb nsh \n" \
"   isb \n" \
-   "   .word 0xa000f7f0 /* illegal */  \n" \
+   "   udf #0  \n" \
".previous");
Index: lib/csu/arm/md_init.h
===
RCS file: /cvs/src/lib/csu/arm/md_init.h,v
retrieving revision 1.16
diff -u -p -r1.16 md_init.h
--- lib/csu/arm/md_init.h   15 Oct 2020 16:30:23 -  1.16
+++ lib/csu/arm/md_init.h   19 Oct 2020 13:23:00 -
@@ -159,5 +159,5 @@
"   swi #0  \n" \
"   dsb nsh \n" \
"   isb \n" \
-   "   .word 0xa000f7f0 /* illegal */  \n" \
+   "   udf #0  \n" \
".previous");
Index: lib/libc/arch/aarch64/sys/tfork_thread.S
===
RCS file: /cvs/src/lib/libc/arch/aarch64/sys/tfork_thread.S,v
retrieving revision 1.5
diff -u -p -r1.5 tfork_thread.S
--- lib/libc/arch/aarch64/sys/tfork_thread.S18 Oct 2020 14:28:16 -  
1.5
+++ lib/libc/arch/aarch64/sys/tfork_thread.S19 Oct 2020 11:59:32 -
@@ -43,6 +43,6 @@ ENTRY(__tfork_thread)
mov x0, x3
blr x2
SYSTRAP(__threxit)
-   .word   0xa000f7f0  /* illegal on all cpus? */
+   udf #0
.cfi_endproc
 END(__tfork_thread)
Index: lib/libc/arch/arm/sys/tfork_thread.S
===
RCS file: /cvs/src/lib/libc/arch/arm/sys/tfork_thread.S,v
retrieving revision 1.5
diff -u -p -r1.5 tfork_thread.S
--- lib/libc/arch/arm/sys/tfork_thread.S18 Oct 2020 14:28:17 -  
1.5
+++ lib/libc/arch/arm/sys/tfork_thread.S19 Oct 2020 13:23:35 -
@@ -37,5 +37,5 @@ ENTRY(__tfork_thread)
mov pc, r2
nop
SYSTRAP(__threxit)
-   .word   0xa000f7f0  /* illegal on all cpus? */
+   udf #0
 END(__tfork_thread)
Index: sys/arch/arm/arm/sigcode.S
===
RCS file: /cvs/src/sys/arch/arm/arm/sigcode.S,v
retrieving revision 1.9
diff -u -p -r1.9 sigcode.S
--- sys/arch/arm/arm/sigcode.S  13 Mar 2020 08:46:50 -  1.9
+++ sys/arch/arm/arm/sigcode.S  19 Oct 2020 13:23:55 -
@@ -72,7 +72,7 @@ _C_LABEL(esigcode):
 
.globl  sigfill
 sigfill:
-   .word   0xa000f7f0  /* illegal on all cpus? */
+   udf #0
 esigfill:
 
.data
Index: sys/arch/arm64/arm64/locore.S
===
RCS file: /cvs/src/sys/arch/arm64/arm64/locore.S,v
retrieving revision 1.31
diff -u -p -r1.31 locore.S
--- sys/arch/arm64/arm64/locore.S   13 Mar 2020 00:14:38 -  1.31
+++ sys/arch/arm64/arm64/locore.S   19 Oct 2020 12:02:23 -
@@ -366,7 +366,7 @@ _C_LABEL(esigcode):
 
.globl  sigfill
 sigfill:
-   .word   0xa000f7f0  /* FIXME: illegal on all cpus? */
+   udf #0
 esigfill:
 
.data
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.bin/cvs

2020-10-16 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may modify the string buffer.

There were only two compiler warnings about discarded const, but
there are numerous instances where the code assumes non-POSIX
semantics for basename() and dirname().  Given that there is at
least a FreeBSD port of OpenCVS, cleaning this up is more than
cosmetic.

This could definitely use proofreading.

I chose __func__ (otherwise not used anywhere) over breaking an overly
long "function_" "name" into parts like that.

OK?

Index: usr.bin/cvs/admin.c
===
RCS file: /cvs/src/usr.bin/cvs/admin.c,v
retrieving revision 1.68
diff -u -p -r1.68 admin.c
--- usr.bin/cvs/admin.c 1 Jun 2017 08:08:24 -   1.68
+++ usr.bin/cvs/admin.c 16 Oct 2020 21:14:05 -
@@ -246,12 +246,17 @@ cvs_admin_local(struct cvs_file *cf)
struct cvs_file *ocf;
struct rcs_access *acp;
int ofd;
-   char *d, *f, fpath[PATH_MAX], repo[PATH_MAX];
+   char *d, dbuf[PATH_MAX], *f, fbuf[PATH_MAX];
+   char fpath[PATH_MAX], repo[PATH_MAX];
 
-
-   if ((f = basename(oldfilename)) == NULL)
+   if (strlcpy(fbuf, oldfilename, sizeof(fbuf)) >= sizeof(fbuf))
+   fatal("cvs_admin_local: truncation");
+   if ((f = basename(fbuf)) == NULL)
fatal("cvs_admin_local: basename failed");
-   if ((d = dirname(oldfilename)) == NULL)
+
+   if (strlcpy(dbuf, oldfilename, sizeof(dbuf)) >= sizeof(dbuf))
+   fatal("cvs_admin_local: truncation");
+   if ((d = dirname(dbuf)) == NULL)
fatal("cvs_admin_local: dirname failed");
 
cvs_get_repository_path(d, repo, PATH_MAX);
Index: usr.bin/cvs/checkout.c
===
RCS file: /cvs/src/usr.bin/cvs/checkout.c,v
retrieving revision 1.171
diff -u -p -r1.171 checkout.c
--- usr.bin/cvs/checkout.c  1 Jun 2017 08:08:24 -   1.171
+++ usr.bin/cvs/checkout.c  16 Oct 2020 21:46:33 -
@@ -239,7 +239,7 @@ checkout_check_repository(int argc, char
struct module_checkout *mc;
struct cvs_ignpat *ip;
struct cvs_filelist *fl, *nxt;
-   char repo[PATH_MAX], fpath[PATH_MAX], *f[1];
+   char repo[PATH_MAX], fpath[PATH_MAX], path[PATH_MAX], *f[1];
 
build_dirs = print_stdout ? 0 : 1;
 
@@ -329,14 +329,25 @@ checkout_check_repository(int argc, char
cr.flags = flags;
 
if (!(mc->mc_flags & MODULE_ALIAS)) {
+   if (strlcpy(path, fl->file_path,
+   sizeof(path)) >= sizeof(path))
+   fatal("%s: truncation",
+   __func__);
module_repo_root =
-   xstrdup(dirname(fl->file_path));
+   xstrdup(dirname(path));
d = wdir;
+   if (strlcpy(path, fl->file_path,
+   sizeof(path)) >= sizeof(path))
+   fatal("%s: truncation",
+   __func__);
(void)xsnprintf(fpath, sizeof(fpath),
-   "%s/%s", d,
-   basename(fl->file_path));
+   "%s/%s", d, basename(path));
} else {
-   d = dirname(wdir);
+   if (strlcpy(path, wdir,
+   sizeof(path)) >= sizeof(path))
+   fatal("%s: truncation",
+   __func__);
+   d = dirname(path);
strlcpy(fpath, fl->file_path,
sizeof(fpath));
}
@@ -387,7 +398,7 @@ checkout_check_repository(int argc, char
 static int
 checkout_classify(const char *repo, const char *arg)
 {
-   char *d, *f, fpath[PATH_MAX];
+   char *d, dbuf[PATH_MAX], *f, fbuf[PATH_MAX], fpath[PATH_MAX];
struct stat sb;
 
if (stat(repo, ) == 0) {
@@ -395,8 +406,13 @@ checkout_classify(const char *repo, cons
return CVS_DIR;
}
 
-   d = dirname(repo);
-   f = basename(repo);
+   if (strlcpy(dbuf, repo, sizeof(dbuf)) >= sizeof(dbuf))
+   fatal("checkout_classify: truncation");
+   d = 

Non-const basename: usr.bin/ftp

2020-10-15 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may modify the string buffer.

I've tried to follow the conventions of the existing code.

ok?

Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.197
diff -u -p -r1.197 fetch.c
--- usr.bin/ftp/fetch.c 4 Jul 2020 11:23:35 -   1.197
+++ usr.bin/ftp/fetch.c 15 Oct 2020 21:14:28 -
@@ -192,7 +192,7 @@ file_get(const char *path, const char *o
int  fd, out = -1, rval = -1, save_errno;
volatile sig_t   oldintr, oldinti;
const char  *savefile;
-   char*buf = NULL, *cp;
+   char*buf = NULL, *cp, *pathbuf = NULL;
const size_t buflen = 128 * 1024;
off_thashbytes;
ssize_t  len, wlen;
@@ -215,8 +215,12 @@ file_get(const char *path, const char *o
else {
if (path[strlen(path) - 1] == '/')  /* Consider no file */
savefile = NULL;/* after dir invalid. */
-   else
-   savefile = basename(path);
+   else {
+   pathbuf = strdup(path);
+   if (pathbuf == NULL)
+   errx(1, "Can't allocate memory for filename");
+   savefile = basename(pathbuf);
+   }
}
 
if (EMPTYSTRING(savefile)) {
@@ -294,6 +298,7 @@ file_get(const char *path, const char *o
 
 cleanup_copy:
free(buf);
+   free(pathbuf);
if (out >= 0 && out != fileno(stdout))
close(out);
close(fd);
@@ -315,6 +320,7 @@ url_get(const char *origline, const char
int isunavail = 0, retryafter = -1;
struct addrinfo hints, *res0, *res;
const char *savefile;
+   char *pathbuf = NULL;
char *proxyurl = NULL;
char *credentials = NULL, *proxy_credentials = NULL;
int fd = -1, out = -1;
@@ -412,8 +418,12 @@ noslash:
else {
if (path[strlen(path) - 1] == '/')  /* Consider no file */
savefile = NULL;/* after dir invalid. */
-   else
-   savefile = basename(path);
+   else {
+   pathbuf = strdup(path);
+   if (pathbuf == NULL)
+   errx(1, "Can't allocate memory for filename");
+   savefile = basename(pathbuf);
+   }
}
 
if (EMPTYSTRING(savefile)) {
@@ -1106,6 +1116,7 @@ cleanup_url_get:
if (out >= 0 && out != fileno(stdout))
close(out);
free(buf);
+   free(pathbuf);
free(proxyhost);
free(proxyurl);
free(newline);
Index: usr.bin/ftp/util.c
===
RCS file: /cvs/src/usr.bin/ftp/util.c,v
retrieving revision 1.93
diff -u -p -r1.93 util.c
--- usr.bin/ftp/util.c  6 Jul 2020 17:11:29 -   1.93
+++ usr.bin/ftp/util.c  15 Oct 2020 21:31:55 -
@@ -763,7 +763,7 @@ progressmeter(int flag, const char *file
off_t cursize, abbrevsize;
double elapsed;
int ratio, barlength, i, remaining, overhead = 30;
-   char buf[512];
+   char buf[512], *filenamebuf;
 
if (flag == -1) {
clock_gettime(CLOCK_MONOTONIC, );
@@ -782,11 +782,13 @@ progressmeter(int flag, const char *file
ratio = MAXIMUM(ratio, 0);
ratio = MINIMUM(ratio, 100);
if (!verbose && flag == -1) {
-   filename = basename(filename);
-   if (filename != NULL) {
+   filenamebuf = strdup(filename);
+   filename = basename(filenamebuf);
+   if (filenamebuf != NULL && filename != NULL) {
free(title);
title = strdup(filename);
}
+   free(filenamebuf);
}
 
buf[0] = 0;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.sbin/vmd, usr.sbin/vmctl

2020-10-14 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may in fact modify the string buffer.

The file is built by vmd and vmctl.

I'm uncertain if we want a truncation check here.  Both in vmd and
vmctl, the path has been validated by a previous open(), but given
the code complexity, do we want to rely on this?


Index: usr.sbin/vmd/vioqcow2.c
===
RCS file: /cvs/src/usr.sbin/vmd/vioqcow2.c,v
retrieving revision 1.13
diff -u -p -r1.13 vioqcow2.c
--- usr.sbin/vmd/vioqcow2.c 10 Jan 2019 19:21:02 -  1.13
+++ usr.sbin/vmd/vioqcow2.c 14 Oct 2020 20:57:31 -
@@ -145,6 +145,7 @@ virtio_qcow2_init(struct virtio_backing 
 ssize_t
 virtio_qcow2_get_base(int fd, char *path, size_t npath, const char *dpath)
 {
+   char dpathbuf[PATH_MAX];
char expanded[PATH_MAX];
struct qcheader header;
uint64_t backingoff;
@@ -186,7 +187,8 @@ virtio_qcow2_get_base(int fd, char *path
return -1;
}
} else {
-   s = dirname(dpath);
+   strlcpy(dpathbuf, dpath, sizeof(dpathbuf));
+   s = dirname(dpathbuf);
if (snprintf(expanded, sizeof(expanded),
"%s/%s", s, path) >= (int)sizeof(expanded)) {
log_warnx("path too long: %s/%s", s, path);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.bin/rcs

2020-10-14 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may in fact modify the string buffer.

ok?

Index: usr.bin/rcs/rlog.c
===
RCS file: /cvs/src/usr.bin/rcs/rlog.c,v
retrieving revision 1.74
diff -u -p -r1.74 rlog.c
--- usr.bin/rcs/rlog.c  16 Oct 2016 13:35:51 -  1.74
+++ usr.bin/rcs/rlog.c  14 Oct 2020 20:18:55 -
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -348,7 +349,7 @@ rlog_select_daterev(RCSFILE *rcsfile, ch
 static void
 rlog_file(const char *fname, RCSFILE *file)
 {
-   char numb[RCS_REV_BUFSZ];
+   char fnamebuf[PATH_MAX], numb[RCS_REV_BUFSZ];
u_int nrev;
struct rcs_sym *sym;
struct rcs_access *acp;
@@ -364,7 +365,10 @@ rlog_file(const char *fname, RCSFILE *fi
} else
nrev = file->rf_ndelta;
 
-   if ((workfile = basename(fname)) == NULL)
+   if (strlcpy(fnamebuf, fname, sizeof(fnamebuf)) >= sizeof(fnamebuf))
+   errx(1, "rlog_file: truncation");
+
+   if ((workfile = basename(fnamebuf)) == NULL)
err(1, "basename");
 
/*
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: sbin/pfctl

2020-10-13 Thread Christian Weisgerber
Accommodate a basename(3) that takes a non-const parameter and may
in fact modify the string buffer.

The length of anchor has already been checked in main().

ok?

Index: sbin/pfctl/pfctl.c
===
RCS file: /cvs/src/sbin/pfctl/pfctl.c,v
retrieving revision 1.382
diff -u -p -r1.382 pfctl.c
--- sbin/pfctl/pfctl.c  16 Jan 2020 01:02:20 -  1.382
+++ sbin/pfctl/pfctl.c  13 Oct 2020 20:45:16 -
@@ -2241,16 +2241,19 @@ pfctl_get_anchors(int dev, const char *a
 {
struct pfioc_rulesetpr;
static struct pfr_anchors anchors;
+   char anchorbuf[PATH_MAX];
char *n;
 
SLIST_INIT();
 
memset(, 0, sizeof(pr));
if (*anchor != '\0') {
-   n = dirname(anchor);
+   strlcpy(anchorbuf, anchor, sizeof(anchorbuf));
+   n = dirname(anchorbuf);
if (n[0] != '.' && n[1] != '\0')
strlcpy(pr.path, n, sizeof(pr.path));
-   n = basename(anchor);
+   strlcpy(anchorbuf, anchor, sizeof(anchorbuf));
+   n = basename(anchorbuf);
if (n != NULL)
strlcpy(pr.name, n, sizeof(pr.name));
}
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



net/pfvar.h: MAXPATHLEN -> PATH_MAX

2020-10-13 Thread Christian Weisgerber
In revision 1.407 of , deraadt@ replaced MAXPATHLEN
with PATH_MAX so userland wouldn't have to pull in .

In 1.466, sashan@ accidentally slipped one MAXPATHLEN back in,
because its use is ubiquitous on the kernel side of pf.  Switch
this over to PATH_MAX again.

pfctl(8) doesn't actually use this, so it's very cosmetic.

Index: sys/net/pfvar.h
===
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.496
diff -u -p -r1.496 pfvar.h
--- sys/net/pfvar.h 24 Aug 2020 15:30:58 -  1.496
+++ sys/net/pfvar.h 13 Oct 2020 20:21:04 -
@@ -475,7 +475,7 @@ union pf_rule_ptr {
 };
 
 #definePF_ANCHOR_NAME_SIZE  64
-#definePF_ANCHOR_MAXPATH   (MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)
+#definePF_ANCHOR_MAXPATH   (PATH_MAX - PF_ANCHOR_NAME_SIZE - 1)
 #definePF_OPTIMIZER_TABLE_PFX  "__automatic_"
 
 struct pf_rule {
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: bin/chio

2020-10-13 Thread Christian Weisgerber
As far as I understand, the basename() here is specifically intended
to skip a leading "/dev/".  So how about doing this expressly?

Do we want to use _PATH_DEV or "/dev/"?  There's a "/dev/rst%d" a
few lines outside of the diff context...

Index: bin/chio/parse.y
===
RCS file: /cvs/src/bin/chio/parse.y,v
retrieving revision 1.22
diff -u -p -r1.22 parse.y
--- bin/chio/parse.y13 Feb 2019 22:57:07 -  1.22
+++ bin/chio/parse.y13 Oct 2020 19:23:22 -
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -445,10 +446,12 @@ parse_tapedev(const char *filename, cons
errors = file->errors;
popfile();
 
+   if (strncmp(changer, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+   changer += sizeof(_PATH_DEV) - 1;
TAILQ_FOREACH(p, , entry) {
-   if (strcmp(basename(changer), p->name) == 0) {
+   if (strcmp(changer, p->name) == 0) {
if (drive >= 0 && drive < p->drivecnt) {
-   if (asprintf(, "/dev/%s",
+   if (asprintf(, _PATH_DEV "%s",
 p->drives[drive]) == -1)
errx(1, "malloc failed");
} else
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.sbin/hotplugd

2020-10-13 Thread Christian Weisgerber
Accommodate a basename(3) that takes a non-const parameter and may
in fact modify the string buffer.

Between access(file, ...) and execl(file, ...), no check for
truncation should be necessary.

ok?

Index: usr.sbin/hotplugd/hotplugd.c
===
RCS file: /cvs/src/usr.sbin/hotplugd/hotplugd.c,v
retrieving revision 1.15
diff -u -p -r1.15 hotplugd.c
--- usr.sbin/hotplugd/hotplugd.c30 Apr 2019 17:05:15 -  1.15
+++ usr.sbin/hotplugd/hotplugd.c13 Oct 2020 16:19:43 -
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -163,7 +164,10 @@ exec_script(const char *file, int class,
}
if (pid == 0) {
/* child process */
-   execl(file, basename(file), strclass, name, (char *)NULL);
+   char filebuf[PATH_MAX];
+
+   strlcpy(filebuf, file, sizeof(filebuf));
+   execl(file, basename(filebuf), strclass, name, (char *)NULL);
syslog(LOG_ERR, "execl %s: %m", file);
_exit(1);
/* NOTREACHED */
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: libkvm

2020-10-13 Thread Christian Weisgerber
Accommodate a basename(3) that takes a non-const parameter and may
in fact modify the string buffer.

Note that strlen(uf) >= PATH_MAX is already checked by the caller
in _kvm_open().

ok?

Index: lib/libkvm/kvm.c
===
RCS file: /cvs/src/lib/libkvm/kvm.c,v
retrieving revision 1.66
diff -u -p -r1.66 kvm.c
--- lib/libkvm/kvm.c28 Jun 2019 13:32:42 -  1.66
+++ lib/libkvm/kvm.c13 Oct 2020 08:55:29 -
@@ -676,12 +676,13 @@ static int
 kvm_dbopen(kvm_t *kd, const char *uf)
 {
char dbversion[_POSIX2_LINE_MAX], kversion[_POSIX2_LINE_MAX];
-   char dbname[PATH_MAX];
+   char dbname[PATH_MAX], ufbuf[PATH_MAX];
struct nlist nitem;
size_t dbversionlen;
DBT rec;
 
-   uf = basename(uf);
+   strlcpy(ufbuf, uf, sizeof(ufbuf));
+   uf = basename(ufbuf);
 
(void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Non-const basename: usr.bin/sed

2020-10-11 Thread Christian Weisgerber
Martijn van Duren:

> Wouldn't the following diff be a little simpler?

Yes, it would.  
Should dirbuf be static like oldfname and tmpfname?

Index: main.c
===
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.40
diff -u -p -r1.40 main.c
--- main.c  8 Dec 2018 23:11:24 -   1.40
+++ main.c  11 Oct 2020 15:08:29 -
@@ -96,6 +96,7 @@ const char *fname;/* File name. */
 const char *outfname;  /* Output file name */
 static char oldfname[PATH_MAX];/* Old file name (for in-place editing) 
*/
 static char tmpfname[PATH_MAX];/* Temporary file name (for in-place 
editing) */
+static char dirbuf[PATH_MAX];  /* Temporary path name (for dirname(3)) */
 char *inplace; /* Inplace edit file extension */
 u_long linenum;
 
@@ -397,8 +398,9 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
if (len > sizeof(oldfname))
error(FATAL, "%s: name too long", 
fname);
}
-   len = snprintf(tmpfname, sizeof(tmpfname), 
"%s/sedXX",
-   dirname(fname));
+   strlcpy(dirbuf, fname, sizeof(dirbuf));
+   len = snprintf(tmpfname, sizeof(tmpfname),
+   "%s/sedXX", dirname(dirbuf));
if (len >= sizeof(tmpfname))
error(FATAL, "%s: name too long", fname);
if ((fd = mkstemp(tmpfname)) == -1)
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: WANTLIB problems and possible solution: the libset design

2020-10-11 Thread Christian Weisgerber
Marc Espie:

> The new design:
> 
> The idea behind "libset" is to be able to specify a "set" of wantlib that
> corresponds to our package, AND to just write WANTLIB wrt that libset for
> that specific set of libraries.

I'm struggling to understand whether this libset records the libraries
a port depends on, the libraries the port provides, or both.

Let's say--slightly simplified from reality--we have devel/gettext
that provides libintl and depends on iconv from converters/libiconv.
What would gettext's LIBSET entry look like?

(1) LIBSET = iconv
(2) LIBSET = intl
(3) LIBSET = intl iconv

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.bin/compress

2020-10-10 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may in fact modify the string buffer.

Following martijn@'s comment for the sed diff, we don't need to
check for truncation because the "in" path has already been validated
by a preceding open(2).

ok?

Index: usr.bin/compress/main.c
===
RCS file: /cvs/src/usr.bin/compress/main.c,v
retrieving revision 1.96
diff -u -p -r1.96 main.c
--- usr.bin/compress/main.c 28 Jun 2019 13:35:00 -  1.96
+++ usr.bin/compress/main.c 10 Oct 2020 20:10:44 -
@@ -481,6 +481,7 @@ docompress(const char *in, char *out, co
 {
 #ifndef SMALL
u_char buf[Z_BUFSIZE];
+   char namebuf[PATH_MAX];
char *name;
int error, ifd, ofd, oreg;
void *cookie;
@@ -534,7 +535,8 @@ docompress(const char *in, char *out, co
}
 
if (!pipin && storename) {
-   name = basename(in);
+   strlcpy(namebuf, in, sizeof(namebuf));
+   name = basename(namebuf);
mtime = (u_int32_t)sb->st_mtime;
}
if ((cookie = method->wopen(ofd, name, bits, mtime)) == NULL) {
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.bin/sed

2020-10-10 Thread Christian Weisgerber
Changing basename(3) and dirname(3) to the POSIX-mandated non-const
parameters produces this warnings when compiling sed(1):

/usr/src/usr.bin/sed/main.c:401:16: warning: passing 'const char *' to parameter
 of type 'char *' discards qualifiers [-Wincompatible-pointer-types-discards-qua
lifiers]

Here's a fix to accommodate a basename(3) that takes a non-const
parameter and may in fact modify the string buffer.  Based on FreeBSD
like the surrounding in-place editing code.

OK?

Index: main.c
===
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.40
diff -u -p -r1.40 main.c
--- main.c  8 Dec 2018 23:11:24 -   1.40
+++ main.c  10 Oct 2020 15:16:12 -
@@ -343,6 +343,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
 {
struct stat sb;
size_t len;
+   char *dirbuf;
char *p;
int c, fd;
static int firstfile;
@@ -397,8 +398,11 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
if (len > sizeof(oldfname))
error(FATAL, "%s: name too long", 
fname);
}
+   if ((dirbuf = strdup(fname)) == NULL)
+   error(FATAL, "%s", strerror(errno));
len = snprintf(tmpfname, sizeof(tmpfname), 
"%s/sedXX",
-   dirname(fname));
+   dirname(dirbuf));
+   free(dirbuf);
if (len >= sizeof(tmpfname))
error(FATAL, "%s: name too long", fname);
if ((fd = mkstemp(tmpfname)) == -1)
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Non-const basename: usr.bin/patch

2020-10-10 Thread Christian Weisgerber
Changing basename(3) and dirname(3) to the POSIX-mandated non-const
parameters produces these warnings when compiling patch(1):

/usr/src/usr.bin/patch/backupfile.c:61:34: warning: passing 'const char *' to pa
rameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types-disca
rds-qualifiers]
/usr/src/usr.bin/patch/backupfile.c:64:16: warning: passing 'const char *' to pa
rameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types-disca
rds-qualifiers]

Here's a fix to accommodate a basename(3) that takes a non-const
parameter and may in fact modify the string buffer.  This is
originally from Joerg Sonnenberger for DragonFly BSD and has since
spread to the other BSDs.
https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/41871674d0079dec70d55eb824f39d07dc7b3310
(The corresponding change to inp.c is no longer applicable as that
code has been removed.)

OK?

Index: usr.bin/patch/backupfile.c
===
RCS file: /cvs/src/usr.bin/patch/backupfile.c,v
retrieving revision 1.21
diff -u -p -r1.21 backupfile.c
--- usr.bin/patch/backupfile.c  26 Nov 2013 13:19:07 -  1.21
+++ usr.bin/patch/backupfile.c  10 Oct 2020 14:36:58 -
@@ -53,21 +53,32 @@ static void invalid_arg(const char *, co
 char *
 find_backup_file_name(const char *file)
 {
-   char*dir, *base_versions;
+   char*dir, *base_versions, *tmp_file;
int highest_backup;
 
if (backup_type == simple)
return concat(file, simple_backup_suffix);
-   base_versions = concat(basename(file), ".~");
+   tmp_file = strdup(file);
+   if (tmp_file == NULL)
+   return NULL;
+   base_versions = concat(basename(tmp_file), ".~");
+   free(tmp_file);
if (base_versions == NULL)
return NULL;
-   dir = dirname(file);
+   tmp_file = strdup(file);
+   if (tmp_file == NULL) {
+   free(base_versions);
+   return NULL;
+   }
+   dir = dirname(tmp_file);
if (dir == NULL) {
free(base_versions);
+   free(tmp_file);
return NULL;
}
highest_backup = max_backup_version(base_versions, dir);
free(base_versions);
+   free(tmp_file);
if (backup_type == numbered_existing && highest_backup == 0)
return concat(file, simple_backup_suffix);
return make_version_name(file, highest_backup + 1);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: ssh-keygen: generate ed25519 keys by default

2020-10-08 Thread Christian Weisgerber
On 2020-10-08, Eldritch  wrote:

> With the recent change to prefer ed25519 keys on the server side [1]
> (unless I misunderstood what the change does), I think generating

This only changed the client's order of preference for the various
server key types.  If a server doesn't offer an Ed25519 key, the
client will transparently fall back to one of the other types.

> ed25519 keys by default with ssh-keygen makes sense at this point.
>
> Is there a reason not to do this? I am curious if so, as there's no
> discussion on this matter that I could find.

Those are mostly user keys.  What happens if you upload an Ed25519
public user key to a server that doesn't handle this key type?  It
won't work.  And you're not likely to be presented with a helpful
error message.  It just doesn't work.

At this point, I don't know how many SSH servers are still out there
that don't handle Ed25519.  I still have an ECDSA key somewhere
that I use to log into a machine that still runs... "OpenSSH_6.0p1
Debian-4+deb7u7, OpenSSL 1.0.1t  3 May 2016".  There is a lot of
networking equipment that allows uploading of a user key for SSH
login but may include a comically obsolete version of OpenSSH or
some alternative implementation that doesn't do Ed25519.

So... is it the right time yet?
I don't know, and it's certainly not my decision, but I think that's
the background.

> --- ssh-keygen.c  9 Sep 2020 03:08:01 -   1.420
> +++ ssh-keygen.c  8 Oct 2020 08:21:37 -

That's at least missing a corresponding change to the man page.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: basename(3) should have non-const arg, says POSIX

2020-09-12 Thread Christian Weisgerber
Todd C. Miller:

> This is probably the right thing to do but we should fix the warnings
> it generates.  In this new world order, passing a const char * to
> basename() or dirname() is unsafe.

FWIW, here's the list:

/usr/src/lib/libkvm/kvm.c:684:16: warning: passing 'const char *' to parameter 
of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
uf = basename(uf);
  ^~
/usr/src/bin/chio/parse.y:449:23: warning: passing 'const char *' to parameter 
of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
if (strcmp(basename(changer), p->name) == 0) {
^~~
/usr/src/sbin/pfctl/pfctl.c:2250:15: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
n = dirname(anchor);
^~
/usr/src/sbin/pfctl/pfctl.c:2253:16: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
n = basename(anchor);
 ^~
/usr/src/usr.bin/compress/main.c:537:19: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
name = basename(in);
^~
/usr/src/usr.bin/cvs/checkout.c:398:14: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
d = dirname(repo);
^~~~
/usr/src/usr.bin/cvs/checkout.c:399:15: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
f = basename(repo);
 ^~~~
/usr/src/usr.bin/ftp/fetch.c:219:24: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
savefile = basename(path);
^~~~
/usr/src/usr.bin/ftp/util.c:785:23: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
filename = basename(filename);
^~~~
/usr/src/usr.bin/patch/backupfile.c:61:34: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
base_versions = concat(basename(file), ".~");
^~~~
/usr/src/usr.bin/patch/backupfile.c:64:16: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
dir = dirname(file);
  ^~~~
/usr/src/usr.bin/rcs/rlog.c:367:27: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
if ((workfile = basename(fname)) == NULL)
 ^
/usr/src/usr.bin/sed/main.c:401:16: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
dirname(fname));
^
/usr/src/usr.sbin/hotplugd/hotplugd.c:166:24: warning: passing 'const char *' 
to parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
execl(file, basename(file), strclass, name, (char *)NULL);
 ^~~~
/usr/src/usr.sbin/vmd/vioqcow2.c:189:15: warning: passing 'const char *' to 
parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
s = dirname(dpath);
^
/usr/src/usr.sbin/vmctl/../vmd/vioqcow2.c:189:15: warning: passing 'const char 
*' to parameter of type 'char *' discards qualifiers 
[-Wincompatible-pointer-types-discards-qualifiers]
s = dirname(dpath);
^

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



basename(3) should have non-const arg, says POSIX

2020-09-12 Thread Christian Weisgerber
Our basename(3) and dirname(3) take a const argument:

  char*basename(const char *);
  char*dirname(const char *);

POSIX says otherwise...

  char *basename(char *path);
  char *dirname(char *path);

... and explicitly says the functions may modify the input string.


Our functions were const-ified in 1999 by espie@:

  proper const semantics for dirname & basename.
  (this follows FreeBSD and Linux. Single Unix 2 is still illogical)

Well, four years ago, FreeBSD finally switched to the POSIX prototypes
https://svnweb.freebsd.org/base/head/include/libgen.h?revision=303451=markup
and in fact now has an implementation that modifies the string.

Linux (GNU libc) has a bizarro solution where you get a const basename()
and no dirname() if you just include , but POSIX basename()
and dirname() if you instead or also include .

A make build with the patch below succeeds, but gains some new
warnings "passing 'const char *' to parameter of type 'char *'
discards qualifiers".

This is a portability trap.  Code written on OpenBSD may not be
prepared for basename() or dirname() to splat a '\0' into the input
string, despite the warning in the man page.

I'm in favor of moving to the POSIX prototypes, but I don't know
if there are any hidden pitfalls I may be missing.  Opinions,
comments?


Index: include/libgen.h
===
RCS file: /cvs/src/include/libgen.h,v
retrieving revision 1.9
diff -u -p -r1.9 libgen.h
--- include/libgen.h25 Jan 2019 00:19:25 -  1.9
+++ include/libgen.h11 Sep 2020 20:41:34 -
@@ -22,8 +22,8 @@
 #include 
 
 __BEGIN_DECLS
-char   *basename(const char *);
-char   *dirname(const char *);
+char   *basename(char *);
+char   *dirname(char *);
 __END_DECLS
 
 #endif /* _LIBGEN_H_ */
Index: lib/libc/gen/basename.3
===
RCS file: /cvs/src/lib/libc/gen/basename.3,v
retrieving revision 1.24
diff -u -p -r1.24 basename.3
--- lib/libc/gen/basename.3 25 Jan 2019 00:19:25 -  1.24
+++ lib/libc/gen/basename.3 11 Sep 2020 20:46:30 -
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn basename "const char *path"
+.Fn basename "char *path"
 .Sh DESCRIPTION
 The
 .Fn basename
Index: lib/libc/gen/basename.c
===
RCS file: /cvs/src/lib/libc/gen/basename.c,v
retrieving revision 1.16
diff -u -p -r1.16 basename.c
--- lib/libc/gen/basename.c 25 Jan 2019 00:19:25 -  1.16
+++ lib/libc/gen/basename.c 11 Sep 2020 20:43:13 -
@@ -22,7 +22,7 @@
 #include 
 
 char *
-basename(const char *path)
+basename(char *path)
 {
static char bname[PATH_MAX];
size_t len;
Index: lib/libc/gen/dirname.3
===
RCS file: /cvs/src/lib/libc/gen/dirname.3,v
retrieving revision 1.23
diff -u -p -r1.23 dirname.3
--- lib/libc/gen/dirname.3  8 Mar 2019 17:33:23 -   1.23
+++ lib/libc/gen/dirname.3  11 Sep 2020 20:47:08 -
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn dirname "const char *path"
+.Fn dirname "char *path"
 .Sh DESCRIPTION
 The
 .Fn dirname
Index: lib/libc/gen/dirname.c
===
RCS file: /cvs/src/lib/libc/gen/dirname.c,v
retrieving revision 1.16
diff -u -p -r1.16 dirname.c
--- lib/libc/gen/dirname.c  25 Jan 2019 00:19:25 -  1.16
+++ lib/libc/gen/dirname.c  11 Sep 2020 20:43:34 -
@@ -24,7 +24,7 @@
 /* A slightly modified copy of this file exists in libexec/ld.so */
 
 char *
-dirname(const char *path)
+dirname(char *path)
 {
static char dname[PATH_MAX];
size_t len;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Format string check for dprintf(3)

2020-09-10 Thread Christian Weisgerber
Add format string checking annotations for dprintf(3) and vdprintf(3).

This was apparently forgotten when the functions were added.  It is
required so the compiler can warn

t.c:25:25: warning: format string is not a string literal (potentially
insecure)
  [-Wformat-security]
dprintf(STDOUT_FILENO, msg);
   ^~~

Absent -Werror, I do not expect any fallout from this, but I ran a
successful amd64 make build with it anyway.

ok?

Index: include/stdio.h
===
RCS file: /cvs/src/include/stdio.h,v
retrieving revision 1.53
diff -u -p -r1.53 stdio.h
--- include/stdio.h 9 Sep 2016 18:12:37 -   1.53
+++ include/stdio.h 10 Sep 2020 15:07:08 -
@@ -204,7 +204,9 @@ __END_DECLS
 __BEGIN_DECLS
 voidclearerr(FILE *);
 #if __POSIX_VISIBLE >= 200809
-int dprintf(int, const char * __restrict, ...);
+int dprintf(int, const char * __restrict, ...)
+   __attribute__((__format__ (printf, 2, 3)))
+   __attribute__((__nonnull__ (2)));
 #endif
 int fclose(FILE *);
 int feof(FILE *);
@@ -266,7 +268,9 @@ int  vfprintf(FILE *, const char *, __va
 int vprintf(const char *, __va_list);
 int vsprintf(char *, const char *, __va_list);
 #if __POSIX_VISIBLE >= 200809
-int vdprintf(int, const char * __restrict, __va_list);
+int vdprintf(int, const char * __restrict, __va_list)
+   __attribute__((__format__ (printf, 2, 0)))
+   __attribute__((__nonnull__ (2)));
 #endif
 
 #if __ISO_C_VISIBLE >= 1999 || __XPG_VISIBLE >= 500 || __BSD_VISIBLE
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: timekeep: fixing large skews on amd64 with RDTSCP

2020-08-23 Thread Christian Weisgerber
Scott Cheloha:

> This "it might slow down the network stack" thing keeps coming up, and
> yet nobody can point to (a) who expressed this concern or (b) what the
> penalty is in practice.

It was kettenis@ who simply raised the question and asked for
comments from the network people.

I think we should just go ahead and use rdtsc_lfence() in
tsc_get_timecount().  It is *correct*.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: man find -exec -- a little bit more hand-holding

2020-08-14 Thread Christian Weisgerber
On 2020-08-14, Jason McIntyre  wrote:

> - i cannot work out what is with the \! examples. i know we try to make
>   entries work for both csh and sh style shells, but stuff like this
>   works without escaping:
>
>   $ find . ! -type f

Going through the CVS and SCCS history, I see that the examples
came with a rewrite of find(1) at Berkeley 30 years ago.

csh's behavior that "for convenience, a `!' is passed unchanged
when it is followed by a blank, tab, newline, `=' or `('" has been
documented as such at least since the start of the CSRG repository
in 1985.

bash, whose history substitution was modeled on csh, also shares
this behavior.

I think it was never necessary to escape the '!' and the man page
examples were written with an abundance of caution and a lack of
understanding of csh's exact replacement mechanism.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



mountd: Avoid reading one byte before buffer

2020-08-06 Thread Christian Weisgerber
>From CheriBSD, via FreeBSD:

| Avoid reading one byte before the path buffer.
| 
| This happens when there's only one component (e.g. "/foo"). This
| (mostly-harmless) bug has been present since June 1990 when it was
| commited to mountd.c SCCS version 5.9.
| 
| Note: the bug is on the second changed line, the first line is changed
| for visual consistency.
https://svnweb.freebsd.org/base?view=revision=363435

You need to look at the surrounding loop to see the problem.

OK?

Index: sbin/mountd/mountd.c
===
RCS file: /cvs/src/sbin/mountd/mountd.c,v
retrieving revision 1.88
diff -u -p -r1.88 mountd.c
--- sbin/mountd/mountd.c24 Jan 2020 18:51:45 -  1.88
+++ sbin/mountd/mountd.c6 Aug 2020 14:41:16 -
@@ -2021,9 +2021,9 @@ do_mount(struct exportlist *ep, struct g
 #endif
}
/* back up over the last component */
-   while (*cp == '/' && cp > dirp)
+   while (cp > dirp && *cp == '/')
cp--;
-   while (*(cp - 1) != '/' && cp > dirp)
+   while (cp > dirp && *(cp - 1) != '/')
cp--;
if (cp == dirp) {
if (debug)
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: timekeep: fixing large skews on amd64 with RDTSCP

2020-07-27 Thread Christian Weisgerber
Scott Cheloha:

> --- lib/libc/arch/amd64/gen/usertc.c  8 Jul 2020 09:17:48 -   1.2
> +++ lib/libc/arch/amd64/gen/usertc.c  25 Jul 2020 17:50:38 -
> @@ -21,9 +21,12 @@
>  static inline u_int
>  rdtsc(void)
>  {
> - uint32_t hi, lo;
> - asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
> - return ((uint64_t)lo)|(((uint64_t)hi)<<32);
> + uint32_t lo;
> +
> + asm volatile("lfence");
> + asm volatile("rdtsc" : "=a"(lo) : : "rdx");

Is there a guarantee that two separate asm()s will not be reordered?

> +
> + return lo;
>  }
>  
>  static int
> --- sys/arch/amd64/amd64/tsc.c6 Jul 2020 13:33:06 -   1.19
> +++ sys/arch/amd64/amd64/tsc.c25 Jul 2020 17:50:38 -
> @@ -211,7 +211,12 @@ cpu_recalibrate_tsc(struct timecounter *
>  u_int
>  tsc_get_timecount(struct timecounter *tc)
>  {
> - return rdtsc() + curcpu()->ci_tsc_skew;
> + uint32_t lo;
> +
> + asm volatile("lfence");
> + asm volatile("rdtsc" : "=a"(lo) : : "rdx");
> +
> + return lo + curcpu()->ci_tsc_skew;
>  }
>  
>  void
> 

I'd just do s/rdtsc/rdtsc_lfence/, which would agree well with the
rest of the file.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: timekeep: fixing large skews on amd64 with RDTSCP

2020-07-16 Thread Christian Weisgerber
Scott Cheloha:

> Can we add the missing LFENCE instructions to userspace and the
> kernel?  And can we excise the upper 32 bits?

> + uint32_t lo;
> +
> + asm volatile("lfence");
> + asm volatile("rdtsc" : "=a"(lo));

That's wrong.  rtdsc will clobber %rdx, whether you use that value
or not.  You need a corresponding constraint:

  asm volatile("rdtsc" : "=a"(lo) : : "rdx");

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: armv7: tweak timercounter mask

2020-07-12 Thread Christian Weisgerber
Mark Kettenis:

> > There is the strong suspicion that the 0x7fff mask in the various
> > armv7 timecounters was simply copied from powerpc, and that these really
> > are full 32-bit counters.
> > 
> > I wanted to verify this from the data sheets, but I'm insufficiently
> > familiar with the ARM ecosystem to locate those.
> 
> The counter is described in the ARM Architecture Reference Manual.  It
> was introduced later so you need to look at revision C or later.

Found it.  That's agtimer.

amptimer is the global timer in the ARM Cortex-A9 MPCore Technical
Reference Manual.  It's a 64-bit counter.

For gptimer, I've found the OMAP4460 Technical Reference Manual.
It's a 32-bit counter.

So they should be all fine with 0x.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc(64): tweak timecounter mask

2020-07-12 Thread Christian Weisgerber
Mark Kettenis:

> > Date: Sun, 12 Jul 2020 18:12:39 +0200
> > From: Christian Weisgerber 
> > 
> > The PowerPC/Power ISA Time Base is a 64-bit register.  We can use
> > the full lower 32 bits.
> > 
> > OK?
> 
> Sure, but this needs to be coordinated with the userland diff.

No.  tc_update_timekeep() copies the counter mask into the timekeep
structure and the userland picks it up from there.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



armv7: tweak timercounter mask

2020-07-12 Thread Christian Weisgerber
There is the strong suspicion that the 0x7fff mask in the various
armv7 timecounters was simply copied from powerpc, and that these really
are full 32-bit counters.

I wanted to verify this from the data sheets, but I'm insufficiently
familiar with the ARM ecosystem to locate those.

Back in September 2017, Artturi Alm proposed the very same change
here but failed to make himself heard.


Index: arch/arm/cortex/agtimer.c
===
RCS file: /cvs/src/sys/arch/arm/cortex/agtimer.c,v
retrieving revision 1.9
diff -u -p -r1.9 agtimer.c
--- arch/arm/cortex/agtimer.c   11 Aug 2018 10:42:42 -  1.9
+++ arch/arm/cortex/agtimer.c   12 Jul 2020 16:13:22 -
@@ -46,7 +46,7 @@ int32_t agtimer_frequency = TIMER_FREQUE
 u_int agtimer_get_timecount(struct timecounter *);
 
 static struct timecounter agtimer_timecounter = {
-   agtimer_get_timecount, NULL, 0x7fff, 0, "agtimer", 0, NULL
+   agtimer_get_timecount, NULL, 0x, 0, "agtimer", 0, NULL
 };
 
 struct agtimer_pcpu_softc {
Index: arch/arm/cortex/amptimer.c
===
RCS file: /cvs/src/sys/arch/arm/cortex/amptimer.c,v
retrieving revision 1.7
diff -u -p -r1.7 amptimer.c
--- arch/arm/cortex/amptimer.c  6 Jul 2020 13:33:06 -   1.7
+++ arch/arm/cortex/amptimer.c  12 Jul 2020 16:13:37 -
@@ -67,7 +67,7 @@ int32_t amptimer_frequency = TIMER_FREQU
 u_int amptimer_get_timecount(struct timecounter *);
 
 static struct timecounter amptimer_timecounter = {
-   amptimer_get_timecount, NULL, 0x7fff, 0, "amptimer", 0, NULL, 0
+   amptimer_get_timecount, NULL, 0x, 0, "amptimer", 0, NULL, 0
 };
 
 #define MAX_ARM_CPUS   8
Index: arch/armv7/omap/gptimer.c
===
RCS file: /cvs/src/sys/arch/armv7/omap/gptimer.c,v
retrieving revision 1.8
diff -u -p -r1.8 gptimer.c
--- arch/armv7/omap/gptimer.c   6 Jul 2020 13:33:07 -   1.8
+++ arch/armv7/omap/gptimer.c   12 Jul 2020 15:53:06 -
@@ -117,7 +117,7 @@ int gptimer_irq = 0;
 u_int gptimer_get_timecount(struct timecounter *);
 
 static struct timecounter gptimer_timecounter = {
-   gptimer_get_timecount, NULL, 0x7fff, 0, "gptimer", 0, NULL, 0
+   gptimer_get_timecount, NULL, 0x, 0, "gptimer", 0, NULL, 0
 };
 
 volatile u_int32_t nexttickevent;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc(64): tweak timecounter mask

2020-07-12 Thread Christian Weisgerber
Christian Weisgerber:

> - tb_get_timecount, NULL, 0x7fff, 0, "tb", 0, NULL, 0
> + tb_get_timecount, NULL, 0x, 0, "tb", 0, NULL, 0

PS: Do we prefer ~0u over 0x?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



powerpc(64): tweak timecounter mask

2020-07-12 Thread Christian Weisgerber
The PowerPC/Power ISA Time Base is a 64-bit register.  We can use
the full lower 32 bits.

OK?

Index: arch/macppc/macppc/clock.c
===
RCS file: /cvs/src/sys/arch/macppc/macppc/clock.c,v
retrieving revision 1.44
diff -u -p -r1.44 clock.c
--- arch/macppc/macppc/clock.c  6 Jul 2020 13:33:08 -   1.44
+++ arch/macppc/macppc/clock.c  12 Jul 2020 15:17:48 -
@@ -57,7 +57,7 @@ u_int32_t ns_per_tick = 320;
 static int32_t ticks_per_intr;
 
 static struct timecounter tb_timecounter = {
-   tb_get_timecount, NULL, 0x7fff, 0, "tb", 0, NULL, 0
+   tb_get_timecount, NULL, 0x, 0, "tb", 0, NULL, 0
 };
 
 /* calibrate the timecounter frequency for the listed models */
Index: arch/powerpc64/powerpc64/clock.c
===
RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/clock.c,v
retrieving revision 1.1
diff -u -p -r1.1 clock.c
--- arch/powerpc64/powerpc64/clock.c10 Jun 2020 19:06:53 -  1.1
+++ arch/powerpc64/powerpc64/clock.c12 Jul 2020 15:18:02 -
@@ -37,7 +37,7 @@ struct evcount stat_count;
 u_int  tb_get_timecount(struct timecounter *);
 
 static struct timecounter tb_timecounter = {
-   tb_get_timecount, NULL, 0x7fff, 0, "tb", 0, NULL
+   tb_get_timecount, NULL, 0x, 0, "tb", 0, NULL
 };
 
 void   cpu_startclock(void);
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: arm64 usertc

2020-07-11 Thread Christian Weisgerber
Mark Kettenis:

> Nevertheless, here is a different take on the problem. Since the
> timecounter only uses the low 32 bits we don't need the double read.
> This version also changes the timecounter mask from 0x7fff to
> 0x.  That must be ok, since the counter has 64 bits and we are
> already using 0x as a mask on amd64 and sparc64.
> 
> ok?

Yes, but don't forget the part in sys/arch/arm64/include/timetc.h.

Also, if I may ask, ...

> Index: sys/arch/arm64/dev/agtimer.c
> ===
> RCS file: /cvs/src/sys/arch/arm64/dev/agtimer.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 agtimer.c
> --- sys/arch/arm64/dev/agtimer.c  11 Jul 2020 15:22:44 -  1.14
> +++ sys/arch/arm64/dev/agtimer.c  11 Jul 2020 18:35:12 -
> @@ -43,7 +43,8 @@ int32_t agtimer_frequency = TIMER_FREQUE
>  u_int agtimer_get_timecount(struct timecounter *);
>  
>  static struct timecounter agtimer_timecounter = {
> - agtimer_get_timecount, NULL, 0x7fff, 0, "agtimer", 0, NULL, 0
> + agtimer_get_timecount, NULL, 0x, 0, "agtimer", 0, NULL,
> + TC_AGTIMER
>  };
>  
>  struct agtimer_pcpu_softc {
> @@ -191,7 +192,15 @@ agtimer_attach(struct device *parent, st
>  u_int
>  agtimer_get_timecount(struct timecounter *tc)
>  {
> - return agtimer_readcnt64();
> + uint64_t val;
> +
> + /*
> +  * No need to work around Cortex-A73 errata 858921 since we
> +  * only look at the low 32 bits here.
> +  */
> + __asm volatile("isb" ::: "memory");
> + __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val));
> + return (val & 0x);

Is there any point, stylistically I mean, to explicitly masking
this over the truncation implicit in the types?  I'm pretty sure
we do, say, "intvar = int64var" all the time.

>  }
>  
>  int
> Index: lib/libc/arch/aarch64/gen/usertc.c
> ===
> RCS file: /cvs/src/lib/libc/arch/aarch64/gen/usertc.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 usertc.c
> --- lib/libc/arch/aarch64/gen/usertc.c6 Jul 2020 13:33:05 -   
> 1.1
> +++ lib/libc/arch/aarch64/gen/usertc.c11 Jul 2020 18:35:12 -
> @@ -1,6 +1,6 @@
> -/*   $OpenBSD: usertc.c,v 1.1 2020/07/06 13:33:05 pirofti Exp $  */
> +/*   $OpenBSD$   */
>  /*
> - * Copyright (c) 2020 Paul Irofti 
> + * Copyright (c) 2020 Mark Kettenis 
>   *
>   * Permission to use, copy, modify, and distribute this software for any
>   * purpose with or without fee is hereby granted, provided that the above
> @@ -18,4 +18,30 @@
>  #include 
>  #include 
>  
> -int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
> +static inline u_int
> +agtimer_get_timecount(struct timecounter *tc)
> +{
> + uint64_t val;
> +
> + /*
> +  * No need to work around Cortex-A73 errata 858921 since we
> +  * only look at the low 32 bits here.
> +  */
> + __asm volatile("isb" ::: "memory");
> + __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val));
> + return (val & 0x);
> +}
> +
> +static int
> +tc_get_timecount(struct timekeep *tk, u_int *tc)
> +{
> + switch (tk->tk_user) {
> + case TC_AGTIMER:
> + *tc = agtimer_get_timecount(NULL);
> + return 0;
> + }
> +
> + return -1;
> +}
> +
> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = 
> tc_get_timecount;
> 

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-07-08 Thread Christian Weisgerber
On 2020-06-26, George Koehler  wrote:

> Here's macppc again.  My macppc isn't using your newest diff but does
> now need to define TC_TB in .

Crucial question: How confident are we that TB is in sync on
multiprocessor machines?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: user tc for alpha

2020-07-08 Thread Christian Weisgerber
Paul Irofti:

> > Userland gettime support for alpha.
> > Alas, completely untested since I don't have access to that arch.
> 
> Never had an alpha. Reads OK to me (if you make the function static like
> kettenis@ said).

For the archives, here's a version that looks like kettenis@'s
style.

Unfortunately, as Theo has discovered, on multi-socket machines the
PCCs are not in sync.  Fixing this will require kernel work...
so consider this diff withdrawn.


Index: lib/libc/arch/alpha/gen/usertc.c
===
RCS file: /cvs/src/lib/libc/arch/alpha/gen/usertc.c,v
retrieving revision 1.1
diff -u -p -r1.1 usertc.c
--- lib/libc/arch/alpha/gen/usertc.c6 Jul 2020 13:33:05 -   1.1
+++ lib/libc/arch/alpha/gen/usertc.c8 Jul 2020 11:39:37 -
@@ -18,4 +18,25 @@
 #include 
 #include 
 
-int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
+static inline u_int
+rpcc_get_timecount(void)
+{
+   unsigned long val;
+
+   __asm volatile("rpcc %0" : "=r" (val));
+   return val;
+}
+
+static int
+tc_get_timecount(struct timekeep *tk, u_int *tc)
+{
+   switch (tk->tk_user) {
+   case TC_RPCC:
+   *tc = rpcc_get_timecount();
+   return 0;
+   }
+
+   return -1;
+}
+
+int (*const _tc_get_timecount)(struct timekeep *, u_int *) = tc_get_timecount;
Index: sys/arch/alpha/alpha/clock.c
===
RCS file: /cvs/src/sys/arch/alpha/alpha/clock.c,v
retrieving revision 1.24
diff -u -p -r1.24 clock.c
--- sys/arch/alpha/alpha/clock.c6 Jul 2020 13:33:06 -   1.24
+++ sys/arch/alpha/alpha/clock.c7 Jul 2020 20:29:47 -
@@ -64,7 +64,7 @@ int clk_irq = 0;
 
 u_int rpcc_get_timecount(struct timecounter *);
 struct timecounter rpcc_timecounter = {
-   rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL, 0
+   rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL, TC_RPCC
 };
 
 extern todr_chip_handle_t todr_handle;
Index: sys/arch/alpha/include/timetc.h
===
RCS file: /cvs/src/sys/arch/alpha/include/timetc.h,v
retrieving revision 1.1
diff -u -p -r1.1 timetc.h
--- sys/arch/alpha/include/timetc.h 6 Jul 2020 13:33:06 -   1.1
+++ sys/arch/alpha/include/timetc.h 8 Jul 2020 11:30:17 -
@@ -18,6 +18,6 @@
 #ifndef _MACHINE_TIMETC_H_
 #define _MACHINE_TIMETC_H_
 
-#defineTC_LAST 0
+#define TC_RPCC1
 
 #endif /* _MACHINE_TIMETC_H_ */
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: user tc for alpha

2020-07-07 Thread Christian Weisgerber
Mark Kettenis:

> > --- lib/libc/arch/alpha/gen/usertc.c6 Jul 2020 13:33:05 -   
> > 1.1
> > +++ lib/libc/arch/alpha/gen/usertc.c7 Jul 2020 20:40:37 -

> > +int
> > +tc_get_timecount(struct timekeep *tk, u_int *tc)
> 
> Need to make this function static to avoid namespace pollution.

Then this needs to be fixed in amd64/gen/usertc.c pronto, before
everybody copies it from there.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



user tc for alpha

2020-07-07 Thread Christian Weisgerber
Userland gettime support for alpha.

Alas, completely untested since I don't have access to that arch.

Index: lib/libc/arch/alpha/gen/usertc.c
===
RCS file: /cvs/src/lib/libc/arch/alpha/gen/usertc.c,v
retrieving revision 1.1
diff -u -p -r1.1 usertc.c
--- lib/libc/arch/alpha/gen/usertc.c6 Jul 2020 13:33:05 -   1.1
+++ lib/libc/arch/alpha/gen/usertc.c7 Jul 2020 20:40:37 -
@@ -18,4 +18,18 @@
 #include 
 #include 
 
-int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
+int
+tc_get_timecount(struct timekeep *tk, u_int *tc)
+{
+   unsigned long val;
+
+   if (tk->tk_user != TC_RPCC)
+   return -1;
+
+   __asm volatile("rpcc %0" : "=r" (val));
+   *tc = val;
+   return 0;
+}
+
+int (*const _tc_get_timecount)(struct timekeep *, u_int *)
+   = tc_get_timecount;
Index: sys/arch/alpha/alpha/clock.c
===
RCS file: /cvs/src/sys/arch/alpha/alpha/clock.c,v
retrieving revision 1.24
diff -u -p -r1.24 clock.c
--- sys/arch/alpha/alpha/clock.c6 Jul 2020 13:33:06 -   1.24
+++ sys/arch/alpha/alpha/clock.c7 Jul 2020 20:29:47 -
@@ -64,7 +64,7 @@ int clk_irq = 0;
 
 u_int rpcc_get_timecount(struct timecounter *);
 struct timecounter rpcc_timecounter = {
-   rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL, 0
+   rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL, TC_RPCC
 };
 
 extern todr_chip_handle_t todr_handle;
Index: sys/arch/alpha/include/timetc.h
===
RCS file: /cvs/src/sys/arch/alpha/include/timetc.h,v
retrieving revision 1.1
diff -u -p -r1.1 timetc.h
--- sys/arch/alpha/include/timetc.h 6 Jul 2020 13:33:06 -   1.1
+++ sys/arch/alpha/include/timetc.h 7 Jul 2020 20:42:53 -
@@ -18,6 +18,7 @@
 #ifndef _MACHINE_TIMETC_H_
 #define _MACHINE_TIMETC_H_
 
-#defineTC_LAST 0
+#defineTC_RPCC 1
+#defineTC_LAST 2
 
 #endif /* _MACHINE_TIMETC_H_ */
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-07-03 Thread Christian Weisgerber
On 2020-07-03, Scott Cheloha  wrote:

> Are we doing powerpc, arm64, and sparc64 separately?

hppa can de done as well, but somebody with access to a machine
needs to investigate/ensure that the S bit in the processor status
register is appropriately set to allow userland access to the
Interval Timer register.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-07-03 Thread Christian Weisgerber
On 2020-07-03, Mark Kettenis  wrote:

> Are the issue that naddy@ saw solved?

Yes, they were understood and fixed.

I'll defer to you and Scott regarding the TSC synchronization issues;
aside from that I'm okaying the diff.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc64: 64-bit-ize memmove.S

2020-06-26 Thread Christian Weisgerber
Christian Weisgerber:

> Well, I suggested it, so here's my attempt to switch powerpc64's
> libc memmove.S over to 64 bits:

Actually, on second thought:

That function simply copies as many (double)words plus a tail of
bytes as the length argument specifies.  Neither source nor destination
are checked for alignment, so this will happily run a loop of
unaligned accesses, which doesn't sound very optimal.

I'm also intrigued by this aside in the PowerPC ISA documentation:
| Moreover, Load with Update instructions may take longer to execute
| in some implementations than the corresponding pair of a non-update
| Load instruction and an Add instruction.
What does clang generate?

I think we should consider dropping this "optimized" memmove.S on
both powerpc and powerpc64.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



powerpc64: 64-bit-ize memmove.S

2020-06-26 Thread Christian Weisgerber
Well, I suggested it, so here's my attempt to switch powerpc64's
libc memmove.S over to 64 bits:
* Treat length parameter as 64 bits (size_t) instead of 32 (u_int).
* Set up the main loop to copy 64-bit doublewords instead of 32-bit
  words.

This definitely needs double and triple checking.

Things I wonder about, but didn't touch:
* Why is the memcpy entry point commented out?
* END... STRONG? WEAK? BUILTIN?

Index: memmove.S
===
RCS file: /cvs/src/lib/libc/arch/powerpc64/string/memmove.S,v
retrieving revision 1.1
diff -u -p -r1.1 memmove.S
--- memmove.S   25 Jun 2020 02:34:22 -  1.1
+++ memmove.S   26 Jun 2020 22:22:51 -
@@ -39,7 +39,7 @@
  * ==
  */
 
-#include "SYS.h"
+#include "DEFS.h"
 
 .text
 
@@ -64,45 +64,45 @@ ENTRY(memmove)
/* start of dest*/
 
 fwd:
-   addi%r4, %r4, -4/* Back up src and dst pointers */
-   addi%r8, %r8, -4/* due to auto-update of 'load' */
+   addi%r4, %r4, -8/* Back up src and dst pointers */
+   addi%r8, %r8, -8/* due to auto-update of 'load' */
 
-   srwi.   %r9,%r5,2   /* How many words in total cnt  */
-   beq-last1   /* Handle byte by byte if < 4   */
+   srdi.   %r9,%r5,3   /* Doublewords in total count   */
+   beq-last1   /* Handle byte by byte if < 8   */
/* bytes total  */
-   mtctr   %r9 /* Count of words for loop  */
-   lwzu%r7, 4(%r4) /* Preload first word   */
+   mtctr   %r9 /* Count of dwords for loop */
+   ldu %r7, 8(%r4) /* Preload first doubleword */
 
b   g1
 
 g0:/* Main loop*/
 
-   lwzu%r7, 4(%r4) /* Load a new word  */
-   stwu%r6, 4(%r8) /* Store previous word  */
+   ldu %r7, 8(%r4) /* Load a new doubleword*/
+   stdu%r6, 8(%r8) /* Store previous doubleword*/
 
 g1:
 
bdz-last/* Dec cnt, and branch if just  */
-   /* one word to store*/
-   lwzu%r6, 4(%r4) /* Load another word*/
-   stwu%r7, 4(%r8) /* Store previous word  */
+   /* one doubleword to store  */
+   ldu %r6, 8(%r4) /* Load another doubleword  */
+   stdu%r7, 8(%r8) /* Store previous doubleword*/
bdnz+   g0  /* Dec cnt, and loop again if   */
-   /* more words   */
-   mr  %r7, %r6/* If word count -> 0, then...  */
+   /* more doublewords */
+   mr  %r7, %r6/* If dword count -> 0, then... */
 
 last:
 
-   stwu%r7, 4(%r8) /* ... store last word  */
+   stdu%r7, 8(%r8) /* ... store last doubleword*/
 
 last1: /* Byte-by-byte copy*/
 
-   clrlwi. %r5,%r5,30  /* If count -> 0, then ...  */
+   clrldi. %r5,%r5,61  /* If count -> 0, then ...  */
beqlr   /* we're done   */
 
mtctr   %r5 /* else load count for loop */
 
-   lbzu%r6, 4(%r4) /* 1st byte: update addr by 4   */
-   stbu%r6, 4(%r8) /* since we pre-adjusted by 4   */
+   lbzu%r6, 8(%r4) /* 1st byte: update addr by 8   */
+   stbu%r6, 8(%r8) /* since we pre-adjusted by 8   */
bdzlr-  /* in anticipation of main loop */
 
 last2:
@@ -120,40 +120,40 @@ reverse:
 
add %r4, %r4, %r5   /* Work from end to beginning   */
add %r8, %r8, %r5   /* so add count to string ptrs  */
-   srwi.   %r9,%r5,2   /* Words in total count */
-   beq-rlast1  /* Handle byte by byte if < 4   */
+   srdi.   %r9,%r5,3   /* Doublewords in total count   */
+   beq-rlast1  /* Handle byte by byte if < 8   */
/* bytes total  */
 
-   mtctr   %r9 /* Count of words for loop  */
+   mtctr   %r9 /* Count of dwords for loop */
 
-   lwzu%r7, -4(%r4)/* Preload first word   */
+   

Re: ffs(3): libc arch versions, regress

2020-06-25 Thread Christian Weisgerber
Trying again, this time with powerpc64 added:

This adds the optimized ffs(3) versions on aarch64, powerpc, and
powerpc64 to libc.  Also add a brief regression test.

Index: lib/libc/arch/aarch64/string/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/aarch64/string/Makefile.inc,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.inc
--- lib/libc/arch/aarch64/string/Makefile.inc   11 Jan 2017 18:09:24 -  
1.1
+++ lib/libc/arch/aarch64/string/Makefile.inc   11 Jun 2020 20:30:34 -
@@ -2,7 +2,7 @@
 
 SRCS+= bcopy.c memcpy.c memmove.c \
strchr.c strrchr.c \
-   bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c \
+   bcmp.c bzero.c ffs.S memchr.c memcmp.c memset.c \
strcmp.c strncmp.c \
strcat.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \
strncat.c  strncpy.c strpbrk.c strsep.c \
Index: lib/libc/arch/aarch64/string/ffs.S
===
RCS file: lib/libc/arch/aarch64/string/ffs.S
diff -N lib/libc/arch/aarch64/string/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/aarch64/string/ffs.S  11 Jun 2020 20:31:19 -
@@ -0,0 +1,18 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include "DEFS.h"
+
+ENTRY(ffs)
+   RETGUARD_SETUP(ffs, x15)
+   rbitw1, w0
+   clz w1, w1
+   cmp w0, wzr
+   csinc   w0, wzr, w1, eq
+   RETGUARD_CHECK(ffs, x15)
+   ret
+END(ffs)
+.protected
Index: lib/libc/arch/powerpc/string/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/powerpc/string/Makefile.inc,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile.inc
--- lib/libc/arch/powerpc/string/Makefile.inc   15 May 2015 22:29:37 -  
1.6
+++ lib/libc/arch/powerpc/string/Makefile.inc   11 Jun 2020 20:33:04 -
@@ -2,7 +2,7 @@
 
 SRCS+= memcpy.c memmove.S \
strchr.c strrchr.c \
-   bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c strcat.c \
+   bcmp.c bzero.c ffs.S memchr.c memcmp.c memset.c strcat.c \
strcmp.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \
strncat.c strncmp.c strncpy.c strpbrk.c strsep.c \
strspn.c strstr.c swab.c
Index: lib/libc/arch/powerpc/string/ffs.S
===
RCS file: lib/libc/arch/powerpc/string/ffs.S
diff -N lib/libc/arch/powerpc/string/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/powerpc/string/ffs.S  11 Jun 2020 20:33:19 -
@@ -0,0 +1,16 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include "SYS.h"
+
+ENTRY(ffs)
+   neg %r4, %r3
+   and %r3, %r3, %r4
+   cntlzw  %r3, %r3
+   subfic  %r3, %r3, 32
+   blr
+END(ffs)
+.protected
Index: lib/libc/arch/powerpc64/string/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/powerpc64/string/Makefile.inc,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.inc
--- lib/libc/arch/powerpc64/string/Makefile.inc 25 Jun 2020 02:34:22 -  
1.1
+++ lib/libc/arch/powerpc64/string/Makefile.inc 25 Jun 2020 20:53:42 -
@@ -2,7 +2,7 @@
 
 SRCS+= memcpy.c memmove.S \
strchr.c strrchr.c \
-   bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c strcat.c \
+   bcmp.c bzero.c ffs.S memchr.c memcmp.c memset.c strcat.c \
strcmp.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \
strncat.c strncmp.c strncpy.c strpbrk.c strsep.c \
strspn.c strstr.c swab.c
Index: lib/libc/arch/powerpc64/string/ffs.S
===
RCS file: lib/libc/arch/powerpc64/string/ffs.S
diff -N lib/libc/arch/powerpc64/string/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/powerpc64/string/ffs.S25 Jun 2020 20:57:16 -
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include "DEFS.h"
+
+ENTRY(ffs)
+   neg %r4, %r3
+   and %r3, %r3, %r4
+   cntlzw  %r3, %r3
+   subfic  %r3, %r3, 32
+   blr
+END_BUILTIN(ffs)
Index: regress/lib/libc/ffs/Makefile
===
RCS file: regress/lib/libc/ffs/Makefile
diff -N regress/lib/libc/ffs/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/ffs/Makefile   20 Jun 2020 15:26:51 -
@@ -0,0 +1,6 @@
+PROG=  ffs_test
+
+# prevent constant folding and inlining of __builtin_ffs()
+CFLAGS+=   -ffreestanding
+
+.include 
Index: regress/lib/libc/ffs/ffs_test.c
===
RCS file: regress/lib/libc/ffs/ffs_test.c
diff -N regress/lib/libc/ffs/ffs_test.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/

RIP, freedb (cddb service)

2020-06-24 Thread Christian Weisgerber
The freedb.org CD track database is dead.  Its shutdown had already
been announced for March, and it finally disappeared.

gnudb.org, whoever they are, offers the last working alternative
that still supports the CDDB protocol.  Actually, the port was dead
yesterday, but they fixed it today.  I suggest we switch the default
of cdio(1)'s cddb command to gnudb.

I think we can also retire cddb/888 from /etc/services.  Literally
nothing uses this any longer.  gnudb uses the "cddbp-alt" port of
8880, but I don't think we need a services(5) entry for a single
site.  If anything in ports uses getservbyname("cddb", ...), it's
already broken anyway.

OK?

PS:
Clearly the NSA does not consider the unencrypted transmission of
compact disc identifiers a significant source of intelligence, or
they would sponsor a better server...

Index: etc/services
===
RCS file: /cvs/src/etc/services,v
retrieving revision 1.96
diff -u -p -r1.96 services
--- etc/services27 Jan 2019 20:35:06 -  1.96
+++ etc/services24 Jun 2020 22:27:44 -
@@ -182,7 +182,6 @@ kerberos-adm749/udp # 
Kerberos 5 kad
 domain-s   853/tcp # DNS query-response protocol 
run over TLS/DTLS
 domain-s   853/udp # DNS query-response protocol 
run over TLS/DTLS
 rsync  873/tcp # rsync server
-cddb   888/tcp cddbp   # Audio CD Database
 imaps  993/tcp # imap4 protocol over TLS/SSL
 imaps  993/udp # imap4 protocol over TLS/SSL
 pop3s  995/tcp spop3   # pop3 protocol over TLS/SSL
Index: usr.bin/cdio/cddb.c
===
RCS file: /cvs/src/usr.bin/cdio/cddb.c,v
retrieving revision 1.22
diff -u -p -r1.22 cddb.c
--- usr.bin/cdio/cddb.c 7 Dec 2017 02:08:44 -   1.22
+++ usr.bin/cdio/cddb.c 24 Jun 2020 22:25:58 -
@@ -254,7 +254,7 @@ cddb(const char *host_port, int n, struc
int i;
const char *errstr;
 
-   s = parse_connect_to(host_port, "cddb");
+   s = parse_connect_to(host_port, "8880");
if (s == -1)
goto end;
s2 = dup(s);
Index: usr.bin/cdio/cdio.1
===
RCS file: /cvs/src/usr.bin/cdio/cdio.1,v
retrieving revision 1.65
diff -u -p -r1.65 cdio.1
--- usr.bin/cdio/cdio.1 22 Apr 2020 05:37:00 -  1.65
+++ usr.bin/cdio/cdio.1 24 Jun 2020 22:22:34 -
@@ -58,7 +58,7 @@ The options are as follows:
 .Ar host : Ns Ar port
 .Xc
 Specifies a CDDB host
-.Bq default: freedb.freedb.org:cddb .
+.Bq default: gnudb.gnudb.org:8880 .
 .It Fl f Ar device
 Specifies the name of the CD device, such as
 .Pa /dev/rcd0c .
Index: usr.bin/cdio/cdio.c
===
RCS file: /cvs/src/usr.bin/cdio/cdio.c,v
retrieving revision 1.78
diff -u -p -r1.78 cdio.c
--- usr.bin/cdio/cdio.c 3 Jul 2019 03:24:02 -   1.78
+++ usr.bin/cdio/cdio.c 24 Jun 2020 22:25:19 -
@@ -239,7 +239,7 @@ main(int argc, char **argv)
 
cddb_host = getenv("CDDB");
if (!cddb_host)
-   cddb_host = "freedb.freedb.org";
+   cddb_host = "gnudb.gnudb.org";
 
while ((ch = getopt(argc, argv, "svd:f:")) != -1)
switch (ch) {
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-22 Thread Christian Weisgerber
Christian Weisgerber:

> If I move
> 
> vaddr_t ps_timekeep;/* User pointer to timekeep */
> 
> up into the zeroed area, I get a properly randomized _timekeep in
> userland.

Also note that exec_sigcode_map() has this

pr->ps_sigcode = 0; /* no hint */
uao_reference(e->e_sigobject);
if (uvm_map(>ps_vmspace->vm_map, >ps_sigcode, round_page(sz),

I don't know if we want to
* explicitly set ps_timekeep to 0 in exec_timekeep_map(), or
* move it into the zeroed area, which we should also do with ps_sigcode
  then.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-22 Thread Christian Weisgerber
Paul Irofti:

> 683 /* map the process's timekeep page */
> 684 if (exec_timekeep_map(pr))
> 685 goto free_pack_abort;
> 686 /* setup new registers and do misc. setup. */
> 687 if (pack.ep_emul->e_fixup != NULL) {
> 688 if ((*pack.ep_emul->e_fixup)(p, ) != 0)
> 689 goto free_pack_abort;
> 690 }

Yes, with this init(8) gets a proper _timekeep instead of 0x0.

For randomization of the userland page...

+   if (uvm_map(>ps_vmspace->vm_map, >ps_timekeep, 
round_page(timekeep_sz),

... ps_timekeep need to be 0 here.  At the moment, it inherits the
value from the parent process in fork().

In struct process in sys/proc.h, there is this:

/* The following fields are all zeroed upon creation in process_new. */
...
/* End area that is zeroed on creation. */

If I move

vaddr_t ps_timekeep;/* User pointer to timekeep */

up into the zeroed area, I get a properly randomized _timekeep in
userland.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-21 Thread Christian Weisgerber
Christian Weisgerber:

> I tweaked the patch locally to make _timekeep a visible global
> symbol in libc.
> 
> Printing its value has revealed two issues:
> 
> * The timekeep page is mapped to the same address for every process.
>   It changes across reboots, but once running, it's always the same.
>   kettenis suggested
>   - vaddr_t va;
>   + vaddr_t va = 0;
>   in exec_timekeep_map(), but that doesn't make a difference.

But that's the kernel mapping, and my observation concerns the
userland mapping.  So based on this, I moved ps_timekeep up into
the fields of struct process that are zeroed on creation.
With that, _timekeep is always 0 for all processes. :-/

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-21 Thread Christian Weisgerber
Paul Irofti:

[Unrelated, just to mark where we're at]
> Right. Just reproduced it here. This moves the check at the top so that
> each CPU checks its own skew and disables tc_user if necessary.

I tweaked the patch locally to make _timekeep a visible global
symbol in libc.

Printing its value has revealed two issues:

* The timekeep page is mapped to the same address for every process.
  It changes across reboots, but once running, it's always the same.
  kettenis suggested
  - vaddr_t va;
  + vaddr_t va = 0;
  in exec_timekeep_map(), but that doesn't make a difference.

* I'm indeed seeing init(8) with _timekeep == NULL.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-21 Thread Christian Weisgerber
Paul Irofti:

> >   b) Revert _timekeep init (breaks naddy@'s machine)
> 
> Robert helped properly track down this issue to a silly null-ref.

If that was indeed the problem...

> --- lib/libc/dlfcn/init.c
> +++ lib/libc/dlfcn/init.c
> @@ -105,6 +107,14 @@ _libc_preinit(int argc, char **argv, char **envp, 
> dl_cb_cb *cb)
>   phnum = aux->au_v;
>   break;
>  #endif /* !PIC */
> + case AUX_openbsd_timekeep:
> + if (_tc_get_timecount) {
> + _timekeep = (void *)aux->au_v;
> + if (_timekeep &&
> + _timekeep->tk_version != TK_VERSION)
> + _timekeep = NULL;
> + }
> + break;
>   }
>   }
>  

... how could aux->au_v be NULL here?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Retire

2020-06-21 Thread Christian Weisgerber
On 2020-06-20, Christian Weisgerber  wrote:

>> Well... they something in ports might still look at them in 
>> 
>>
>> Can someone from ports speak about this?
>
> I have started an amd64 bulk build without .

There were no build failures attributable to this.
The header can be removed.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-21 Thread Christian Weisgerber
Paul Irofti:

> Can't test right now, but if you enable the TSC_DEBUG in cpu.c or if you
> put a printf in the CPU_INFO_FOREACH you will probably see the correct
> skew values.

It's worse: CPU_INFO_FOREACH() only sees cpu0.  The others aren't
attached yet.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-21 Thread Christian Weisgerber
Paul Irofti:

> This also handles negative skew values that my prevoius diff did not.

> --- sys/arch/amd64/amd64/tsc.c
> +++ sys/arch/amd64/amd64/tsc.c
> @@ -216,6 +217,8 @@ tsc_get_timecount(struct timecounter *tc)
>  void
>  tsc_timecounter_init(struct cpu_info *ci, uint64_t cpufreq)
>  {
> + CPU_INFO_ITERATOR cii;
> +
>  #ifdef TSC_DEBUG
>   printf("%s: TSC skew=%lld observed drift=%lld\n", __func__,
>   (long long)ci->ci_tsc_skew, (long long)tsc_drift_observed);
> @@ -244,8 +247,16 @@ tsc_timecounter_init(struct cpu_info *ci, uint64_t 
> cpufreq)
>   printf("ERROR: %lld cycle TSC drift observed\n",
>   (long long)tsc_drift_observed);
>   tsc_timecounter.tc_quality = -1000;
> + tsc_timecounter.tc_user = 0;
>   tsc_is_invariant = 0;
>   }
> + CPU_INFO_FOREACH(cii, ci) {
> + if (ci->ci_tsc_skew < -TSC_SKEW_MAX ||
> + ci->ci_tsc_skew > TSC_SKEW_MAX) {
> + tsc_timecounter.tc_user = 0;
> + break;
> + }
> + }
>  
>   tc_init(_timecounter);
>  }

If the output order from TSC_DEBUG in dmesg reflects the actual
execution order, then the relative call order is this:

cpu0 tsc_timecounter_init
cpu1 cpu_start_secondary
cpu1 tsc_timecounter_init
cpu2 cpu_start_secondary
cpu2 tsc_timecounter_init
cpu3 cpu_start_secondary
cpu3 tsc_timecounter_init

That CPU_INFO_FOREACH() loop would execute in the very first cpu0
tsc_timecounter_init() call, _before_ the skews of the other CPUs
are determined in the subsequent cpu_start_secondary() calls.

So, instead, I think the skew check needs to move to the top of
tsc_timecounter_init, where each secondary CPU checks its own skew
value and knocks out tsc_timecounter.tc_user if there is a problem.

Unless I'm misunderstanding the whole thing.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-20 Thread Christian Weisgerber
On 2020-06-20, Christian Weisgerber  wrote:

> I can't get this revision of the diff to work on amd64:
> * patch source
> * build and install kernel, reboot
> * make build
> * reboot -> "Process (pid 1) got signal 11"
>
> I'm at a loss.  As part of the "make build", the new libc is installed
> and dynamically linked programs should already be using the userland
> gettime calls.  Clearly this works.  So why does init fail on the
> next reboot?

I can recover by extracting ./sbin/init from a snapshot in the
installer.  After that, the system comes up fine in multiuser mode.
Nothing else appears to be affected, apart from init.

For a while, I had a reproducible situation.

When you call init(8) as a normal user in multiuser mode, it will
just exit with "init: Operation not permitted".  Instead it would
segfault!  I kept tweaking lib/libc/dlfcn/init.c, rebuilding and
reinstalling libc.a, rebuilding init, and watching it segfault.
None of the debug write(2)s I inserted would produce any output,
it seemed to die before ever reaching _libc_preinit().  I finally
ktraced it:

 12420 ktrace   RET   ktrace 0
 12420 ktrace   CALL  execve(0x7f7ec412,0x7f7ec298,0x7f7ec2a8)
 12420 ktrace   NAMI  "./obj/init"
 12420 ktrace   ARGS  
[0] = "./obj/init"
 12420 init RET   execve 0
 12420 init PSIG  SIGSEGV SIG_DFL code SEGV_MAPERR<1> addr=0x0 trapno=6
 12420 init NAMI  "init.core"

There's not even a kbind(2) there.

Then I removed the clearly useless debug write()s... and since then
I have a hard time reproducing the problem.

It doesn't make any sense.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-20 Thread Christian Weisgerber
On 2020-06-19, Paul Irofti  wrote:

> I have addressed your comments bellow, except for the CPU skew one. That
> code disables TSC for all CPUs, not just for PRIMARY. Would you like to
> walk and add code for every CPU to check the drift and then disable the
> TSC? It seems a little too much...
>
> [diff]

I can't get this revision of the diff to work on amd64:
* patch source
* build and install kernel, reboot
* make build
* reboot -> "Process (pid 1) got signal 11"

I'm at a loss.  As part of the "make build", the new libc is installed
and dynamically linked programs should already be using the userland
gettime calls.  Clearly this works.  So why does init fail on the
next reboot?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Retire

2020-06-20 Thread Christian Weisgerber
On 2020-06-19, "Theo de Raadt"  wrote:

> Well... they something in ports might still look at them in 
>
> Can someone from ports speak about this?

I have started an amd64 bulk build without .

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-19 Thread Christian Weisgerber
On 2020-06-19, Mark Kettenis  wrote:

> I'm talking about *skew*, not drift.  If there is a significant drift
> you already knock out the TSC.
>
> What's needed is:
>
> 1. A bit of research of what an acceptable skew is.  My hypothesis is
>that on many machines with a single socket the TSCs are actually in
>synch.  But the way we measure the skew isn't 100% accurate so we
>still get a small skew.  If we sample these values on a couple of
>machines across a couple of reboots we can probably tell what the
>uncertainty in the measurement of the skew is and define a cutoff
>based on that.

So we need amd64 snapshots to enable TSC_DEBUG, maybe a bit prettier
like below, and then reports:

cpu0: Intel(R) Xeon(R) CPU E3-1225 v3 @ 3.20GHz, 3392.69 MHz, 06-3c-03

cpu0: TSC skew=0 observed drift=0
cpu1: TSC skew=-24 observed drift=0
cpu2: TSC skew=-27 observed drift=0
cpu3: TSC skew=-25 observed drift=0

cpu0: TSC skew=0 observed drift=0
cpu1: TSC skew=-1 observed drift=0
cpu2: TSC skew=0 observed drift=0
cpu3: TSC skew=25 observed drift=0

cpu0: TSC skew=0 observed drift=0
cpu1: TSC skew=-30 observed drift=0
cpu2: TSC skew=-39 observed drift=0
cpu3: TSC skew=-41 observed drift=0

cpu0: TSC skew=0 observed drift=0
cpu1: TSC skew=-31 observed drift=0
cpu2: TSC skew=-37 observed drift=0
cpu3: TSC skew=-39 observed drift=0

cpu0: TSC skew=0 observed drift=0
cpu1: TSC skew=-31 observed drift=0
cpu2: TSC skew=-34 observed drift=0
cpu3: TSC skew=-23 observed drift=0


Index: sys/arch/amd64/amd64/tsc.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/tsc.c,v
retrieving revision 1.16
diff -u -p -r1.16 tsc.c
--- sys/arch/amd64/amd64/tsc.c  6 Apr 2020 00:01:08 -   1.16
+++ sys/arch/amd64/amd64/tsc.c  19 Jun 2020 23:49:06 -
@@ -217,7 +217,7 @@ void
 tsc_timecounter_init(struct cpu_info *ci, uint64_t cpufreq)
 {
 #ifdef TSC_DEBUG
-   printf("%s: TSC skew=%lld observed drift=%lld\n", __func__,
+   printf("%s: TSC skew=%lld observed drift=%lld\n", ci->ci_dev->dv_xname,
(long long)ci->ci_tsc_skew, (long long)tsc_drift_observed);
 #endif
 
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: improve pkg_add bandwidth usage with some mirrors

2020-06-19 Thread Christian Weisgerber
On 2020-06-18, Marc Espie  wrote:

> What pkg_add does internally is a pipeline:
>
> ftp | signify|internal gunzip
>
> closing the end file handle should kill the whole chain.
> So I need to figure out where it goes wrong, what's the
> part that doesn't die "instantly".

That's ftp(1).  Our SSL people are sitting on a patch to libtls^H^H^Hssl.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-14 Thread Christian Weisgerber
George Koehler:

> --- lib/libc/arch/powerpc/gen/usertc.c.before Sat Jun 13 21:28:50 2020
> +++ lib/libc/arch/powerpc/gen/usertc.cSat Jun 13 21:38:52 2020
> @@ -18,4 +18,19 @@
>  #include 
>  #include 
>  
> -int (*const _tc_get_timecount)(struct timekeep *, uint64_t *) = NULL;
> +int
> +tc_get_timecount(struct timekeep *tk, uint64_t *tc)
> +{
> + uint64_t tb;
> + uint32_t scratch;
> +
> + if (tk->tk_user != 1)
> + return -1;
> +
> + __asm volatile ("1: mftbu %0; mftb %L0; mftbu %1;"
> + " cmpw 0,%0,%1; bne 1b" : "=r"(tb), "=r"(scratch));

You only need the lower register.  Compare the kernel timecounter:

u_int
tb_get_timecount(struct timecounter *tc)
{
  return ppc_mftbl();
}

As I mentioned before, the declaration of the timecounter value as
uint64_t is confusing and should be changed.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: symmetric toeplitz hashing

2020-06-13 Thread Christian Weisgerber
On 2020-06-13, Theo Buehler  wrote:

> Others have pointed out off-list that one can use __builtin_popcount(),
> but __builtin_parity() is exactly what I want. Is it available on all
> architectures?

The standard implementation will be perfectly fine, no need to resort
to magic compiler built-ins.

int
popcount(uint16_t x)
{
x = (x & 0x) + ((x & 0x) >> 1);
x = (x & 0x) + ((x & 0x) >> 2);
x = (x & 0x0F0F) + ((x & 0xF0F0) >> 4);
x = (x & 0x00FF) + ((x & 0xFF00) >> 8);
return (x);
}

... which immediately lends itself to:

int
parity(uint16_t x)
{
x = (x & 0x) ^ ((x & 0x) >> 1);
x = (x & 0x) ^ ((x & 0x) >> 2);
x = (x & 0x0F0F) ^ ((x & 0xF0F0) >> 4);
x = (x & 0x00FF) ^ ((x & 0xFF00) >> 8);
return (x);
}

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



cpu_rnd_messybits() for hppa

2020-06-12 Thread Christian Weisgerber
Here's a cpu_rnd_messybits() for hppa.  This just steals from
itmr_get_timecount().  If we want to use the mfctl() macro, we need
to include  into cpu.h.  I don't know if we want
that, so I went with the explicit asm() instead.

Completely untested.


Index: sys/arch/hppa/hppa/machdep.c
===
RCS file: /cvs/src/sys/arch/hppa/hppa/machdep.c,v
retrieving revision 1.259
diff -u -p -r1.259 machdep.c
--- sys/arch/hppa/hppa/machdep.c31 May 2020 06:23:57 -  1.259
+++ sys/arch/hppa/hppa/machdep.c5 Jun 2020 15:17:23 -
@@ -1496,12 +1496,3 @@ blink_led_timeout(void *vsc)
t = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
timeout_add(>bls_to, t);
 }
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: sys/arch/hppa/include/cpu.h
===
RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v
retrieving revision 1.92
diff -u -p -r1.92 cpu.h
--- sys/arch/hppa/include/cpu.h 31 May 2020 06:23:57 -  1.92
+++ sys/arch/hppa/include/cpu.h 5 Jun 2020 15:17:23 -
@@ -54,6 +54,7 @@
 #ifdef _KERNEL
 #include 
 #include 
+#include 
 #endif /* _KERNEL */
 
 /*
@@ -237,7 +238,16 @@ intcopy_on_fault(void);
 void   switch_trampoline(void);
 intcpu_dumpsize(void);
 intcpu_dump(void);
-unsigned int cpu_rnd_messybits(void);
+
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+unsigned int __itmr;
+
+   __asm volatile("mfctl %1,%0": "=r" (__itmr) : "i" (CR_ITMR));
+
+return (__itmr);
+}
 
 #ifdef MULTIPROCESSOR
 void   cpu_boot_secondary_processors(void);

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: ffs(3): libc arch versions, regress

2020-06-12 Thread Christian Weisgerber
Christian Weisgerber:

> This adds the optimized ffs(3) versions on aarch64 and powerpc to
> libc, for completeness' sake.
> 
> Also add a brief regression test.
> 
> OK?

Index: lib/libc/arch/aarch64/string/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/aarch64/string/Makefile.inc,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.inc
--- lib/libc/arch/aarch64/string/Makefile.inc   11 Jan 2017 18:09:24 -  
1.1
+++ lib/libc/arch/aarch64/string/Makefile.inc   11 Jun 2020 20:30:34 -
@@ -2,7 +2,7 @@
 
 SRCS+= bcopy.c memcpy.c memmove.c \
strchr.c strrchr.c \
-   bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c \
+   bcmp.c bzero.c ffs.S memchr.c memcmp.c memset.c \
strcmp.c strncmp.c \
strcat.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \
strncat.c  strncpy.c strpbrk.c strsep.c \
Index: lib/libc/arch/aarch64/string/ffs.S
===
RCS file: lib/libc/arch/aarch64/string/ffs.S
diff -N lib/libc/arch/aarch64/string/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/aarch64/string/ffs.S  11 Jun 2020 20:31:19 -
@@ -0,0 +1,18 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include "DEFS.h"
+
+ENTRY(ffs)
+   RETGUARD_SETUP(ffs, x15)
+   rbitw1, w0
+   clz w1, w1
+   cmp w0, wzr
+   csinc   w0, wzr, w1, eq
+   RETGUARD_CHECK(ffs, x15)
+   ret
+END(ffs)
+.protected
Index: lib/libc/arch/powerpc/string/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/powerpc/string/Makefile.inc,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile.inc
--- lib/libc/arch/powerpc/string/Makefile.inc   15 May 2015 22:29:37 -  
1.6
+++ lib/libc/arch/powerpc/string/Makefile.inc   11 Jun 2020 20:33:04 -
@@ -2,7 +2,7 @@
 
 SRCS+= memcpy.c memmove.S \
strchr.c strrchr.c \
-   bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c strcat.c \
+   bcmp.c bzero.c ffs.S memchr.c memcmp.c memset.c strcat.c \
strcmp.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \
strncat.c strncmp.c strncpy.c strpbrk.c strsep.c \
strspn.c strstr.c swab.c
Index: lib/libc/arch/powerpc/string/ffs.S
===
RCS file: lib/libc/arch/powerpc/string/ffs.S
diff -N lib/libc/arch/powerpc/string/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/powerpc/string/ffs.S  11 Jun 2020 20:33:19 -
@@ -0,0 +1,16 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include "SYS.h"
+
+ENTRY(ffs)
+   neg %r4, %r3
+   and %r3, %r3, %r4
+   cntlzw  %r3, %r3
+   subfic  %r3, %r3, 32
+   blr
+END(ffs)
+.protected
Index: regress/lib/libc/ffs/Makefile
===
RCS file: regress/lib/libc/ffs/Makefile
diff -N regress/lib/libc/ffs/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/ffs/Makefile   12 Jun 2020 08:43:43 -
@@ -0,0 +1,6 @@
+PROG=  ffs_test
+
+# prevent inlining of __builtin_ffs()
+CFLAGS+=   -ffreestanding
+
+.include 
Index: regress/lib/libc/ffs/ffs_test.c
===
RCS file: regress/lib/libc/ffs/ffs_test.c
diff -N regress/lib/libc/ffs/ffs_test.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/ffs/ffs_test.c 12 Jun 2020 08:43:19 -
@@ -0,0 +1,18 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+
+#include 
+#include 
+#include 
+
+int
+main(void)
+{
+   assert(ffs(0) == 0);
+   assert(ffs(0x8080) == 8);
+   assert(ffs(INT32_MIN) == 32);
+   return (0);
+}
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-11 Thread Christian Weisgerber
Theo de Raadt:

> The diff is growing complexity to support a future which wouldn't
> exist if attempts at *supporting all* architectures received priority.

Adding support for more archs is very simple, since you just need
to copy the corresponding get_timecounter function from the kernel.

Here's arm64.  I'm running a kernel and libc with this.

I can also provide alpha, powerpc, and sparc64, but I don't have
such machines.

--- ./lib/libc/arch/aarch64/gen/usertc.c.orig   Thu Jun 11 19:07:39 2020
+++ ./lib/libc/arch/aarch64/gen/usertc.cThu Jun 11 19:08:01 2020
@@ -18,4 +18,32 @@
 #include 
 #include 
 
-int (*const _tc_get_timecount)(struct timekeep *, uint64_t *) = NULL;
+static uint64_t
+readcnt64(void)
+{
+   uint64_t val0, val1;
+
+   /*
+* Work around Cortex-A73 errata 858921, where there is a
+* one-cycle window where the read might return the old value
+* for the low 32 bits and the new value for the high 32 bits
+* upon roll-over of the low 32 bits.
+*/
+   __asm volatile("isb" : : : "memory");
+   __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val0));
+   __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val1));
+   return ((val0 ^ val1) & 0x1ULL) ? val0 : val1;
+}
+
+int
+tc_get_timecount(struct timekeep *tk, uint64_t *tc)
+{
+   if (tc == NULL || tk->tk_user != 1)
+   return -1;
+
+   *tc = readcnt64();
+   return 0;
+}
+
+int (*const _tc_get_timecount)(struct timekeep *, uint64_t *)
+   = tc_get_timecount;
--- ./sys/arch/arm64/arm64/machdep.c.orig   Thu Jun 11 17:46:54 2020
+++ ./sys/arch/arm64/arm64/machdep.cThu Jun 11 17:46:59 2020
@@ -91,7 +91,7 @@
 charmachine[] = MACHINE;/* from  */
 
 /* timekeep number of user accesible clocks */
-int tk_nclocks = 0;
+int tk_nclocks = 1;
 
 int safepri = 0;
 
--- ./sys/arch/arm64/dev/agtimer.c.orig Thu Jun 11 17:47:23 2020
+++ ./sys/arch/arm64/dev/agtimer.c  Thu Jun 11 17:47:27 2020
@@ -43,7 +43,7 @@
 u_int agtimer_get_timecount(struct timecounter *);
 
 static struct timecounter agtimer_timecounter = {
-   agtimer_get_timecount, NULL, 0x7fff, 0, "agtimer", 0, NULL, 0
+   agtimer_get_timecount, NULL, 0x7fff, 0, "agtimer", 0, NULL, 1
 };
 
 struct agtimer_pcpu_softc {
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-11 Thread Christian Weisgerber
Paul Irofti:

> > Paul, that tk_nclocks addition isn't useful.  You need to do the
> > bounds checking against the number of clocks you have implemented in
> > libc.  How many clocks the kernel has implemented doesn't matter.
> 
> What you are saying is that we could be in a situation where the kernel
> might expose 3 clocks but we only have 2 entries in libc? Why would we get
> to that point? When someone changes the clock in the kernel, that means it
> is also changed in libc. I don't think we can decouple the two parts. Right?

But we do:  make kernel; install kernel; reboot; make build.

To cross from nclocks to nclocks+1, you need to run the new nclocks+1
kernel with an nclocks userland.

I keep coming back to the idea that we need an 
header with

#define TC_FOO 1
#define TC_BAR 2
#define TC_NUM 3/* or TC_LAST or whatever */

Mark may have a better idea how to name this.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-11 Thread Christian Weisgerber
Paul Irofti:

[lib/libc/arch/*/gen/usertc.c]
> +int (*const _tc_get_timecount)(struct timekeep *, uint64_t *) = NULL;

[lib/libc/sys/microtime.c]
> +static inline int
> +tc_delta(struct timekeep *tk, u_int *delta)
> +{
> +   uint64_t tc;
> +   if (delta == NULL || _tc_get_timecount(tk, ))

This use of uint64_t for the timecounter return value confused me.

All the kernel code uses u_int as the return value of the timecounter_get
functions.  The userland code should do the same (or uint32_t or
whatever the preferred alias is).

A central idea is that we can just copy the MD timecounter_get
functions from the kernel to the userland code.  They all return
only 32 bits.  (If the hardware register has more bits, like TSC
or TICK, the value is truncated.)

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-11 Thread Christian Weisgerber
Paul Irofti:

> > Additionally, it changes struct timekeep in an incompatible way. ;-)
> > A userland built before the addition of tk_nclocks is very unhappy
> > with a kernel built afterwards.
> 
> I have not seen this problem and have not built a snapshot to update or go
> back. What do you mean by very unhappy?

init(8) can't successfully spawn a shell and you're stuck at a prompt
"Enter pathname of shell or RETURN for sh: "

> Can you show me the exact steps you have done?

Well, I had a system running with an earlier version of the diff,
then I updated the source to the newer diff, built and installed a
kernel, rebooted, and boom!, incompatible kernel and userland.

Why is this controversial?  A member tk_nclocks was inserted in the
middle of struct timekeep, changing the layout of the struct.  The
new kernel uses the new layout, the userland the old layout.  Of
course they're incompatible.

I should have noticed this while reading the new diff...

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-11 Thread Christian Weisgerber
Christian Weisgerber:

> Should we already bump major while the diff matures?

Oh, we can't quite bump yet.  tk_major und tk_minor are only set
in exec_timekeep_map(), but aren't checked anywhere.

+   timekeep->tk_major = 0;
+   timekeep->tk_minor = 0;

Those shouldn't be magic numbers but #defines in sys/timetc.h.

We only need to check those once at process startup.  In
libc/dlfcn/init.c, somewhere here:

+   case AUX_openbsd_timekeep:
+   if (_tc_get_timecount)
+   _timekeep = (void *)aux->au_v;
+   break;

Something like this I think:

case AUX_openbsd_timekeep:
if (_tc_get_timecount) {
struct timekeep *tk = (void *)aux->au_v;
if ((tk != NULL) &&
(tk->tk_major == TK_MAJOR) &&
(tk->tk_minor >= TK_MINOR))
_timekeep = tk;
}
break;

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-10 Thread Christian Weisgerber
Paul Irofti:

> This iteration of the diff adds bounds checking for tk_user and moves
> the usertc.c stub to every arch in libc as recommanded by deraadt@.
> It also fixes a gettimeofday issue reported by cheloha@ and tb@.

Additionally, it changes struct timekeep in an incompatible way. ;-)
A userland built before the addition of tk_nclocks is very unhappy
with a kernel built afterwards.  There is no way to compile across
this.  You have to (U)pgrade from boot media to install a ftp.openbsd.org
userland, and then you can re-compile with the new diff.

Should we already bump major while the diff matures?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-10 Thread Christian Weisgerber
Paul Irofti:

> > This iteration of the diff adds bounds checking for tk_user and moves
> > the usertc.c stub to every arch in libc as recommanded by deraadt@.
> > It also fixes a gettimeofday issue reported by cheloha@ and tb@.
> 
> Forgot to add armv7 tk_nclock entries. Noticed by benno@, thanks!

One blemish I see is that tk_user is a magic number.

For example, sparc64 will have two timecounters: tick and stick.
They will be assigned magic numbers 1 and 2...

struct timecounter tick_timecounter = {
tick_get_timecount, NULL, ~0u, 0, "tick", 0, NULL, 1
};
struct timecounter stick_timecounter = {
stick_get_timecount, NULL, ~0u, 0, "stick", 1000, NULL, 2
};

... and sparc64 usertc.c will need the corresponding magic array order:

static uint64_t (*get_tc[])(void) =
{
rdtick,
rdstick,
};

I don't know if we want to go through the effort to make this
prettier.  We would need an MD header, say, 
that gets picked up by , with something like

#define TC_TICK 1
#define TC_STICK2

The symbolic values could then be used in the kernel timecounter
definitions...

struct timecounter tick_timecounter = {
tick_get_timecount, NULL, ~0u, 0, "tick", 0, NULL, TC_TICK
};
struct timecounter stick_timecounter = {
stick_get_timecount, NULL, ~0u, 0, "stick", 1000, NULL, TC_STICK
};

... and in libc usertc.c:

static uint64_t (*get_tc[])(void) =
{
[TC_TICK] = rdtick,
[TC_STICK] = rdstick,
};
...
*tc = (*get_tc[tk_user])();

The cost would be yet another header file per arch.
Thoughts?

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: libkern: ffs() for arm64, powerpc, powerpc64

2020-06-10 Thread Christian Weisgerber
Next try.
Optimized versions for kernel ffs(3) on arm64, powerpc, powerpc64.

I have tested arm64; cwen@ has tested powerpc in userland.
powerpc64 is copied from powerpc.

ok?


Index: lib/libkern/arch/arm64/ffs.S
===
RCS file: lib/libkern/arch/arm64/ffs.S
diff -N lib/libkern/arch/arm64/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libkern/arch/arm64/ffs.S10 Jun 2020 17:38:50 -
@@ -0,0 +1,17 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include 
+
+ENTRY(ffs)
+   RETGUARD_SETUP(ffs, x15)
+   rbitw1, w0
+   clz w1, w1
+   cmp w0, wzr
+   csinc   w0, wzr, w1, eq
+   RETGUARD_CHECK(ffs, x15)
+   ret
+END(ffs)
Index: lib/libkern/arch/powerpc/ffs.S
===
RCS file: lib/libkern/arch/powerpc/ffs.S
diff -N lib/libkern/arch/powerpc/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libkern/arch/powerpc/ffs.S  10 Jun 2020 17:39:02 -
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include 
+
+ENTRY(ffs)
+   neg %r4, %r3
+   and %r3, %r3, %r4
+   cntlzw  %r3, %r3
+   subfic  %r3, %r3, 32
+   blr
+END(ffs)
Index: lib/libkern/arch/powerpc64/ffs.S
===
RCS file: lib/libkern/arch/powerpc64/ffs.S
diff -N lib/libkern/arch/powerpc64/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libkern/arch/powerpc64/ffs.S10 Jun 2020 17:39:06 -
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+ 
+#include 
+
+ENTRY(ffs)
+   neg %r4, %r3
+   and %r3, %r3, %r4
+   cntlzw  %r3, %r3
+   subfic  %r3, %r3, 32
+   blr
+END(ffs)
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: libkern: ffs() for arm64, powerpc, powerpc64

2020-06-09 Thread Christian Weisgerber
Mark Kettenis:

> Unfortunately that doesn't quite work.  At least in my build it
> doesn't pick up .c files in the linker/arch directories.
> 
> > Index: lib/libkern/arch/arm64/ffs.c

I was certain I had checked this, but indeed it doesn't work.

The Makefile rules are generated from sys/conf/files:

...
file lib/libkern/arch/${MACHINE_ARCH}/ffs.S | lib/libkern/ffs.c
...

We could extend this by a third file.  Ugly.
Alternatively I could go back to .S, sigh.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: libkern: ffs() for arm64, powerpc, powerpc64

2020-06-09 Thread Christian Weisgerber
On 2020-06-09, Christian Weisgerber  wrote:

> Here are optimized ffs(3) implementations for
> * arm64  (superseding the earlier ffs.S)
> * powerpc
> * powerpc64

> +int ffs(int x)

Oops, I'm going to change that to

int
ffs(int x)

before commit.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



ffs(3): libc arch versions, regress

2020-06-09 Thread Christian Weisgerber
This adds the optimized ffs(3) versions on aarch64 and powerpc to
libc, for completeness' sake.

Also add a brief regression test.

OK?

Index: lib/libc/arch/aarch64/string/ffs.c
===
RCS file: lib/libc/arch/aarch64/string/ffs.c
diff -N lib/libc/arch/aarch64/string/ffs.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/aarch64/string/ffs.c  9 Jun 2020 19:54:21 -
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+
+#include 
+
+int
+ffs(int x)
+{
+   x = x & -x;
+   __asm volatile("clz %w0, %w0" : "+r" (x));
+   return (32 - x);
+}
Index: lib/libc/arch/powerpc/string/ffs.c
===
RCS file: lib/libc/arch/powerpc/string/ffs.c
diff -N lib/libc/arch/powerpc/string/ffs.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libc/arch/powerpc/string/ffs.c  9 Jun 2020 19:54:41 -
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+
+#include 
+
+int
+ffs(int x)
+{
+   x = x & -x;
+   __asm volatile("cntlzw %0, %0" : "+r" (x));
+   return (32 - x);
+}
Index: regress/lib/libc/ffs/Makefile
===
RCS file: regress/lib/libc/ffs/Makefile
diff -N regress/lib/libc/ffs/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/ffs/Makefile   9 Jun 2020 19:45:02 -
@@ -0,0 +1,8 @@
+# $OpenBSD$
+
+PROG=  ffs_test
+
+# prevent inlining of __builtin_ffs()
+CFLAGS+=   -ffreestanding
+
+.include 
Index: regress/lib/libc/ffs/ffs_test.c
===
RCS file: regress/lib/libc/ffs/ffs_test.c
diff -N regress/lib/libc/ffs/ffs_test.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/lib/libc/ffs/ffs_test.c 9 Jun 2020 19:40:33 -
@@ -0,0 +1,18 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+
+#include 
+#include 
+#include 
+
+int
+main(void)
+{
+   assert(ffs(0) == 0);
+   assert(ffs(0x8080) == 8);
+   assert(ffs(INT32_MIN) == 32);
+   return (0);
+}
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: libkern: ffs() for arm64

2020-06-08 Thread Christian Weisgerber
On 2020-06-08, Christian Weisgerber  wrote:

> More archs to come...

Style question:
Since this mostly comes down to embedding a single special instruction
in between normal C operations, I wonder whether I should just do .c
with asm() instead of .S, and leave all the boilerplate to the
compiler?  It would save me from reading up on calling conventions,
more assembly syntax, etc.

E.g.:

int ffs(int x)
{
x = x & -x;
__asm volatile("clz %0, %0" : "=r" (x));
return (32 - x);
}

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



libkern: ffs() for arm64

2020-06-08 Thread Christian Weisgerber
Here is an optimized kernel ffs(3) for arm64.

I blame dlg@ for making me scrutinize the POWER7 instruction set,
which led me to the clz instruction, which led me to ffs().  I
wanted to add this to libc, but then realized the futility because
the compiler already inlines its optimized copy of ffs().  However,
this optimization is disabled for the kernel with -ffreestanding.

Honestly, I'm not sure I can claim to have written this.  The elegant
version below is adapted from clang output, because the compiler
is smarter than I am.

More archs to come...

Comments?  OK?

Index: lib/libkern/arch/arm64/ffs.S
===
RCS file: lib/libkern/arch/arm64/ffs.S
diff -N lib/libkern/arch/arm64/ffs.S
--- /dev/null   1 Jan 1970 00:00:00 -
+++ lib/libkern/arch/arm64/ffs.S8 Jun 2020 20:35:01 -
@@ -0,0 +1,17 @@
+/* $OpenBSD$ */
+/*
+ * Written by Christian Weisgerber .
+ * Public domain.
+ */
+
+#include 
+
+ENTRY(ffs)
+   RETGUARD_SETUP(ffs, x15)
+   rbitw1, w0
+   clz w1, w1
+   cmp w0, #0
+   csinc   w0, wzr, w1, eq
+   RETGUARD_CHECK(ffs, x15)
+   ret
+END(ffs)
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc64: ldbrx/stdbrx for endian.h?

2020-06-08 Thread Christian Weisgerber
On 2020-06-08, Christian Weisgerber  wrote:

>> Did they also happen to add opcodes for doing swaps in registers?
>
> No.
> (I haven't looked at the vector instructions yet.)

PS: There's a vector permutate instruction, but AFAICT there is no
way to move data between general purpose and vector registers; you
have to go through memory.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: powerpc64: ldbrx/stdbrx for endian.h?

2020-06-08 Thread Christian Weisgerber
David Gwynne:

> > Starting with POWER7 (Power ISA v.2.06), there are also corresponding
> > 64-bit instructions.  Do we want to use those on powerpc64?  Or do
> > we want to keep compatibility with older processors?
> 
> I'm ok with using the instructions. I can't think of what benefit compat in 
> this space would actually provide.

Well, if people were to extend powerpc64 down to the PowerPC G5
(= POWER4) Apple machines, then it would not be possible to use
those instructions.

> Did they also happen to add opcodes for doing swaps in registers?

No.
(I haven't looked at the vector instructions yet.)

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



powerpc64: ldbrx/stdbrx for endian.h?

2020-06-08 Thread Christian Weisgerber
powerpc has byte-swapping 16 and 32-bit load/stores and we use those
in .

Starting with POWER7 (Power ISA v.2.06), there are also corresponding
64-bit instructions.  Do we want to use those on powerpc64?  Or do
we want to keep compatibility with older processors?


Index: arch/powerpc64/include/endian.h
===
RCS file: /cvs/src/sys/arch/powerpc64/include/endian.h,v
retrieving revision 1.1
diff -u -p -r1.1 endian.h
--- arch/powerpc64/include/endian.h 16 May 2020 17:11:14 -  1.1
+++ arch/powerpc64/include/endian.h 8 Jun 2020 11:16:33 -
@@ -36,7 +36,7 @@ __mswap16(volatile const __uint16_t *m)
 
__asm("lhbrx %0, 0, %1"
: "=r" (v)
-: "r" (m), "m" (*m));
+   : "r" (m), "m" (*m));
 
return (v);
 }
@@ -48,7 +48,7 @@ __mswap32(volatile const __uint32_t *m)
 
__asm("lwbrx %0, 0, %1"
: "=r" (v)
-: "r" (m), "m" (*m));
+   : "r" (m), "m" (*m));
 
return (v);
 }
@@ -56,11 +56,11 @@ __mswap32(volatile const __uint32_t *m)
 static inline __uint64_t
 __mswap64(volatile const __uint64_t *m)
 {
-   __uint32_t *a = (__uint32_t *)m;
__uint64_t v;
 
-   v = (__uint64_t)__mswap32(a + 1) << 32 |
-   (__uint64_t)__mswap32(a);
+   __asm("ldbrx %0, 0, %1"
+   : "=r" (v)
+   : "r" (m), "m" (*m));
 
return (v);
 }
@@ -84,10 +84,9 @@ __swapm32(volatile __uint32_t *m, __uint
 static inline void
 __swapm64(volatile __uint64_t *m, __uint64_t v)
 {
-   __uint32_t *a = (__uint32_t *)m;
-
-   __swapm32(a + 1, v >> 32);
-   __swapm32(a, v);
+   __asm("stdbrx %1, 0, %2"
+   : "=m" (*m)
+   : "r" (v), "r" (m));
 }
 
 #define __HAVE_MD_SWAPIO
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: cpu_rnd_messybits() for arm64

2020-06-05 Thread Christian Weisgerber
Mark Kettenis:

> > Here is a cpu_rnd_messybits() implementation for arm64.
> > It reads the virtual counter and xors it with a bit-reversed copy
> > of itself.
> > 
> > The virtual counter is used by the only timecounter implementation
> > used on arm64, so I assume it is generally available.
> > 
> > It's a 64-bit counter, which we reduce to 32 bits.  Since there is
> > progressively less entropy in the higher bits of a counter than in
> > the lower bits, it intuitively makes sense not just to do hi^lo,
> > but to bit-reverse one half in order to extract maximal entropy,
> > and on aarch64 bit reversal is a simple instruction.
> 
> Can you make that uint64_t?
> Can you use %0 and %1 instead of %x0 and %x1?

Right.

Index: arch/arm64/arm64/machdep.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.52
diff -u -p -r1.52 machdep.c
--- arch/arm64/arm64/machdep.c  31 May 2020 06:23:57 -  1.52
+++ arch/arm64/arm64/machdep.c  5 Jun 2020 20:00:20 -
@@ -1247,12 +1247,3 @@ dumpregs(struct trapframe *frame)
printf("pc: 0x%016lx\n", frame->tf_elr);
printf("spsr: 0x%016lx\n", frame->tf_spsr);
 }
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: arch/arm64/include/cpu.h
===
RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
retrieving revision 1.17
diff -u -p -r1.17 cpu.h
--- arch/arm64/include/cpu.h31 May 2020 06:23:57 -  1.17
+++ arch/arm64/include/cpu.h5 Jun 2020 22:13:07 -
@@ -183,7 +183,16 @@ void cpu_boot_secondary_processors(void)
 
 #define curpcb curcpu()->ci_curpcb
 
-unsigned int   cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+   uint64_t val, rval;
+
+   __asm volatile("mrs %0, CNTVCT_EL0; rbit %1, %0;"
+   : "=r" (val), "=r" (rval));
+
+   return (val ^ rval);
+}
 
 /*
  * Scheduling glue
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



cpu_rnd_messybits() for arm64

2020-06-05 Thread Christian Weisgerber
Here is a cpu_rnd_messybits() implementation for arm64.
It reads the virtual counter and xors it with a bit-reversed copy
of itself.

The virtual counter is used by the only timecounter implementation
used on arm64, so I assume it is generally available.

It's a 64-bit counter, which we reduce to 32 bits.  Since there is
progressively less entropy in the higher bits of a counter than in
the lower bits, it intuitively makes sense not just to do hi^lo,
but to bit-reverse one half in order to extract maximal entropy,
and on aarch64 bit reversal is a simple instruction.

This patch I have tested!

ok?

Index: arch/arm64/arm64/machdep.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.52
diff -u -p -r1.52 machdep.c
--- arch/arm64/arm64/machdep.c  31 May 2020 06:23:57 -  1.52
+++ arch/arm64/arm64/machdep.c  5 Jun 2020 20:00:20 -
@@ -1247,12 +1247,3 @@ dumpregs(struct trapframe *frame)
printf("pc: 0x%016lx\n", frame->tf_elr);
printf("spsr: 0x%016lx\n", frame->tf_spsr);
 }
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: arch/arm64/include/cpu.h
===
RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
retrieving revision 1.17
diff -u -p -r1.17 cpu.h
--- arch/arm64/include/cpu.h31 May 2020 06:23:57 -  1.17
+++ arch/arm64/include/cpu.h5 Jun 2020 20:32:01 -
@@ -183,7 +183,16 @@ void cpu_boot_secondary_processors(void)
 
 #define curpcb curcpu()->ci_curpcb
 
-unsigned int   cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+   u_int64_t val, rval;
+
+   __asm volatile("mrs %x0, CNTVCT_EL0; rbit %x1, %x0;"
+   : "=r" (val), "=r" (rval));
+
+   return (val ^ rval);
+}
 
 /*
  * Scheduling glue
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



cpu_rnd_messybits() for alpha, powerpc, sparc64

2020-06-04 Thread Christian Weisgerber
Here's a proposal for implementing cpu_rnd_messybits() as a read of
the cycle counter on alpha, powerpc, and sparc64.  Since I don't have
those archs, the diff is not even compile-tested.

* alpha: RPCC is a 32-bit counter (in a 64-bit register)
* powerpc: TB is a 64-bit counter split into two registers
* sparc64: TICK is a(n implementation-defined, up to) 63-bit counter


Index: sys/arch/alpha/alpha/machdep.c
===
RCS file: /cvs/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.191
diff -u -p -r1.191 machdep.c
--- sys/arch/alpha/alpha/machdep.c  31 May 2020 06:23:56 -  1.191
+++ sys/arch/alpha/alpha/machdep.c  4 Jun 2020 17:57:45 -
@@ -1854,12 +1854,3 @@ alpha_XXX_dmamap(v)  
/* XXX */
return (vtophys(v) | alpha_XXX_dmamap_or);  /* XXX */
 }  /* XXX */
 /* XXX XXX END XXX XXX */
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: sys/arch/alpha/include/cpu.h
===
RCS file: /cvs/src/sys/arch/alpha/include/cpu.h,v
retrieving revision 1.62
diff -u -p -r1.62 cpu.h
--- sys/arch/alpha/include/cpu.h31 May 2020 06:23:56 -  1.62
+++ sys/arch/alpha/include/cpu.h4 Jun 2020 17:59:25 -
@@ -288,7 +288,11 @@ do {   
\
  */
 #definecpu_number()alpha_pal_whami()
 
-unsigned int cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+   return alpha_rpcc();
+}
 
 /*
  * Arguments to hardclock and gatherstats encapsulate the previous
Index: sys/arch/macppc/macppc/machdep.c
===
RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v
retrieving revision 1.191
diff -u -p -r1.191 machdep.c
--- sys/arch/macppc/macppc/machdep.c31 May 2020 06:23:57 -  1.191
+++ sys/arch/macppc/macppc/machdep.c4 Jun 2020 18:07:31 -
@@ -913,12 +913,3 @@ cpu_switchto(struct proc *oldproc, struc
 
cpu_switchto_asm(oldproc, newproc);
 }
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
Index: sys/arch/powerpc/include/cpu.h
===
RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.67
diff -u -p -r1.67 cpu.h
--- sys/arch/powerpc/include/cpu.h  31 May 2020 06:23:58 -  1.67
+++ sys/arch/powerpc/include/cpu.h  4 Jun 2020 18:13:07 -
@@ -161,7 +161,15 @@ extern int ppc_nobat;
 
 void   cpu_bootstrap(void);
 
-unsigned int cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+   unsigned int hi, lo;
+
+   __asm volatile("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo));
+
+   return (hi ^ lo);
+}
 
 /*
  * This is used during profiling to integrate system time.
Index: sys/arch/sparc64/include/cpu.h
===
RCS file: /cvs/src/sys/arch/sparc64/include/cpu.h,v
retrieving revision 1.94
diff -u -p -r1.94 cpu.h
--- sys/arch/sparc64/include/cpu.h  31 May 2020 06:23:58 -  1.94
+++ sys/arch/sparc64/include/cpu.h  4 Jun 2020 18:05:18 -
@@ -211,7 +211,15 @@ void   cpu_unidle(struct cpu_info *);
 #define curpcb __curcpu->ci_cpcb
 #define fpproc __curcpu->ci_fpproc
 
-unsigned int cpu_rnd_messybits(void);
+static inline unsigned int
+cpu_rnd_messybits(void)
+{
+   u_int64_t tick;
+
+   __asm volatile("rd %%tick, %0" : "=r" (tick) :);
+
+   return ((tick >> 32) ^ tick);
+}
 
 /*
  * On processors with multiple threads we force a thread switch.
Index: sys/arch/sparc64/sparc64/machdep.c
===
RCS file: /cvs/src/sys/arch/sparc64/sparc64/machdep.c,v
retrieving revision 1.196
diff -u -p -r1.196 machdep.c
--- sys/arch/sparc64/sparc64/machdep.c  31 May 2020 06:23:58 -  1.196
+++ sys/arch/sparc64/sparc64/machdep.c  4 Jun 2020 18:01:16 -
@@ -2114,12 +2114,3 @@ blink_led_timeout(void *vsc)
t = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
timeout_add(>bls_to, t);
 }
-
-unsigned int
-cpu_rnd_messybits(void)
-{
-   struct timespec ts;
-
-   nanotime();
-   return (ts.tv_nsec ^ (ts.tv_sec << 20));
-}
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: userland clock_gettime proof of concept

2020-06-01 Thread Christian Weisgerber
Theo de Raadt:

> > Then you still need to check on every call whether the clockid has
> > changed (because the kern.timecounter.hardware sysctl was changed)
> > and refetch the function pointer in that case.
> 
> Then really, we should remove that sysctl support.
> 
> Because otherwise I don't see how it can work.  Aren't there deadlock
> or spinning conditions?  Or at minimum, situtions where time won't flow
> linearly.

The patch as-is works fine when kern.timecounter.hardware is toggled
back and forth between tsc with userland gettime support and, say,
acpihpet0 without.  tk_user marks whether the currently selected
timecounter has userland support, the wrapper checks that and falls
back to the system call.

Reading the code, I don't see a reason why this shouldn't work fine,
and experimentally it does work.  Changing kern.timecounter.hardware
is transparent.

kettenis@'s suggestion of extending this from on/off to
clockid1/clockid2/.../off makes sense to me.  Most architectures
will likely only have one timecounter for which userland support
is possible, but sparc64 has indeed two (tick, stick).

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Xwindows keymap weirdness

2020-06-01 Thread Christian Weisgerber
Marc Espie:

> If I type 'c
> 
> I get a ç  in programs like firefox or chrome, BUT I get
> ć   in xterm ?
> 
> why are things different ? which program is right ?

GTK comes with its own compose rules that are occasionally different
from the default X11 ones.

Personally, I disable GTK's compose processing with GTK_IM_MODULE=xim.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: official ports vs DEBUG_PACKAGES

2020-05-29 Thread Christian Weisgerber
Marc Espie:

> There are about 3 solutions to that:
> - change the bulk machines to /usr/ports/pobj
> - change the ports default to /usr/obj/ports

I don't think it's reasonable to expect everybody to use the same
path here.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: random(4): use arc4random_ctx_buf() for large device reads

2020-05-25 Thread Christian Weisgerber
Sebastien Marie:

> > For large reads from /dev/random, use the arc4random_ctx_*() functions
> > instead of hand-rolling the same code to set up a temporary ChaCha
> > instance.
> 
> Eventually, I would get ride of myctx, initialize lctx to NULL, and use
> (lctx == NULL) to replace (myctx == 0).

Right.  Here we go:

Index: rnd.c
===
RCS file: /cvs/src/sys/dev/rnd.c,v
retrieving revision 1.213
diff -u -p -r1.213 rnd.c
--- rnd.c   18 May 2020 15:00:16 -  1.213
+++ rnd.c   25 May 2020 14:58:43 -
@@ -589,6 +589,9 @@ arc4random_ctx_free(struct arc4random_ct
 void
 arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n)
 {
+#ifndef KEYSTREAM_ONLY
+   memset(buf, 0, n);
+#endif
chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n);
 }
 
@@ -701,40 +704,31 @@ randomclose(dev_t dev, int flag, int mod
 int
 randomread(dev_t dev, struct uio *uio, int ioflag)
 {
-   u_char  lbuf[KEYSZ+IVSZ];
-   chacha_ctx  lctx;
+   struct arc4random_ctx *lctx = NULL;
size_t  total = uio->uio_resid;
u_char  *buf;
-   int myctx = 0, ret = 0;
+   int ret = 0;
 
if (uio->uio_resid == 0)
return 0;
 
buf = malloc(POOLBYTES, M_TEMP, M_WAITOK);
-   if (total > RND_MAIN_MAX_BYTES) {
-   arc4random_buf(lbuf, sizeof(lbuf));
-   chacha_keysetup(, lbuf, KEYSZ * 8);
-   chacha_ivsetup(, lbuf + KEYSZ, NULL);
-   explicit_bzero(lbuf, sizeof(lbuf));
-   myctx = 1;
-   }
+   if (total > RND_MAIN_MAX_BYTES)
+   lctx = arc4random_ctx_new();
 
while (ret == 0 && uio->uio_resid > 0) {
size_t  n = ulmin(POOLBYTES, uio->uio_resid);
 
-   if (myctx) {
-#ifndef KEYSTREAM_ONLY
-   memset(buf, 0, n);
-#endif
-   chacha_encrypt_bytes(, buf, buf, n);
-   } else
+   if (lctx != NULL)
+   arc4random_ctx_buf(lctx, buf, n);
+   else
arc4random_buf(buf, n);
ret = uiomove(buf, n, uio);
if (ret == 0 && uio->uio_resid > 0)
yield();
}
-   if (myctx)
-   explicit_bzero(, sizeof(lctx));
+   if (lctx != NULL)
+   arc4random_ctx_free(lctx);
explicit_bzero(buf, POOLBYTES);
free(buf, M_TEMP, POOLBYTES);
return ret;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



random(4): use arc4random_ctx_buf() for large device reads

2020-05-24 Thread Christian Weisgerber
(This is in a different part of the file from Theo's current efforts.)

For large reads from /dev/random, use the arc4random_ctx_*() functions
instead of hand-rolling the same code to set up a temporary ChaCha
instance.

ok?


Index: rnd.c
===
RCS file: /cvs/src/sys/dev/rnd.c,v
retrieving revision 1.213
diff -u -p -r1.213 rnd.c
--- rnd.c   18 May 2020 15:00:16 -  1.213
+++ rnd.c   24 May 2020 15:54:00 -
@@ -589,6 +589,9 @@ arc4random_ctx_free(struct arc4random_ct
 void
 arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n)
 {
+#ifndef KEYSTREAM_ONLY
+   memset(buf, 0, n);
+#endif
chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n);
 }
 
@@ -701,8 +704,7 @@ randomclose(dev_t dev, int flag, int mod
 int
 randomread(dev_t dev, struct uio *uio, int ioflag)
 {
-   u_char  lbuf[KEYSZ+IVSZ];
-   chacha_ctx  lctx;
+   struct arc4random_ctx *lctx;
size_t  total = uio->uio_resid;
u_char  *buf;
int myctx = 0, ret = 0;
@@ -712,29 +714,23 @@ randomread(dev_t dev, struct uio *uio, i
 
buf = malloc(POOLBYTES, M_TEMP, M_WAITOK);
if (total > RND_MAIN_MAX_BYTES) {
-   arc4random_buf(lbuf, sizeof(lbuf));
-   chacha_keysetup(, lbuf, KEYSZ * 8);
-   chacha_ivsetup(, lbuf + KEYSZ, NULL);
-   explicit_bzero(lbuf, sizeof(lbuf));
+   lctx = arc4random_ctx_new();
myctx = 1;
}
 
while (ret == 0 && uio->uio_resid > 0) {
size_t  n = ulmin(POOLBYTES, uio->uio_resid);
 
-   if (myctx) {
-#ifndef KEYSTREAM_ONLY
-   memset(buf, 0, n);
-#endif
-   chacha_encrypt_bytes(, buf, buf, n);
-   } else
+   if (myctx)
+   arc4random_ctx_buf(lctx, buf, n);
+   else
arc4random_buf(buf, n);
ret = uiomove(buf, n, uio);
if (ret == 0 && uio->uio_resid > 0)
yield();
}
if (myctx)
-   explicit_bzero(, sizeof(lctx));
+   arc4random_ctx_free(lctx);
explicit_bzero(buf, POOLBYTES);
free(buf, M_TEMP, POOLBYTES);
return ret;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: Block device poll(2) vs kqueue(2)

2020-05-20 Thread Christian Weisgerber
On 2020-05-20, Martin Pieuchot  wrote:

>   - FreeBSD doesn't allow opening block devices in devfs_open(), so
> only character devices seem to support poll(2) and kqueue(2).

FreeBSD doesn't have block devices anymore.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: iked(8): AES_GCM ciphers for IKE

2020-05-16 Thread Christian Weisgerber
Tobias Heider:

> currently iked(8) supports AES-GCM only for ESP.
> The diff below adds the ENCR_AES_GCM_16 and ENCR_AES_GCM_12 variants for IKE.
> (for more information see [1] and [2]).
> Both variants support the 128, 196, and 256 bit key lengths.
> 
> The new new ciphers can be configured with:
> - aes-128-gcm, aes-196-gcm and aes-256-gcm for ENCR_AES_GCM_16
> - aes-128-gcm-12, aes-196-gcm-12 and aes-256-gcm-12 for ENCR_AES_GCM_12

Is there a compelling reason to implement the GCM_12 variants?

I remember that truncating integrity tags is problematic for GCM.
That probably doesn't matter for small IKE exchanges, but then again
four extra bytes per packet don't matter either.  According to
RFC5282, full length tags MUST be supported anyway, truncated ones
are optional.

RFC5282 also says that AES-192 is NOT RECOMMENDED.

So I think only aes-128-gcm and aes-256-gcm should be added.  While
adding the other variants is simple, there is no value in supporting
them; they just add more configuration buttons.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



  1   2   3   4   5   >