Mercurial > dovecot > core-2.2
changeset 1082:c62416017121 HEAD
make sure we don't access free'd memory if auth process dies.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 02 Feb 2003 11:45:07 +0200 |
parents | 98dca3b6b209 |
children | f6ec28683512 |
files | src/login-common/auth-connection.c src/login-common/auth-connection.h |
diffstat | 2 files changed, 43 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/auth-connection.c Sun Feb 02 11:30:18 2003 +0200 +++ b/src/login-common/auth-connection.c Sun Feb 02 11:45:07 2003 +0200 @@ -27,6 +27,8 @@ static struct timeout *to; static void auth_connection_destroy(struct auth_connection *conn); +static void auth_connection_unref(struct auth_connection *conn); + static void auth_input(void *context); static void auth_connect_missing(void); @@ -59,6 +61,7 @@ net_set_nonblock(fd, FALSE); conn = i_new(struct auth_connection, 1); + conn->refcount = 1; conn->path = i_strdup(path); conn->fd = fd; conn->io = io_add(fd, IO_READ, auth_input, conn); @@ -88,12 +91,19 @@ i_free(request); } +static void request_hash_remove(void *key __attr_unused__, void *value, + void *context __attr_unused__) +{ + struct auth_request *request = value; + + request->callback(request, NULL, NULL, request->context); +} + static void request_hash_destroy(void *key __attr_unused__, void *value, void *context __attr_unused__) { struct auth_request *request = value; - request->callback(request, NULL, NULL, request->context); request_destroy(request); } @@ -101,6 +111,9 @@ { struct auth_connection **pos; + if (conn->fd == -1) + return; + for (pos = &auth_connections; *pos != NULL; pos = &(*pos)->next) { if (*pos == conn) { *pos = conn->next; @@ -108,12 +121,24 @@ } } + if (close(conn->fd) < 0) + i_error("close(auth) failed: %m"); + io_remove(conn->io); + conn->fd = -1; + + hash_foreach(conn->requests, request_hash_remove, NULL); + + auth_connection_unref(conn); +} + +static void auth_connection_unref(struct auth_connection *conn) +{ + if (--conn->refcount > 0) + return; + hash_foreach(conn->requests, request_hash_destroy, NULL); hash_destroy(conn->requests); - if (close(conn->fd) < 0) - i_error("close(auth) failed: %m"); - io_remove(conn->io); i_stream_unref(conn->input); o_stream_unref(conn->output); i_free(conn->path); @@ -309,6 +334,16 @@ request_destroy(request); } +void auth_request_ref(struct auth_request *request) +{ + request->conn->refcount++; +} + +void auth_request_unref(struct auth_request *request) +{ + auth_connection_unref(request->conn); +} + static void auth_connect_missing(void) { DIR *dirp;
--- a/src/login-common/auth-connection.h Sun Feb 02 11:30:18 2003 +0200 +++ b/src/login-common/auth-connection.h Sun Feb 02 11:45:07 2003 +0200 @@ -11,6 +11,7 @@ struct auth_connection { struct auth_connection *next; + int refcount; char *path; int fd; @@ -50,6 +51,9 @@ void auth_abort_request(struct auth_request *request); +void auth_request_ref(struct auth_request *request); +void auth_request_unref(struct auth_request *request); + void auth_connection_init(void); void auth_connection_deinit(void);