Re: realpath(3) on a dangling symlink
On Wed, 27 Jun 2018 at 21:35:31 -0500, joshua stein wrote: > symlink("/tmp/link", "/tmp/nonexistent"); Oops, I changed this test code at the last second. The proper test code which incorrectly prints on OpenBSD: resolved realpath of /tmp/nonexistent (returned /tmp/nonexistent), errno is 2 #include #include #include #include #include #include int main() { char resolved[1024]; char *ret; unlink("/tmp/link"); unlink("/tmp/nonexistent"); symlink("/tmp/nonexistent", "/tmp/link"); ret = realpath("/tmp/link", resolved); if (ret == NULL) printf("realpath failed: %s\n", strerror(errno)); else printf("resolved realpath of %s (returned %s), errno is %d\n", resolved, ret, errno); return (0); }
realpath(3) on a dangling symlink
realpath(3) on a symlink that points to a non-existent path returns that path (but also sets errno), rather than returning NULL and setting errno. This is inconsistent with at least Linux, FreeBSD, and macOS. #include #include #include #include #include #include int main() { char resolved[1024]; char *ret; unlink("/tmp/link"); unlink("/tmp/nonexistent"); symlink("/tmp/link", "/tmp/nonexistent"); ret = realpath("/tmp/link", resolved); if (ret == NULL) printf("realpath failed: %s\n", strerror(errno)); else printf("resolved realpath of %s (returned %s), errno is %d\n", resolved, ret, errno); return (0); } Should print: realpath failed: No such file or directory But prints: resolved realpath of /tmp/link (returned /tmp/link), errno is 2 This makes it fall through to the error case (in case any memory needs to be freed) and return NULL. Index: lib/libc/stdlib/realpath.c === RCS file: /cvs/src/lib/libc/stdlib/realpath.c,v retrieving revision 1.22 diff -u -p -u -p -r1.22 realpath.c --- lib/libc/stdlib/realpath.c 24 Dec 2017 01:50:50 - 1.22 +++ lib/libc/stdlib/realpath.c 28 Jun 2018 02:24:37 - @@ -163,10 +163,8 @@ realpath(const char *path, char *resolve /* not a symlink, continue to next component */ continue; case ENOENT: - if (p == NULL) { + if (p == NULL) errno = serrno; - return (resolved); - } /* FALLTHROUGH */ default: goto err;
next step in synchronizing ber.c and ber.h
The following diff makes ber.c and ber.h identical across ldap, ldapd, and ypldap, and slightly reduces the diff with snmpd. It covers the evolution of a few scattered enhancements, including: - sync proscription of indefinite length BER encoding - sync consistent presence of ber_free_element() - sync correct parsing of '}' and ')' in ber_scanf_elements() (i.e. a "break" instead of a "continue") - sync use of ber_readbuf in ber_getc() Ok? Index: usr.bin/ldap/ber.c === RCS file: /cvs/src/usr.bin/ldap/ber.c,v retrieving revision 1.4 diff -u -p -r1.4 ber.c --- usr.bin/ldap/ber.c 27 Jun 2018 20:38:10 - 1.4 +++ usr.bin/ldap/ber.c 27 Jun 2018 22:15:55 - @@ -729,7 +729,7 @@ ber_scanf_elements(struct ber_element *b goto fail; ber = parent[level--]; ret++; - continue; + break; default: goto fail; } @@ -822,6 +822,19 @@ ber_read_elements(struct ber *ber, struc } void +ber_free_element(struct ber_element *root) +{ + if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || + root->be_encoding == BER_TYPE_SET)) + ber_free_elements(root->be_sub); + if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || + root->be_encoding == BER_TYPE_BITSTRING || + root->be_encoding == BER_TYPE_OBJECT)) + free(root->be_val); + free(root); +} + +void ber_free_elements(struct ber_element *root) { if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || @@ -1030,6 +1043,12 @@ get_len(struct ber *b, ssize_t *len) return 1; } + if (u == 0x80) { + /* Indefinite length not supported. */ + errno = EINVAL; + return -1; + } + n = u & ~BER_TAG_MORE; if (sizeof(ssize_t) < n) { errno = ERANGE; @@ -1046,12 +1065,6 @@ get_len(struct ber *b, ssize_t *len) if (s < 0) { /* overflow */ errno = ERANGE; - return -1; - } - - if (s == 0) { - /* invalid encoding */ - errno = EINVAL; return -1; } Index: usr.bin/ldap/ber.h === RCS file: /cvs/src/usr.bin/ldap/ber.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 ber.h --- usr.bin/ldap/ber.h 13 Jun 2018 15:45:57 - 1.1.1.1 +++ usr.bin/ldap/ber.h 27 Jun 2018 22:15:55 - @@ -119,6 +119,7 @@ ssize_t ber_get_writebuf(struct ber * int ber_write_elements(struct ber *, struct ber_element *); voidber_set_readbuf(struct ber *, void *, size_t); struct ber_element *ber_read_elements(struct ber *, struct ber_element *); +voidber_free_element(struct ber_element *); voidber_free_elements(struct ber_element *); size_t ber_calc_len(struct ber_element *); voidber_set_application(struct ber *, Index: usr.sbin/ldapd/ber.c === RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v retrieving revision 1.14 diff -u -p -r1.14 ber.c --- usr.sbin/ldapd/ber.c27 Jun 2018 13:22:17 - 1.14 +++ usr.sbin/ldapd/ber.c27 Jun 2018 22:15:55 - @@ -729,7 +729,7 @@ ber_scanf_elements(struct ber_element *b goto fail; ber = parent[level--]; ret++; - continue; + break; default: goto fail; } Index: usr.sbin/ypldap/ber.c === RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v retrieving revision 1.16 diff -u -p -r1.16 ber.c --- usr.sbin/ypldap/ber.c 27 Jun 2018 20:38:10 - 1.16 +++ usr.sbin/ypldap/ber.c 27 Jun 2018 22:15:56 - @@ -729,7 +729,7 @@ ber_scanf_elements(struct ber_element *b goto fail; ber = parent[level--]; ret++; - continue; + break; default: goto fail; } @@ -822,6 +822,19 @@ ber_read_elements(struct ber *ber, struc } void +ber_free_element(struct ber_element *root) +{ + if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || + root->be_encoding == BER_TYPE_SET)) + ber_free_elements(root->be_sub); + if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || + root->be_encoding == BER_TYPE_BITSTRING || + root->be_encoding ==
irrsi pkg_info (amd64 - [6.2])
Hello, Could you be so kind to explain me this issue for "irssi" pkg (IRC client 6.2/[amd64]) # pkg_info -f irssi | grep '@depend' | cut -f 3 -d : libiconv-1.14p3 gettext-0.19.8.1p1 glib2-2.52.3 libiconv-1.14p3 <-REPEAT gettext-0.19.8.1p1 <-REPEAT glib2-2.52.3<-REPEAT dante-1.4.1p0 BR Oleg Pahl (Munich)
Re: pkg_info (vlc)
On 2018/06/27 22:09, Dr. COD wrote: > Hello all, > > I would like to inform tech team about one problem with our Public > REPOSITORY for 6.2 (amd64): > > *# pkg_info vlc | grep Information | cut -d ':' -f 2* > > I got answer from system: > > *//ftp.openbsd.org/pub/OpenBSD/6.2/packages/amd64/vlc-2.2.6p0.tgz* > > I thing that it's not correct and should be: > > *vlc-2.2.6p0* > > Please confirm it. > > Sorry for my English. > > BR > > Oleg Pahl (Munich) > It is correct, it allows you to distinguish between data fetched from a remote source, and data fetched from a package that you have installed on your system ("Information for inst:vlc-2.2.6p0").
pkg_info (vlc)
Hello all, I would like to inform tech team about one problem with our Public REPOSITORY for 6.2 (amd64): *# pkg_info vlc | grep Information | cut -d ':' -f 2* I got answer from system: *//ftp.openbsd.org/pub/OpenBSD/6.2/packages/amd64/vlc-2.2.6p0.tgz* I thing that it's not correct and should be: *vlc-2.2.6p0* Please confirm it. Sorry for my English. BR Oleg Pahl (Munich)
Re: more bgpd cleanup
reads good running on a machine here without problems ok benno@ Claudio Jeker(cje...@diehard.n-r-g.com) on 2018.06.27 16:55:57 +0200: > My plan is to make struct prefix the main object that holds references to > aspath, nexthop and rib. This diff is the next little step towards that. > > Pass a struct prefix to rde_filter and remove some of the arguments which > are now fetched from struct prefix. Currently some trickery is needed > for export default-route but this will get better once Adj-RIB-Out comes. > > Please test and review > -- > :wq Claudio > > Index: rde.c > === > RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v > retrieving revision 1.381 > diff -u -p -r1.381 rde.c > --- rde.c 25 Jun 2018 14:28:33 - 1.381 > +++ rde.c 27 Jun 2018 13:18:01 - > @@ -1364,6 +1364,7 @@ rde_update_update(struct rde_peer *peer, > struct bgpd_addr *prefix, u_int8_t prefixlen) > { > struct rde_aspath *fasp; > + struct prefix *p; > enum filter_actions action; > u_int16_ti; > > @@ -1372,12 +1373,15 @@ rde_update_update(struct rde_peer *peer, > if (path_update([RIB_ADJ_IN].rib, peer, asp, prefix, prefixlen, 0)) > peer->prefix_cnt++; > > + p = prefix_get([RIB_ADJ_IN].rib, peer, prefix, prefixlen, 0); > + if (p == NULL) > + fatalx("rde_update_update: no prefix in Adj-RIB-In"); > + > for (i = RIB_LOC_START; i < rib_size; i++) { > if (*ribs[i].name == '\0') > break; > /* input filter */ > - action = rde_filter(ribs[i].in_rules, , peer, asp, prefix, > - prefixlen, peer); > + action = rde_filter(ribs[i].in_rules, peer, , p, asp); > > if (fasp == NULL) > fasp = asp; > @@ -2303,8 +2307,7 @@ rde_dump_filterout(struct rde_peer *peer > > pt_getaddr(p->re->prefix, ); > asp = prefix_aspath(p); > - a = rde_filter(out_rules, , peer, asp, , > - p->re->prefix->prefixlen, asp->peer); > + a = rde_filter(out_rules, peer, , p, asp); > if (fasp) > fasp->peer = asp->peer; > else > @@ -3064,16 +3067,14 @@ rde_softreconfig_in(struct rib_entry *re > > /* check if prefix changed */ > if (rib->state == RECONF_RELOAD) { > - oa = rde_filter(rib->in_rules_tmp, , peer, > - asp, , pt->prefixlen, peer); > + oa = rde_filter(rib->in_rules_tmp, peer, , p, asp); > oasp = oasp != NULL ? oasp : asp; > } else { > /* make sure we update everything for RECONF_REINIT */ > oa = ACTION_DENY; > oasp = asp; > } > - na = rde_filter(rib->in_rules, , peer, asp, > - , pt->prefixlen, peer); > + na = rde_filter(rib->in_rules, peer, , p, asp); > nasp = nasp != NULL ? nasp : asp; > > /* go through all 4 possible combinations */ > @@ -3122,10 +3123,8 @@ rde_softreconfig_out(struct rib_entry *r > if (up_test_update(peer, p) != 1) > return; > > - oa = rde_filter(out_rules_tmp, , peer, prefix_aspath(p), > - , pt->prefixlen, prefix_peer(p)); > - na = rde_filter(out_rules, , peer, prefix_aspath(p), > - , pt->prefixlen, prefix_peer(p)); > + oa = rde_filter(out_rules_tmp, peer, , p, prefix_aspath(p)); > + na = rde_filter(out_rules, peer, , p, prefix_aspath(p)); > oasp = oasp != NULL ? oasp : prefix_aspath(p); > nasp = nasp != NULL ? nasp : prefix_aspath(p); > > @@ -3167,8 +3166,7 @@ rde_softreconfig_unload_peer(struct rib_ > if (up_test_update(peer, p) != 1) > return; > > - oa = rde_filter(out_rules_tmp, , peer, prefix_aspath(p), > - , pt->prefixlen, prefix_peer(p)); > + oa = rde_filter(out_rules_tmp, peer, , p, prefix_aspath(p)); > oasp = oasp != NULL ? oasp : prefix_aspath(p); > > if (oa == ACTION_DENY) > @@ -3648,9 +3646,9 @@ network_add(struct network_config *nc, i > } > if (!flagstatic) > asp->flags |= F_ANN_DYNAMIC; > - rde_apply_set(asp, >attrset, nc->prefix.aid, peerself, peerself); > + rde_apply_set(>attrset, asp, nc->prefix.aid, peerself, peerself); > if (vpnset) > - rde_apply_set(asp, vpnset, nc->prefix.aid, peerself, peerself); > + rde_apply_set(vpnset, asp, nc->prefix.aid, peerself, peerself); > for (i = RIB_LOC_START; i < rib_size; i++) { > if (*ribs[i].name == '\0') > break; > Index: rde.h > === > RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v > retrieving revision 1.171 > diff -u -p -r1.171 rde.h > --- rde.h 27 Jun 2018 13:14:44 -
more bgpd cleanup
My plan is to make struct prefix the main object that holds references to aspath, nexthop and rib. This diff is the next little step towards that. Pass a struct prefix to rde_filter and remove some of the arguments which are now fetched from struct prefix. Currently some trickery is needed for export default-route but this will get better once Adj-RIB-Out comes. Please test and review -- :wq Claudio Index: rde.c === RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v retrieving revision 1.381 diff -u -p -r1.381 rde.c --- rde.c 25 Jun 2018 14:28:33 - 1.381 +++ rde.c 27 Jun 2018 13:18:01 - @@ -1364,6 +1364,7 @@ rde_update_update(struct rde_peer *peer, struct bgpd_addr *prefix, u_int8_t prefixlen) { struct rde_aspath *fasp; + struct prefix *p; enum filter_actions action; u_int16_ti; @@ -1372,12 +1373,15 @@ rde_update_update(struct rde_peer *peer, if (path_update([RIB_ADJ_IN].rib, peer, asp, prefix, prefixlen, 0)) peer->prefix_cnt++; + p = prefix_get([RIB_ADJ_IN].rib, peer, prefix, prefixlen, 0); + if (p == NULL) + fatalx("rde_update_update: no prefix in Adj-RIB-In"); + for (i = RIB_LOC_START; i < rib_size; i++) { if (*ribs[i].name == '\0') break; /* input filter */ - action = rde_filter(ribs[i].in_rules, , peer, asp, prefix, - prefixlen, peer); + action = rde_filter(ribs[i].in_rules, peer, , p, asp); if (fasp == NULL) fasp = asp; @@ -2303,8 +2307,7 @@ rde_dump_filterout(struct rde_peer *peer pt_getaddr(p->re->prefix, ); asp = prefix_aspath(p); - a = rde_filter(out_rules, , peer, asp, , - p->re->prefix->prefixlen, asp->peer); + a = rde_filter(out_rules, peer, , p, asp); if (fasp) fasp->peer = asp->peer; else @@ -3064,16 +3067,14 @@ rde_softreconfig_in(struct rib_entry *re /* check if prefix changed */ if (rib->state == RECONF_RELOAD) { - oa = rde_filter(rib->in_rules_tmp, , peer, - asp, , pt->prefixlen, peer); + oa = rde_filter(rib->in_rules_tmp, peer, , p, asp); oasp = oasp != NULL ? oasp : asp; } else { /* make sure we update everything for RECONF_REINIT */ oa = ACTION_DENY; oasp = asp; } - na = rde_filter(rib->in_rules, , peer, asp, - , pt->prefixlen, peer); + na = rde_filter(rib->in_rules, peer, , p, asp); nasp = nasp != NULL ? nasp : asp; /* go through all 4 possible combinations */ @@ -3122,10 +3123,8 @@ rde_softreconfig_out(struct rib_entry *r if (up_test_update(peer, p) != 1) return; - oa = rde_filter(out_rules_tmp, , peer, prefix_aspath(p), - , pt->prefixlen, prefix_peer(p)); - na = rde_filter(out_rules, , peer, prefix_aspath(p), - , pt->prefixlen, prefix_peer(p)); + oa = rde_filter(out_rules_tmp, peer, , p, prefix_aspath(p)); + na = rde_filter(out_rules, peer, , p, prefix_aspath(p)); oasp = oasp != NULL ? oasp : prefix_aspath(p); nasp = nasp != NULL ? nasp : prefix_aspath(p); @@ -3167,8 +3166,7 @@ rde_softreconfig_unload_peer(struct rib_ if (up_test_update(peer, p) != 1) return; - oa = rde_filter(out_rules_tmp, , peer, prefix_aspath(p), - , pt->prefixlen, prefix_peer(p)); + oa = rde_filter(out_rules_tmp, peer, , p, prefix_aspath(p)); oasp = oasp != NULL ? oasp : prefix_aspath(p); if (oa == ACTION_DENY) @@ -3648,9 +3646,9 @@ network_add(struct network_config *nc, i } if (!flagstatic) asp->flags |= F_ANN_DYNAMIC; - rde_apply_set(asp, >attrset, nc->prefix.aid, peerself, peerself); + rde_apply_set(>attrset, asp, nc->prefix.aid, peerself, peerself); if (vpnset) - rde_apply_set(asp, vpnset, nc->prefix.aid, peerself, peerself); + rde_apply_set(vpnset, asp, nc->prefix.aid, peerself, peerself); for (i = RIB_LOC_START; i < rib_size; i++) { if (*ribs[i].name == '\0') break; Index: rde.h === RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v retrieving revision 1.171 diff -u -p -r1.171 rde.h --- rde.h 27 Jun 2018 13:14:44 - 1.171 +++ rde.h 27 Jun 2018 13:20:17 - @@ -402,10 +402,10 @@ u_char*community_ext_delete_non_trans( voidprefix_evaluate(struct prefix *, struct rib_entry *); /* rde_filter.c */
Re: sync calloc call in ber.c
On Wed, Jun 27, 2018 at 10:05:52AM -0400, Rob Pierce wrote: > This ber.c change has been in ldapd since rev 1.1 and was applied to snmpd > back > in 2012. The following diff applies the change to the ldap client and ypldap. > > Ok? looks right, > > Index: usr.bin/ldap/ber.c > === > RCS file: /cvs/src/usr.bin/ldap/ber.c,v > retrieving revision 1.2 > diff -u -p -r1.2 ber.c > --- usr.bin/ldap/ber.c27 Jun 2018 13:22:17 - 1.2 > +++ usr.bin/ldap/ber.c27 Jun 2018 13:55:51 - > @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev > struct ber_element *elm; > char *string; > > - if ((string = calloc(1, len)) == NULL) > + if ((string = calloc(1, len + 1)) == NULL) > return NULL; > if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { > free(string); > > Index: usr.sbin/ypldap/ber.c > === > RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v > retrieving revision 1.14 > diff -u -p -r1.14 ber.c > --- usr.sbin/ypldap/ber.c 27 Jun 2018 13:22:17 - 1.14 > +++ usr.sbin/ypldap/ber.c 27 Jun 2018 13:55:51 - > @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev > struct ber_element *elm; > char *string; > > - if ((string = calloc(1, len)) == NULL) > + if ((string = calloc(1, len + 1)) == NULL) > return NULL; > if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { > free(string); >
Re: sync calloc call in ber.c
On Wed, Jun 27, 2018 at 10:05:52AM -0400, Rob Pierce wrote: > This ber.c change has been in ldapd since rev 1.1 and was applied to snmpd > back > in 2012. The following diff applies the change to the ldap client and ypldap. > > Ok? OK claudio@ > Index: usr.bin/ldap/ber.c > === > RCS file: /cvs/src/usr.bin/ldap/ber.c,v > retrieving revision 1.2 > diff -u -p -r1.2 ber.c > --- usr.bin/ldap/ber.c27 Jun 2018 13:22:17 - 1.2 > +++ usr.bin/ldap/ber.c27 Jun 2018 13:55:51 - > @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev > struct ber_element *elm; > char *string; > > - if ((string = calloc(1, len)) == NULL) > + if ((string = calloc(1, len + 1)) == NULL) > return NULL; > if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { > free(string); > > Index: usr.sbin/ypldap/ber.c > === > RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v > retrieving revision 1.14 > diff -u -p -r1.14 ber.c > --- usr.sbin/ypldap/ber.c 27 Jun 2018 13:22:17 - 1.14 > +++ usr.sbin/ypldap/ber.c 27 Jun 2018 13:55:51 - > @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev > struct ber_element *elm; > char *string; > > - if ((string = calloc(1, len)) == NULL) > + if ((string = calloc(1, len + 1)) == NULL) > return NULL; > if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { > free(string); > -- :wq Claudio
sync calloc call in ber.c
This ber.c change has been in ldapd since rev 1.1 and was applied to snmpd back in 2012. The following diff applies the change to the ldap client and ypldap. Ok? Index: usr.bin/ldap/ber.c === RCS file: /cvs/src/usr.bin/ldap/ber.c,v retrieving revision 1.2 diff -u -p -r1.2 ber.c --- usr.bin/ldap/ber.c 27 Jun 2018 13:22:17 - 1.2 +++ usr.bin/ldap/ber.c 27 Jun 2018 13:55:51 - @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev struct ber_element *elm; char *string; - if ((string = calloc(1, len)) == NULL) + if ((string = calloc(1, len + 1)) == NULL) return NULL; if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { free(string); Index: usr.sbin/ypldap/ber.c === RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v retrieving revision 1.14 diff -u -p -r1.14 ber.c --- usr.sbin/ypldap/ber.c 27 Jun 2018 13:22:17 - 1.14 +++ usr.sbin/ypldap/ber.c 27 Jun 2018 13:55:51 - @@ -269,7 +269,7 @@ ber_add_nstring(struct ber_element *prev struct ber_element *elm; char *string; - if ((string = calloc(1, len)) == NULL) + if ((string = calloc(1, len + 1)) == NULL) return NULL; if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) { free(string);
Re: Unlock sendit-based syscalls
Here is a new version of the f_count atomic update diff. Now all updating of the `f_count' field should use atomic operations, and the `fhdlk' is only used for serializing access to the list of open files. In addition, the role of the `fd_fplock' should be clearer now: its only purpose is to let fd_getfile() instantiate a file reference safely. The `fd_lock' has to be locked when changing a file descriptor table. When the unlocking of system calls proceeds further, it will become necessary to protect the `fd_ofileflags' field with a lock because of fdexpand() and to maintain coherency with `fd_ofiles'. The patch includes two small, logically separate, pieces towards that: fdp locking for fcntl(F_GETFD), and fdp locking for unp_internalize(). The former merely ensures that the `fd_ofileflags' array is valid, while the latter also makes sure the `fd_ofileflags[fd]' entry matches with the file instance. OK? Index: kern/kern_descrip.c === RCS file: src/sys/kern/kern_descrip.c,v retrieving revision 1.171 diff -u -p -r1.171 kern_descrip.c --- kern/kern_descrip.c 26 Jun 2018 14:43:01 - 1.171 +++ kern/kern_descrip.c 27 Jun 2018 12:52:25 - @@ -198,6 +198,7 @@ struct file * fd_iterfile(struct file *fp, struct proc *p) { struct file *nfp; + unsigned int count; mtx_enter(); if (fp == NULL) @@ -206,10 +207,15 @@ fd_iterfile(struct file *fp, struct proc nfp = LIST_NEXT(fp, f_list); /* don't refcount when f_count == 0 to avoid race in fdrop() */ - while (nfp != NULL && nfp->f_count == 0) - nfp = LIST_NEXT(nfp, f_list); - if (nfp != NULL) - nfp->f_count++; + while (nfp != NULL) { + count = nfp->f_count; + if (count == 0) { + nfp = LIST_NEXT(nfp, f_list); + continue; + } + if (atomic_cas_uint(>f_count, count, count + 1) == count) + break; + } mtx_leave(); if (fp != NULL) @@ -228,11 +234,11 @@ fd_getfile(struct filedesc *fdp, int fd) if ((u_int)fd >= fdp->fd_nfiles) return (NULL); - mtx_enter(); + mtx_enter(>fd_fplock); fp = fdp->fd_ofiles[fd]; if (fp != NULL) - fp->f_count++; - mtx_leave(); + atomic_inc_int(>f_count); + mtx_leave(>fd_fplock); return (fp); } @@ -433,7 +439,9 @@ restart: return (error); case F_GETFD: + fdplock(fdp); *retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0; + fdpunlock(fdp); break; case F_SETFD: @@ -652,7 +660,7 @@ finishdup(struct proc *p, struct file *f fdpassertlocked(fdp); KASSERT(fp->f_iflags & FIF_INSERTED); - if (fp->f_count == LONG_MAX-2) { + if (fp->f_count >= FDUP_MAX_COUNT) { FRELE(fp, p); return (EDEADLK); } @@ -666,7 +674,14 @@ finishdup(struct proc *p, struct file *f fd_used(fdp, new); } + /* +* Use `fd_fplock' to synchronize with fd_getfile() so that +* the function no longer creates a new reference to the old file. +*/ + mtx_enter(>fd_fplock); fdp->fd_ofiles[new] = fp; + mtx_leave(>fd_fplock); + fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~UF_EXCLOSE; *retval = new; @@ -694,18 +709,31 @@ fdinsert(struct filedesc *fdp, int fd, i LIST_INSERT_HEAD(, fp, f_list); } } + mtx_leave(); + + mtx_enter(>fd_fplock); KASSERT(fdp->fd_ofiles[fd] == NULL); fdp->fd_ofiles[fd] = fp; + mtx_leave(>fd_fplock); + fdp->fd_ofileflags[fd] |= (flags & UF_EXCLOSE); - mtx_leave(); } void fdremove(struct filedesc *fdp, int fd) { fdpassertlocked(fdp); + + /* +* Use `fd_fplock' to synchronize with fd_getfile() so that +* the function no longer creates a new reference to the file. +*/ + mtx_enter(>fd_fplock); fdp->fd_ofiles[fd] = NULL; + mtx_leave(>fd_fplock); + fdp->fd_ofileflags[fd] = 0; + fd_unused(fdp, fd); } @@ -839,6 +867,8 @@ fdalloc(struct proc *p, int want, int *r int lim, last, i; u_int new, off; + fdpassertlocked(fdp); + /* * Search for a free descriptor starting at the higher * of want or fd_freefile. If that fails, consider @@ -886,14 +916,17 @@ void fdexpand(struct proc *p) { struct filedesc *fdp = p->p_fd; - int nfiles; + int nfiles, oldnfiles; size_t copylen; - struct file **newofile; + struct file **newofile, **oldofile; char *newofileflags; u_int *newhimap, *newlomap; fdpassertlocked(fdp); + oldnfiles
IP_SENDSRCADDR cmsg_len and dnsmasq
So a while back Alexander Markert sent a bug report regarding sendmsg() behaviour with IP_SENDSRCADDR : https://marc.info/?l=openbsd-tech=149276833923905=2 This impacts our dnsmasq port : https://marc.info/?l=openbsd-tech=149234052220818=2 Alexander Markert shows in the first thread the problematic code and conditions. To save you the trip back in time : sendfrom() returns EWOULDBLOCK (or blocks if using blocking IO) when len(cmsg) + len(data) > len(socket.buffer). The better behaviour would be to never block and return EMSGSIZE. The first diff fixes the kernel code ; The second diff reverts https://marc.info/?l=openbsd-ports-cvs=149233921320572=2 and fixes a bad cmsg setup. 1) Can you confirm this fixes dnsmasq ? or whatever you used to trigger the bug ? 2) Ok ? (apologies for the delay by the way :S ) -- 8< 8< 8< -- Index: sys/kern/uipc_socket.c === RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.224 diff -u -p -r1.224 uipc_socket.c --- sys/kern/uipc_socket.c 14 Jun 2018 08:46:09 - 1.224 +++ sys/kern/uipc_socket.c26 Jun 2018 18:51:49 - @@ -459,9 +459,10 @@ restart: space = sbspace(so, >so_snd); if (flags & MSG_OOB) space += 1024; - if ((atomic && resid > so->so_snd.sb_hiwat) || + if ((so->so_proto->pr_domain->dom_family == AF_UNIX && + atomic && resid > so->so_snd.sb_hiwat) || (so->so_proto->pr_domain->dom_family != AF_UNIX && - clen > so->so_snd.sb_hiwat)) + clen + (atomic ? resid : 0) > so->so_snd.sb_hiwat)) snderr(EMSGSIZE); if (space < clen || (space - clen < resid && -- 8< 8< 8< -- Index: net/dnsmasq/patches/patch-src_dnsmasq_c === RCS file: net/dnsmasq/patches/patch-src_dnsmasq_c diff -N net/dnsmasq/patches/patch-src_dnsmasq_c --- net/dnsmasq/patches/patch-src_dnsmasq_c 29 Mar 2018 19:42:51 - 1.5 +++ /dev/null 1 Jan 1970 00:00:00 - @@ -1,16 +0,0 @@ -$OpenBSD: patch-src_dnsmasq_c,v 1.5 2018/03/29 19:42:51 ajacoutot Exp $ - -Fails. Currently disabled pending investigation. - -Index: src/dnsmasq.c src/dnsmasq.c.orig -+++ src/dnsmasq.c -@@ -149,7 +149,7 @@ int main (int argc, char **argv) - open("/dev/null", O_RDWR); - - #ifndef HAVE_LINUX_NETWORK --# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR)) -+# if defined(__OpenBSD__) || !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR)) - if (!option_bool(OPT_NOWILD)) - { - bind_fallback = 1; Index: net/dnsmasq/patches/patch-src_forward_c === RCS file: /cvs/ports/net/dnsmasq/patches/patch-src_forward_c,v retrieving revision 1.1 diff -u -p -r1.1 patch-src_forward_c --- net/dnsmasq/patches/patch-src_forward_c 16 Apr 2017 10:40:07 - 1.1 +++ net/dnsmasq/patches/patch-src_forward_c 26 Jun 2018 18:48:17 - @@ -1,24 +1,17 @@ -$OpenBSD: patch-src_forward_c,v 1.1 2017/04/16 10:40:07 sthen Exp $ +$OpenBSD$ -Fails. Currently disabled pending investigation. +CMSG_SPACE() != CMSG_LEN() src/forward.c.orig Sat Apr 15 22:36:04 2017 -+++ src/forward.c Sat Apr 15 22:46:09 2017 -@@ -35,7 +35,7 @@ int send_from(int fd, int nowild, char *packet, size_t - struct cmsghdr align; /* this ensures alignment */ - #if defined(HAVE_LINUX_NETWORK) - char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; --#elif defined(IP_SENDSRCADDR) -+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR) - char control[CMSG_SPACE(sizeof(struct in_addr))]; - #endif - #ifdef HAVE_IPV6 -@@ -71,7 +71,7 @@ int send_from(int fd, int nowild, char *packet, size_t - msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); - cmptr->cmsg_level = IPPROTO_IP; +Index: src/forward.c +--- src/forward.c.orig src/forward.c +@@ -73,7 +73,8 @@ int send_from(int fd, int nowild, char *packet, size_t cmptr->cmsg_type = IP_PKTINFO; --#elif defined(IP_SENDSRCADDR) -+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR) + #elif defined(IP_SENDSRCADDR) memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4)); - msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); +-msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); ++msg.msg_controllen = sizeof(control_u.control); ++cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); cmptr->cmsg_level = IPPROTO_IP; + cmptr->cmsg_type = IP_SENDSRCADDR; + #endif
[PATCH] smsc: set SMSC_MII_BUSY to read/write PHY regs
Hi, The diff below sets SMSC_MII_BUSY bit, which is necessary for PHY to acknowledge a read/write request; from FreeBSD r333096. While here, mask off the PHY address and register. Tested on rpi3. # dmesg |grep smsc smsc0 at uhub1 port 1 configuration 1 interface 0 "Standard Microsystems SMSC9512/14" rev 2.00/2.00 addr 3 smsc0: address b8:27:eb:b0:32:5d ukphy0 at smsc0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x0001f0, model 0x000c Index: sys/dev/usb/if_smsc.c === RCS file: /cvs/src/sys/dev/usb/if_smsc.c,v retrieving revision 1.31 diff -u -p -u -p -r1.31 if_smsc.c --- sys/dev/usb/if_smsc.c 29 Jul 2017 17:24:04 - 1.31 +++ sys/dev/usb/if_smsc.c 27 Jun 2018 08:37:34 - @@ -283,7 +283,6 @@ int smsc_miibus_readreg(struct device *dev, int phy, int reg) { struct smsc_softc *sc = (struct smsc_softc *)dev; - uint32_t addr; uint32_t val = 0; smsc_lock_mii(sc); @@ -292,8 +291,8 @@ smsc_miibus_readreg(struct device *dev, goto done; } - addr = (phy << 11) | (reg << 6) | SMSC_MII_READ; - smsc_write_reg(sc, SMSC_MII_ADDR, addr); + smsc_write_reg(sc, SMSC_MII_ADDR, SMSC_MII_READ | SMSC_MII_BUSY | + SMSC_MII_PHY_ADDR(phy) | SMSC_MII_REG_ADDR(reg)); if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) smsc_warn_printf(sc, "MII read timeout\n"); @@ -309,7 +308,6 @@ void smsc_miibus_writereg(struct device *dev, int phy, int reg, int val) { struct smsc_softc *sc = (struct smsc_softc *)dev; - uint32_t addr; if (sc->sc_phyno != phy) return; @@ -323,8 +321,9 @@ smsc_miibus_writereg(struct device *dev, smsc_write_reg(sc, SMSC_MII_DATA, val); - addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE; - smsc_write_reg(sc, SMSC_MII_ADDR, addr); + smsc_write_reg(sc, SMSC_MII_ADDR, SMSC_MII_WRITE | SMSC_MII_BUSY | + SMSC_MII_PHY_ADDR(phy) | SMSC_MII_REG_ADDR(reg)); + smsc_unlock_mii(sc); if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0) Index: sys/dev/usb/if_smscreg.h === RCS file: /cvs/src/sys/dev/usb/if_smscreg.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 if_smscreg.h --- sys/dev/usb/if_smscreg.h18 Jun 2015 09:28:54 - 1.5 +++ sys/dev/usb/if_smscreg.h27 Jun 2018 08:37:35 - @@ -215,9 +215,17 @@ #define SMSC_INTR_GPIOS 0x07FFUL /* Phy MII interface register */ +#define SMSC_MII_PHY_ADDR_MASK 0xF800 +#define SMSC_MII_PHY_ADDR_SHIFT 11 +#define SMSC_MII_REG_ADDR_MASK 0x07C0 +#define SMSC_MII_REG_ADDR_SHIFT 6 #define SMSC_MII_WRITE (0x1UL << 1) #define SMSC_MII_READ (0x0UL << 1) #define SMSC_MII_BUSY (0x1UL << 0) +#define SMSC_MII_REG_ADDR(x)\ +(((x) << SMSC_MII_REG_ADDR_SHIFT ) & SMSC_MII_REG_ADDR_MASK) +#define SMSC_MII_PHY_ADDR(x) \ +(((x) << SMSC_MII_PHY_ADDR_SHIFT) & SMSC_MII_PHY_ADDR_MASK) /* H/W checksum register */ #define SMSC_COE_CTRL_TX_EN (0x1UL << 16) /* Tx H/W csum enable */