Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F98933912
D45871.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D45871.diff
View Options
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -680,28 +680,27 @@
int
validate_access(int peer, char **filep, int mode)
{
- struct stat stbuf;
- int fd;
- int error;
- struct dirlist *dirp;
static char pathname[MAXPATHLEN];
+ struct stat sb;
+ struct dirlist *dirp;
char *filename = *filep;
+ int err, fd;
/*
* Prevent tricksters from getting around the directory restrictions
*/
- if (strstr(filename, "/../"))
+ if (strncmp(filename, "../", 3) == 0 ||
+ strstr(filename, "/../") != NULL)
return (EACCESS);
if (*filename == '/') {
/*
- * Allow the request if it's in one of the approved locations.
- * Special case: check the null prefix ("/") by looking
- * for length = 1 and relying on the arg. processing that
- * it's a /.
+ * Absolute file name: allow the request if it's in one of the
+ * approved locations.
*/
for (dirp = dirs; dirp->name != NULL; dirp++) {
if (dirp->len == 1)
+ /* Only "/" can have len 1 */
break;
if (strncmp(filename, dirp->name, dirp->len) == 0 &&
filename[dirp->len] == '/')
@@ -710,30 +709,20 @@
/* If directory list is empty, allow access to any file */
if (dirp->name == NULL && dirp != dirs)
return (EACCESS);
- if (stat(filename, &stbuf) < 0)
+ if (stat(filename, &sb) != 0)
return (errno == ENOENT ? ENOTFOUND : EACCESS);
- if ((stbuf.st_mode & S_IFMT) != S_IFREG)
+ if (!S_ISREG(sb.st_mode))
return (ENOTFOUND);
if (mode == RRQ) {
- if ((stbuf.st_mode & S_IROTH) == 0)
+ if ((sb.st_mode & S_IROTH) == 0)
return (EACCESS);
} else {
- if (check_woth && ((stbuf.st_mode & S_IWOTH) == 0))
+ if (check_woth && (sb.st_mode & S_IWOTH) == 0)
return (EACCESS);
}
} else {
- int err;
-
/*
* Relative file name: search the approved locations for it.
- * Don't allow write requests that avoid directory
- * restrictions.
- */
-
- if (!strncmp(filename, "../", 3))
- return (EACCESS);
-
- /*
* If the file exists in one of the directories and isn't
* readable, continue looking. However, change the error code
* to give an indication that the file exists.
@@ -741,18 +730,20 @@
err = ENOTFOUND;
for (dirp = dirs; dirp->name != NULL; dirp++) {
snprintf(pathname, sizeof(pathname), "%s/%s",
- dirp->name, filename);
- if (stat(pathname, &stbuf) == 0 &&
- (stbuf.st_mode & S_IFMT) == S_IFREG) {
- if (mode == RRQ) {
- if ((stbuf.st_mode & S_IROTH) != 0)
- break;
- } else {
- if (!check_woth || ((stbuf.st_mode & S_IWOTH) != 0))
- break;
- }
- err = EACCESS;
+ dirp->name, filename);
+ if (stat(pathname, &sb) != 0)
+ continue;
+ if (!S_ISREG(sb.st_mode))
+ continue;
+ err = EACCESS;
+ if (mode == RRQ) {
+ if ((sb.st_mode & S_IROTH) == 0)
+ continue;
+ } else {
+ if (check_woth && (sb.st_mode & S_IWOTH) == 0)
+ continue;
}
+ break;
}
if (dirp->name != NULL)
*filep = filename = pathname;
@@ -766,27 +757,27 @@
* This option is handled here because it (might) require(s) the
* size of the file.
*/
- option_tsize(peer, NULL, mode, &stbuf);
+ option_tsize(peer, NULL, mode, &sb);
- if (mode == RRQ)
+ if (mode == RRQ) {
fd = open(filename, O_RDONLY);
- else {
- if (create_new) {
- if (increase_name) {
- error = find_next_name(filename, &fd);
- if (error > 0)
- return (error + 100);
- } else
- fd = open(filename,
- O_WRONLY | O_TRUNC | O_CREAT,
- S_IRUSR | S_IWUSR | S_IRGRP |
- S_IWGRP | S_IROTH | S_IWOTH );
- } else
- fd = open(filename, O_WRONLY | O_TRUNC);
+ } else if (create_new) {
+ if (increase_name) {
+ err = find_next_name(filename, &fd);
+ if (err > 0)
+ return (err + 100);
+ } else {
+ fd = open(filename,
+ O_WRONLY | O_TRUNC | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP |
+ S_IWGRP | S_IROTH | S_IWOTH );
+ }
+ } else {
+ fd = open(filename, O_WRONLY | O_TRUNC);
}
if (fd < 0)
return (errno + 100);
- file = fdopen(fd, (mode == RRQ)? "r":"w");
+ file = fdopen(fd, mode == RRQ ? "r" : "w");
if (file == NULL) {
close(fd);
return (errno + 100);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 6, 9:27 AM (22 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13719956
Default Alt Text
D45871.diff (4 KB)
Attached To
Mode
D45871: tftpd: Code cleanup.
Attached
Detach File
Event Timeline
Log In to Comment