mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-25 01:55:19 +01:00
Merge branch 'freebsd/current/main' into hardened/current/master
This commit is contained in:
commit
ccd44b020a
@ -680,28 +680,27 @@ find_next_name(char *filename, int *fd)
|
|||||||
int
|
int
|
||||||
validate_access(int peer, char **filep, int mode)
|
validate_access(int peer, char **filep, int mode)
|
||||||
{
|
{
|
||||||
struct stat stbuf;
|
|
||||||
int fd;
|
|
||||||
int error;
|
|
||||||
struct dirlist *dirp;
|
|
||||||
static char pathname[MAXPATHLEN];
|
static char pathname[MAXPATHLEN];
|
||||||
|
struct stat sb;
|
||||||
|
struct dirlist *dirp;
|
||||||
char *filename = *filep;
|
char *filename = *filep;
|
||||||
|
int err, fd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent tricksters from getting around the directory restrictions
|
* Prevent tricksters from getting around the directory restrictions
|
||||||
*/
|
*/
|
||||||
if (strstr(filename, "/../"))
|
if (strncmp(filename, "../", 3) == 0 ||
|
||||||
|
strstr(filename, "/../") != NULL)
|
||||||
return (EACCESS);
|
return (EACCESS);
|
||||||
|
|
||||||
if (*filename == '/') {
|
if (*filename == '/') {
|
||||||
/*
|
/*
|
||||||
* Allow the request if it's in one of the approved locations.
|
* Absolute file name: allow the request if it's in one of the
|
||||||
* Special case: check the null prefix ("/") by looking
|
* approved locations.
|
||||||
* for length = 1 and relying on the arg. processing that
|
|
||||||
* it's a /.
|
|
||||||
*/
|
*/
|
||||||
for (dirp = dirs; dirp->name != NULL; dirp++) {
|
for (dirp = dirs; dirp->name != NULL; dirp++) {
|
||||||
if (dirp->len == 1)
|
if (dirp->len == 1)
|
||||||
|
/* Only "/" can have len 1 */
|
||||||
break;
|
break;
|
||||||
if (strncmp(filename, dirp->name, dirp->len) == 0 &&
|
if (strncmp(filename, dirp->name, dirp->len) == 0 &&
|
||||||
filename[dirp->len] == '/')
|
filename[dirp->len] == '/')
|
||||||
@ -710,30 +709,20 @@ validate_access(int peer, char **filep, int mode)
|
|||||||
/* If directory list is empty, allow access to any file */
|
/* If directory list is empty, allow access to any file */
|
||||||
if (dirp->name == NULL && dirp != dirs)
|
if (dirp->name == NULL && dirp != dirs)
|
||||||
return (EACCESS);
|
return (EACCESS);
|
||||||
if (stat(filename, &stbuf) < 0)
|
if (stat(filename, &sb) != 0)
|
||||||
return (errno == ENOENT ? ENOTFOUND : EACCESS);
|
return (errno == ENOENT ? ENOTFOUND : EACCESS);
|
||||||
if ((stbuf.st_mode & S_IFMT) != S_IFREG)
|
if (!S_ISREG(sb.st_mode))
|
||||||
return (ENOTFOUND);
|
return (ENOTFOUND);
|
||||||
if (mode == RRQ) {
|
if (mode == RRQ) {
|
||||||
if ((stbuf.st_mode & S_IROTH) == 0)
|
if ((sb.st_mode & S_IROTH) == 0)
|
||||||
return (EACCESS);
|
return (EACCESS);
|
||||||
} else {
|
} else {
|
||||||
if (check_woth && ((stbuf.st_mode & S_IWOTH) == 0))
|
if (check_woth && (sb.st_mode & S_IWOTH) == 0)
|
||||||
return (EACCESS);
|
return (EACCESS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Relative file name: search the approved locations for it.
|
* 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
|
* If the file exists in one of the directories and isn't
|
||||||
* readable, continue looking. However, change the error code
|
* readable, continue looking. However, change the error code
|
||||||
* to give an indication that the file exists.
|
* to give an indication that the file exists.
|
||||||
@ -741,18 +730,20 @@ validate_access(int peer, char **filep, int mode)
|
|||||||
err = ENOTFOUND;
|
err = ENOTFOUND;
|
||||||
for (dirp = dirs; dirp->name != NULL; dirp++) {
|
for (dirp = dirs; dirp->name != NULL; dirp++) {
|
||||||
snprintf(pathname, sizeof(pathname), "%s/%s",
|
snprintf(pathname, sizeof(pathname), "%s/%s",
|
||||||
dirp->name, filename);
|
dirp->name, filename);
|
||||||
if (stat(pathname, &stbuf) == 0 &&
|
if (stat(pathname, &sb) != 0)
|
||||||
(stbuf.st_mode & S_IFMT) == S_IFREG) {
|
continue;
|
||||||
if (mode == RRQ) {
|
if (!S_ISREG(sb.st_mode))
|
||||||
if ((stbuf.st_mode & S_IROTH) != 0)
|
continue;
|
||||||
break;
|
err = EACCESS;
|
||||||
} else {
|
if (mode == RRQ) {
|
||||||
if (!check_woth || ((stbuf.st_mode & S_IWOTH) != 0))
|
if ((sb.st_mode & S_IROTH) == 0)
|
||||||
break;
|
continue;
|
||||||
}
|
} else {
|
||||||
err = EACCESS;
|
if (check_woth && (sb.st_mode & S_IWOTH) == 0)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (dirp->name != NULL)
|
if (dirp->name != NULL)
|
||||||
*filep = filename = pathname;
|
*filep = filename = pathname;
|
||||||
@ -766,27 +757,27 @@ validate_access(int peer, char **filep, int mode)
|
|||||||
* This option is handled here because it (might) require(s) the
|
* This option is handled here because it (might) require(s) the
|
||||||
* size of the file.
|
* 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);
|
fd = open(filename, O_RDONLY);
|
||||||
else {
|
} else if (create_new) {
|
||||||
if (create_new) {
|
if (increase_name) {
|
||||||
if (increase_name) {
|
err = find_next_name(filename, &fd);
|
||||||
error = find_next_name(filename, &fd);
|
if (err > 0)
|
||||||
if (error > 0)
|
return (err + 100);
|
||||||
return (error + 100);
|
} else {
|
||||||
} else
|
fd = open(filename,
|
||||||
fd = open(filename,
|
O_WRONLY | O_TRUNC | O_CREAT,
|
||||||
O_WRONLY | O_TRUNC | O_CREAT,
|
S_IRUSR | S_IWUSR | S_IRGRP |
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP |
|
S_IWGRP | S_IROTH | S_IWOTH );
|
||||||
S_IWGRP | S_IROTH | S_IWOTH );
|
}
|
||||||
} else
|
} else {
|
||||||
fd = open(filename, O_WRONLY | O_TRUNC);
|
fd = open(filename, O_WRONLY | O_TRUNC);
|
||||||
}
|
}
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return (errno + 100);
|
return (errno + 100);
|
||||||
file = fdopen(fd, (mode == RRQ)? "r":"w");
|
file = fdopen(fd, mode == RRQ ? "r" : "w");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return (errno + 100);
|
return (errno + 100);
|
||||||
|
Loading…
Reference in New Issue
Block a user