NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: bin/43164 (tftpd: file upload broken)
The following reply was made to PR bin/43164; it has been noted by GNATS.
From: Hubert Feyrer <hubert%feyrer.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Fri, 16 Apr 2010 22:41:54 +0200 (CEST)
Updated patch (V2):
Currently, file uploads require files to exist.
Allow file upload without that restriction if option -w is used.
Document with hint at proper security precautions.
Patch applies to netbsd-4 and netbsd-5 branch as of 20100414.
- Hubert Feyrer <hubert%feyrer.de@localhost>
Index: tftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
retrieving revision 1.31
diff -u -r1.31 tftpd.c
--- tftpd.c 21 Jul 2008 13:25:47 -0000 1.31
+++ tftpd.c 16 Apr 2010 20:35:11 -0000
@@ -108,6 +108,7 @@
static int logging;
static int secure;
static char *securedir;
+static int unrestricted_writes; /* uploaded files don't have to exist */
struct formats;
@@ -170,7 +171,7 @@
curuid = getuid();
curgid = getgid();
- while ((ch = getopt(argc, argv, "dg:lns:u:")) != -1)
+ while ((ch = getopt(argc, argv, "dg:lns:u:w")) != -1)
switch (ch) {
case 'd':
debug++;
@@ -197,6 +198,10 @@
tgtuser = optarg;
break;
+ case 'w':
+ unrestricted_writes = 1;
+ break;
+
default:
usage();
break;
@@ -722,6 +727,8 @@
static char pathname[MAXPATHLEN];
char *filename;
int fd;
+ int creat=0;
+ int trunc=0;
filename = *filep;
@@ -787,21 +794,46 @@
return (EACCESS);
*filep = filename = pathname;
} else {
+ int stat_rc;
+
/*
* If there's no directory list, take our cue from the
* absolute file request check above (*filename == '/'),
* and allow access to anything.
*/
- if (stat(filename, &stbuf) < 0)
- return (errno == ENOENT ? ENOTFOUND : EACCESS);
- if (!S_ISREG(stbuf.st_mode))
- return (ENOTFOUND);
+ stat_rc = stat(filename, &stbuf);
if (mode == RRQ) {
+ /* Read request */
+ if (stat_rc < 0)
+ return (errno == ENOENT ? ENOTFOUND :
EACCESS);
+ if (!S_ISREG(stbuf.st_mode))
+ return (ENOTFOUND);
if ((stbuf.st_mode & S_IROTH) == 0)
return (EACCESS);
} else {
- if ((stbuf.st_mode & S_IWOTH) == 0)
- return (EACCESS);
+ /* Write request */
+ if (stat_rc < 0) {
+ /* Can't stat */
+ if (errno == EACCES) {
+ /* Permission denied */
+ return EACCESS;
+ } else {
+ /* Not there */
+ if (unrestricted_writes) {
+ /* need to creat new
file! */
+ creat = O_CREAT;
+ } else {
+ /* Permission denied */
+ return EACCESS;
+ }
+ }
+ } else {
+ /* Can stat */
+ if ((stbuf.st_mode & S_IWOTH) == 0) {
+ return (EACCESS);
+ }
+ trunc = O_TRUNC;
+ }
}
*filep = filename;
}
@@ -810,9 +842,10 @@
if (tftp_opt_tsize && mode == RRQ)
tftp_tsize = (unsigned long) stbuf.st_size;
- fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | O_TRUNC);
- if (fd < 0)
+ fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | trunc | creat,
0644); /*644=debatable... maybe 646? or 004? or 006, so the file can be
overwritten? */
+ if (fd < 0) {
return (errno + 100);
+ }
file = fdopen(fd, (mode == RRQ)? "r":"w");
if (file == NULL) {
close(fd);
Index: tftpd.8
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.8,v
retrieving revision 1.21
diff -u -r1.21 tftpd.8
--- tftpd.8 7 Aug 2003 09:46:53 -0000 1.21
+++ tftpd.8 16 Apr 2010 20:35:11 -0000
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)tftpd.8 8.1 (Berkeley) 6/4/93
.\"
-.Dd June 11, 2003
+.Dd April 16, 2010
.Dt TFTPD 8
.Os
.Sh NAME
@@ -45,6 +45,7 @@
.Op Fl n
.Op Fl s Ar directory
.Op Fl u Ar user
+.Op Fl w
.Op Ar directory ...
.Sh DESCRIPTION
.Nm
@@ -68,7 +69,10 @@
will allow only publicly readable files to be accessed.
Filenames beginning in ``\|\fB.\|.\fP\|/'' or
containing ``/\|\fB.\|.\fP\|/'' are not allowed.
-Files may be written to only if they already exist and are publicly writable.
+Unless option
+.Fl w
+is used,
+files may be written to only if they already exist and are publicly writable.
.Pp
Note that this extends the concept of
.Qq public
@@ -141,6 +145,9 @@
isn't also given, change the gid to that of
.Ar user
as well.
+.Fl w
+Allow unrestricted writing of new files, with no need for
+a prior existance.
.El
.Sh SEE ALSO
.Xr tftp 1 ,
@@ -220,3 +227,9 @@
sort of file-access restrictions in place.
The exact methods are specific to each site and therefore
difficult to document here.
+.Pp
+If unrestricted file upload is enabled via the
+.Fl w
+option, care should be taken that this can be used
+to fill up disk space in an uncontrolled manner
+if this is used in an insecure environment.
Home |
Main Index |
Thread Index |
Old Index