diff options
| author | Ryan Mallon <rmallon@gmail.com> | 2014-01-09 19:14:07 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-01-09 19:15:16 +0100 |
| commit | 89deb22f9745e145fdbb4fbe985cfa9e20e90024 (patch) | |
| tree | 3205c4004d321fddd0ad6dc4eba80bebd6e87afa | |
| parent | 16ca379b55eb5dc1cacfaabf4ca026c49fb516bd (diff) | |
| download | busybox-w32-89deb22f9745e145fdbb4fbe985cfa9e20e90024.tar.gz busybox-w32-89deb22f9745e145fdbb4fbe985cfa9e20e90024.tar.bz2 busybox-w32-89deb22f9745e145fdbb4fbe985cfa9e20e90024.zip | |
fakeidentd: fix use-after-free
function old new delta
do_rd 199 197 -2
Signed-off-by: Ryan Mallon <rmallon@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/isrv_identd.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/networking/isrv_identd.c b/networking/isrv_identd.c index a41405c33..c6b0f6528 100644 --- a/networking/isrv_identd.c +++ b/networking/isrv_identd.c | |||
| @@ -51,19 +51,18 @@ static int do_rd(int fd, void **paramp) | |||
| 51 | { | 51 | { |
| 52 | identd_buf_t *buf = *paramp; | 52 | identd_buf_t *buf = *paramp; |
| 53 | char *cur, *p; | 53 | char *cur, *p; |
| 54 | int retval = 0; /* session is ok (so far) */ | ||
| 55 | int sz; | 54 | int sz; |
| 56 | 55 | ||
| 57 | cur = buf->buf + buf->pos; | 56 | cur = buf->buf + buf->pos; |
| 58 | 57 | ||
| 59 | if (buf->fd_flag & O_NONBLOCK) | 58 | if (buf->fd_flag & O_NONBLOCK) |
| 60 | fcntl(fd, F_SETFL, buf->fd_flag); | 59 | fcntl(fd, F_SETFL, buf->fd_flag); |
| 61 | sz = safe_read(fd, cur, sizeof(buf->buf) - buf->pos); | 60 | sz = safe_read(fd, cur, sizeof(buf->buf) - 1 - buf->pos); |
| 62 | 61 | ||
| 63 | if (sz < 0) { | 62 | if (sz < 0) { |
| 64 | if (errno != EAGAIN) | 63 | if (errno != EAGAIN) |
| 65 | goto term; /* terminate this session if !EAGAIN */ | 64 | goto term; |
| 66 | goto ok; | 65 | return 0; /* "session is ok" */ |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | buf->pos += sz; | 68 | buf->pos += sz; |
| @@ -71,19 +70,19 @@ static int do_rd(int fd, void **paramp) | |||
| 71 | p = strpbrk(cur, "\r\n"); | 70 | p = strpbrk(cur, "\r\n"); |
| 72 | if (p) | 71 | if (p) |
| 73 | *p = '\0'; | 72 | *p = '\0'; |
| 74 | if (!p && sz && buf->pos <= (int)sizeof(buf->buf)) | 73 | if (!p && sz && buf->pos < (int)sizeof(buf->buf)) |
| 75 | goto ok; | 74 | return 0; /* "session is ok" */ |
| 75 | |||
| 76 | /* Terminate session. If we are in server mode, then | 76 | /* Terminate session. If we are in server mode, then |
| 77 | * fd is still in nonblocking mode - we never block here */ | 77 | * fd is still in nonblocking mode - we never block here */ |
| 78 | if (fd == 0) fd++; /* inetd mode? then write to fd 1 */ | 78 | if (fd == 0) |
| 79 | fd++; /* inetd mode? then write to fd 1 */ | ||
| 79 | fdprintf(fd, "%s : USERID : UNIX : %s\r\n", buf->buf, bogouser); | 80 | fdprintf(fd, "%s : USERID : UNIX : %s\r\n", buf->buf, bogouser); |
| 80 | term: | ||
| 81 | free(buf); | ||
| 82 | retval = 1; /* terminate */ | ||
| 83 | ok: | ||
| 84 | if (buf->fd_flag & O_NONBLOCK) | 81 | if (buf->fd_flag & O_NONBLOCK) |
| 85 | fcntl(fd, F_SETFL, buf->fd_flag & ~O_NONBLOCK); | 82 | fcntl(fd, F_SETFL, buf->fd_flag & ~O_NONBLOCK); |
| 86 | return retval; | 83 | term: |
| 84 | free(buf); | ||
| 85 | return 1; /* "terminate" */ | ||
| 87 | } | 86 | } |
| 88 | 87 | ||
| 89 | static int do_timeout(void **paramp UNUSED_PARAM) | 88 | static int do_timeout(void **paramp UNUSED_PARAM) |
| @@ -120,7 +119,7 @@ int fakeidentd_main(int argc UNUSED_PARAM, char **argv) | |||
| 120 | opt = getopt32(argv, "fiwb:", &bind_address); | 119 | opt = getopt32(argv, "fiwb:", &bind_address); |
| 121 | strcpy(bogouser, "nobody"); | 120 | strcpy(bogouser, "nobody"); |
| 122 | if (argv[optind]) | 121 | if (argv[optind]) |
| 123 | strncpy(bogouser, argv[optind], sizeof(bogouser)); | 122 | strncpy(bogouser, argv[optind], sizeof(bogouser) - 1); |
| 124 | 123 | ||
| 125 | /* Daemonize if no -f and no -i and no -w */ | 124 | /* Daemonize if no -f and no -i and no -w */ |
| 126 | if (!(opt & OPT_fiw)) | 125 | if (!(opt & OPT_fiw)) |
