David Gwynne <da...@gwynne.id.au> wrote: > > On 22 Jan 2020, at 8:54 am, Damien Miller <d...@mindrot.org> wrote: > > > > On Wed, 22 Jan 2020, David Gwynne wrote: > > > >>> Index: sys/kern/kern_pledge.c > >>> =================================================================== > >>> RCS file: /cvs/src/sys/kern/kern_pledge.c,v > >>> retrieving revision 1.255 > >>> diff -u -p -r1.255 kern_pledge.c > >>> --- sys/kern/kern_pledge.c 25 Aug 2019 18:46:40 -0000 1.255 > >>> +++ sys/kern/kern_pledge.c 29 Oct 2019 07:57:58 -0000 > >>> @@ -666,7 +666,7 @@ pledge_namei(struct proc *p, struct name > >>> } > >>> } > >>> > >>> - /* DNS needs /etc/{resolv.conf,hosts,services}. */ > >>> + /* DNS needs /etc/{resolv.conf,hosts,services,protocols}. */ > >>> if ((ni->ni_pledge == PLEDGE_RPATH) && > >>> (p->p_p->ps_pledge & PLEDGE_DNS)) { > >>> if (strcmp(path, "/etc/resolv.conf") == 0) { > >>> @@ -678,6 +678,10 @@ pledge_namei(struct proc *p, struct name > >>> return (0); > >>> } > >>> if (strcmp(path, "/etc/services") == 0) { > >>> + ni->ni_cnd.cn_flags |= BYPASSUNVEIL; > >>> + return (0); > >>> + } > >>> + if (strcmp(path, "/etc/protocols") == 0) { > >>> ni->ni_cnd.cn_flags |= BYPASSUNVEIL; > >>> return (0); > > > > This looks like it is fixing a real, separate bug in pledge vs > > getaddrinfo, no? (specifically: that lookups for named ports will fail > > currently). > > no, our getaddrinfo currently hardcodes mapping of SOCK_STREAM, SOCK_DGRAM, > IPPROTO_TCP, and IPPROTO_UDP and maps them to "udp" and "tcp" for use when > looking up /etc/services via getservbyname_r. this is fine because they are > by far the most common case and worth optimising for. > > the problem is if (when) i want to use getnameinfo to look up entries for > IPPROTO_GRE. i either hardcode IPPROTO_GRE in getnameinfo guts to "gre" for > it to pass to getservbyname_r, or i look up /etc/protocols via > getprotobynumber_r to get a name. i opted for the latter.
a number of people have expressed gaping-mouth horror that pledge knows about some userland paths. these specific paths are really part of what libc does. we could have hard-coded this info into libc and avoided the horror, but that approach would have other downsides. many programs hit libc interfaces which needed the /etc/services file because of getaddrinfo_async/getnameinfo which are highly desired interfaces. protocols hadn't hit this situation yet, but will now rise to the same level. i want to *minimize* the number of recognized paths, since there are two very subtle changes in behaviour. one other thing needs mentioning: this kind of translation won't work in a chroot.