SECURITY HOLE IN tftpd (fix for a fix, sigh..)
lee at unmvax.UUCP
lee at unmvax.UUCP
Fri Sep 28 08:41:57 AEST 1984
The last "fix" I posted neglected to account for symlinks. I still
live in a 4.1 world, I guess.... This one gets the symlinks too.
RCS file: RCS/tftpd.c,v
retrieving revision 1.1
diff -c -r1.1 tftpd.c
*** /tmp/,RCSt1013277 Thu Sep 27 16:40:55 1984
--- tftpd.c Thu Sep 27 16:34:50 1984
***************
*** 188,193
int mode;
{
struct stat stbuf;
if (*file != '/')
return (EACCESS);
--- 188,200 -----
int mode;
{
struct stat stbuf;
+ char *ptr,
+ *lsptr,
+ *eptr,
+ buf[BUFSIZ],
+ tbuf[BUFSIZ];
+ int sret,
+ cc;
(void )chdir("/");
if (*file != '/')
***************
*** 189,194
{
struct stat stbuf;
if (*file != '/')
return (EACCESS);
if (stat(file, &stbuf) < 0)
--- 196,202 -----
int sret,
cc;
+ (void )chdir("/");
if (*file != '/')
return (EACCESS);
/* Check path first */
***************
*** 191,196
if (*file != '/')
return (EACCESS);
if (stat(file, &stbuf) < 0)
return (errno == ENOENT ? ENOTFOUND : EACCESS);
if (mode == RRQ) {
--- 199,245 -----
(void )chdir("/");
if (*file != '/')
return (EACCESS);
+ /* Check path first */
+ eptr = file + strlen(file);
+ lsptr = ptr = file;
+ ptr++;
+ while (ptr < eptr) {
+ if (*ptr++ != '/' && *ptr)
+ continue;
+ if (*ptr) {
+ ptr--;
+ *ptr = NULL;
+ }
+ sret = lstat(file, &stbuf);
+ if (ptr != eptr)
+ *ptr++ = '/';
+ else
+ ptr++;
+ if (sret < 0)
+ return (errno == ENOENT ? ENOTFOUND : EACCESS);
+ if ((stbuf.st_mode&S_IFMT) == S_IFDIR) {
+ if((stbuf.st_mode&(S_IEXEC >> 6)) == 0)
+ return (EACCESS);
+ } else if ((stbuf.st_mode&S_IFMT) == S_IFLNK) {
+ *--ptr = NULL;
+ cc = readlink(file, tbuf, sizeof(tbuf));
+ if (cc < 0)
+ return(errno);
+ tbuf[cc] = NULL;
+ strncat(tbuf, ptr, sizeof(tbuf) - 1 - cc);
+ if (tbuf[0] != '/') {
+ *lsptr = NULL;
+ (void )chdir(file);
+ ptr = buf;
+ } else
+ ptr = &buf[1];
+ strcpy(buf, tbuf);
+ file = buf;
+ eptr = file + strlen(file);
+ } else
+ break;
+ lsptr = ptr - 1;
+ }
if (stat(file, &stbuf) < 0)
return (errno == ENOENT ? ENOTFOUND : EACCESS);
if (mode == RRQ) {
--
--Lee (Ward)
{ucbvax,convex,gatech,pur-ee}!unmvax!lee
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list