On Sun, Oct 02, 2022 at 06:32:04PM +0000, Klemens Nanni wrote: > diskless(8) just needs tftpd(8) to deliver files, none of the possibly > untrusted clients are supposed to ever write anything. > > Either way, even when run without -c, a single file writable by _tftpd > might be enough for a malicious client to fill up the server's disk. > > A proper read-only mode ("stdio rpath dns inet") seems much safer.
agreed. i'm ok with this diff, but it's worth asking if we can make the default read-only and ask people to opt in for write (and create) before this specific diff goes in. ie, read-only be default, '-w' to enable write mode, '-c' to enable write+create? > > diskless(8) setup and manual testing runs fine with this, clients get > proper error responses (just like trying to write /etc/random.seed) and > the server keeps running without any pledge violations: > > $ doas ./obj/tfpd -dvR ./_tftpd > > $ touch file > $ echo put file | tftp localhost > tftp> Error code 2: Access violation > > tftpd: 127.0.0.1: write request for 'file' > tftpd: 127.0.0.1: nak: Access violation > > > tftpd(8) is nicely written such that all file access goes through a > single validation function, so adding read-only logic seems trivial. > > Did I miss anything? > Feedback? OK? > > This applies cleanly to -current but conflicts with the -c/cpath diff > on tech@, so one needs rebasing after the other lands. > > Index: tftpd.8 > =================================================================== > RCS file: /cvs/src/usr.sbin/tftpd/tftpd.8,v > retrieving revision 1.8 > diff -u -p -r1.8 tftpd.8 > --- tftpd.8 4 Mar 2019 01:06:03 -0000 1.8 > +++ tftpd.8 1 Oct 2022 17:30:27 -0000 > @@ -37,7 +37,7 @@ > .Nd Trivial File Transfer Protocol daemon > .Sh SYNOPSIS > .Nm tftpd > -.Op Fl 46cdiv > +.Op Fl 46cdivR > .Op Fl l Ar address > .Op Fl p Ar port > .Op Fl r Ar socket > @@ -56,6 +56,8 @@ will allow only publicly readable files > Files may be written only if they already exist and are publicly writable, > unless the > .Fl c > +or > +.Fl R > flag is specified > .Pq see below . > Note that this extends the concept of > @@ -145,6 +147,8 @@ to > on startup; > the remote host is not expected to pass the directory > as part of the file name to transfer. > +.Fl R > +Prevent creating or writing to files. > .El > .Sh SEE ALSO > .Xr tftp 1 , > Index: tftpd.c > =================================================================== > RCS file: /cvs/src/usr.sbin/tftpd/tftpd.c,v > retrieving revision 1.47 > diff -u -p -r1.47 tftpd.c > --- tftpd.c 24 Oct 2021 21:24:19 -0000 1.47 > +++ tftpd.c 2 Oct 2022 18:12:25 -0000 > @@ -289,6 +289,7 @@ usage(void) > } > > int cancreate = 0; > +int readonly = 0; > int verbose = 0; > int debug = 0; > int iflag = 0; > @@ -309,7 +310,7 @@ main(int argc, char *argv[]) > int family = AF_UNSPEC; > int devnull = -1; > > - while ((c = getopt(argc, argv, "46cdil:p:r:v")) != -1) { > + while ((c = getopt(argc, argv, "46cdil:p:r:vR")) != -1) { > switch (c) { > case '4': > family = AF_INET; > @@ -342,6 +343,9 @@ main(int argc, char *argv[]) > case 'v': > verbose = 1; > break; > + case 'R': > + readonly = 1; > + break; > default: > usage(); > /* NOTREACHED */ > @@ -351,6 +355,9 @@ main(int argc, char *argv[]) > argc -= optind; > argv += optind; > > + if (cancreate && readonly) > + errx(1, "options -c and -R are incompatible"); > + > if (argc != 1) > usage(); > > @@ -391,8 +398,13 @@ main(int argc, char *argv[]) > if (!debug && rdaemon(devnull) == -1) > err(1, "unable to daemonize"); > > - if (pledge("stdio rpath wpath cpath fattr dns inet", NULL) == -1) > - lerr(1, "pledge"); > + if (readonly) { > + if (pledge("stdio rpath dns inet", NULL) == -1) > + lerr(1, "pledge"); > + } else { > + if (pledge("stdio rpath wpath cpath fattr dns inet", NULL) == > -1) > + lerr(1, "pledge"); > + } > > event_init(); > > @@ -964,6 +976,9 @@ validate_access(struct tftp_client *clie > int fd, wmode; > const char *errstr, *filename; > char rewritten[PATH_MAX]; > + > + if (readonly && mode != RRQ) > + return (EACCESS); > > if (strcmp(requested, SEEDPATH) == 0) { > char *buf; >