| Summary: | FreeBSD-SA-01:40 | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Eugene Grosbein <ports> | ||||
| Component: | bin | Assignee: | Warner Losh <imp> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 3.5-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
Eugene Grosbein
2001-06-07 05:00:16 UTC
On Thu, Jun 07, 2001 at 11:52:13AM +0800, eugen@grosbein.pp.ru wrote: > >Environment: > FreeBSD 3.5-STABLE i386 > > >Description: > > A patch in FreeBSD Security Advisory FreeBSD-SA-01:40 does not apply to > 3.5-STABLE. Here is a path from advisory adopted for RELENG_3 at the time of > advisory issue. > > >How-To-Repeat: > > Exploit has been posted to security@freebsd.org mailing list. > RELENG_3 branch declared to support ONLY fixes of remote exploits (see http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3320+0+archive/2001/ freebsd-announce/20010513.freebsd-announce). Bye, Serg N. Voronkov. > > A patch in FreeBSD Security Advisory FreeBSD-SA-01:40 does not apply to
> > 3.5-STABLE. Here is a path from advisory adopted for RELENG_3 at the time of
> > advisory issue.
> >
> > >How-To-Repeat:
> >
> > Exploit has been posted to security@freebsd.org mailing list.
> >
>
> RELENG_3 branch declared to support ONLY fixes of remote exploits (see
> http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3320+0+archive/2001/
> freebsd-announce/20010513.freebsd-announce).
I know. It was said, if someone will supply patches for RELENG_3, they will
be consideted, so I corrected the patch.
Eugene Grosbein
Responsible Changed From-To: freebsd-bugs->security-officer Let's see if this works :) Responsible Changed From-To: security-officer->imp Since someone went to the trouble of doing the patch, I'll try it with my 3.5 tree and commit it if things compile after auditing the contents of the patch. > @@ -1086,7 +1087,7 @@
> newfd = fd;
> if (ISSET(FTS_NOCHDIR))
> return (0);
> - if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
> + if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
> return (-1);
> if (fstat(newfd, &sb)) {
> ret = -1;
I'm very sorry but this patch breaks libc_r on 3.5-STABLE.
The use of missing _open() is incorrect here, it needs to be changed back
to open(). With this one-line change the patch looks like this:
--- fts.c.orig Sat Dec 25 15:29:45 1999
+++ fts.c Wed Jun 13 16:17:28 2001
@@ -61,7 +61,7 @@
static int fts_palloc __P((FTS *, size_t));
static FTSENT *fts_sort __P((FTS *, FTSENT *, int));
static u_short fts_stat __P((FTS *, FTSENT *, int));
-static int fts_safe_changedir __P((FTS *, FTSENT *, int));
+static int fts_safe_changedir __P((FTS *, FTSENT *, int, char *));
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' &&
!a[2])))
@@ -69,7 +69,6 @@
#define ISSET(opt) (sp->fts_options & (opt))
#define SET(opt) (sp->fts_options |= (opt))
-#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
/* fts_build flags */
@@ -273,6 +272,7 @@
fts_read(sp)
register FTS *sp;
{
+ struct stat sb;
register FTSENT *p, *tmp;
register int instr;
register char *t;
@@ -349,7 +349,7 @@
* FTS_STOP or the fts_info field of the node.
*/
if (sp->fts_child) {
- if (fts_safe_changedir(sp, p, -1)) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
p->fts_errno = errno;
p->fts_flags |= FTS_DONTCHDIR;
for (p = sp->fts_child; p; p = p->fts_link)
@@ -446,11 +446,10 @@
return (NULL);
}
(void)close(p->fts_symfd);
- } else if (!(p->fts_flags & FTS_DONTCHDIR)) {
- if (CHDIR(sp, "..")) {
- SET(FTS_STOP);
- return (NULL);
- }
+ } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
+ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
}
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
return (sp->fts_cur = p);
@@ -637,7 +636,7 @@
*/
cderrno = 0;
if (nlinks || type == BREAD) {
- if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
if (nlinks && type == BREAD)
cur->fts_errno = errno;
cur->fts_flags |= FTS_DONTCHDIR;
@@ -803,7 +802,8 @@
*/
if (descend && (type == BCHILD || !nitems) &&
(cur->fts_level == FTS_ROOTLEVEL ?
- FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+ FCHDIR(sp, sp->fts_rfd) :
+ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
return (NULL);
@@ -1075,10 +1075,11 @@
* Assumes p->fts_dev and p->fts_ino are filled in.
*/
static int
-fts_safe_changedir(sp, p, fd)
+fts_safe_changedir(sp, p, fd, path)
FTS *sp;
FTSENT *p;
int fd;
+ char *path;
{
int ret, oerrno, newfd;
struct stat sb;
@@ -1086,7 +1087,7 @@
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
+ if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
return (-1);
if (fstat(newfd, &sb)) {
ret = -1;
Eugene Grosbein
State Changed From-To: open->closed fix committed to RELENG_3 |