fcache: prevent null pointer dereference

Validate krb5_ccache and krb5_cc_cursor inputs
before use.  Avoid null pointer dereference which
can occur if an application fails to properly check
return codes.

Change-Id: I8023808936e60cc7b8e57a062106cfcdc51ee7d7
This commit is contained in:
Jeffrey Altman
2011-05-18 10:00:31 -04:00
parent 305596d9ad
commit 18b76b6236

View File

@@ -62,6 +62,9 @@ static const char* KRB5_CALLCONV
fcc_get_name(krb5_context context, fcc_get_name(krb5_context context,
krb5_ccache id) krb5_ccache id)
{ {
if (FCACHE(id) == NULL)
return NULL;
return FILENAME(id); return FILENAME(id);
} }
@@ -383,8 +386,14 @@ fcc_open(krb5_context context,
krb5_boolean exclusive = ((flags | O_WRONLY) == flags || krb5_boolean exclusive = ((flags | O_WRONLY) == flags ||
(flags | O_RDWR) == flags); (flags | O_RDWR) == flags);
krb5_error_code ret; krb5_error_code ret;
const char *filename = FILENAME(id); const char *filename;
int fd; int fd;
if (FCACHE(id) == NULL)
return EINVAL;
filename = FILENAME(id);
fd = open(filename, flags, mode); fd = open(filename, flags, mode);
if(fd < 0) { if(fd < 0) {
char buf[128]; char buf[128];
@@ -412,9 +421,11 @@ fcc_initialize(krb5_context context,
krb5_fcache *f = FCACHE(id); krb5_fcache *f = FCACHE(id);
int ret = 0; int ret = 0;
int fd; int fd;
char *filename = f->filename;
unlink (filename); if (f == NULL)
return EINVAL;
unlink (f->filename);
ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600); ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600);
if(ret) if(ret)
@@ -464,6 +475,9 @@ static krb5_error_code KRB5_CALLCONV
fcc_close(krb5_context context, fcc_close(krb5_context context,
krb5_ccache id) krb5_ccache id)
{ {
if (FCACHE(id) == NULL)
return EINVAL;
free (FILENAME(id)); free (FILENAME(id));
krb5_data_free(&id->data); krb5_data_free(&id->data);
return 0; return 0;
@@ -473,6 +487,9 @@ static krb5_error_code KRB5_CALLCONV
fcc_destroy(krb5_context context, fcc_destroy(krb5_context context,
krb5_ccache id) krb5_ccache id)
{ {
if (FCACHE(id) == NULL)
return EINVAL;
_krb5_erase_file(context, FILENAME(id)); _krb5_erase_file(context, FILENAME(id));
return 0; return 0;
} }
@@ -701,6 +718,9 @@ fcc_get_first (krb5_context context,
krb5_error_code ret; krb5_error_code ret;
krb5_principal principal; krb5_principal principal;
if (FCACHE(id) == NULL)
return EINVAL;
*cursor = malloc(sizeof(struct fcc_cursor)); *cursor = malloc(sizeof(struct fcc_cursor));
if (*cursor == NULL) { if (*cursor == NULL) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
@@ -733,6 +753,13 @@ fcc_get_next (krb5_context context,
krb5_creds *creds) krb5_creds *creds)
{ {
krb5_error_code ret; krb5_error_code ret;
if (FCACHE(id) == NULL)
return EINVAL;
if (FCC_CURSOR(*cursor) == NULL)
return EINVAL;
if((ret = fcc_lock(context, id, FCC_CURSOR(*cursor)->fd, FALSE)) != 0) if((ret = fcc_lock(context, id, FCC_CURSOR(*cursor)->fd, FALSE)) != 0)
return ret; return ret;
@@ -749,6 +776,13 @@ fcc_end_get (krb5_context context,
krb5_ccache id, krb5_ccache id,
krb5_cc_cursor *cursor) krb5_cc_cursor *cursor)
{ {
if (FCACHE(id) == NULL)
return EINVAL;
if (FCC_CURSOR(*cursor) == NULL)
return EINVAL;
krb5_storage_free(FCC_CURSOR(*cursor)->sp); krb5_storage_free(FCC_CURSOR(*cursor)->sp);
close (FCC_CURSOR(*cursor)->fd); close (FCC_CURSOR(*cursor)->fd);
free(*cursor); free(*cursor);
@@ -767,6 +801,9 @@ fcc_remove_cred(krb5_context context,
char *newname = NULL; char *newname = NULL;
int fd; int fd;
if (FCACHE(id) == NULL)
return EINVAL;
ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &copy); ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &copy);
if (ret) if (ret)
return ret; return ret;
@@ -827,6 +864,9 @@ fcc_set_flags(krb5_context context,
krb5_ccache id, krb5_ccache id,
krb5_flags flags) krb5_flags flags)
{ {
if (FCACHE(id) == NULL)
return EINVAL;
return 0; /* XXX */ return 0; /* XXX */
} }
@@ -834,6 +874,9 @@ static int KRB5_CALLCONV
fcc_get_version(krb5_context context, fcc_get_version(krb5_context context,
krb5_ccache id) krb5_ccache id)
{ {
if (FCACHE(id) == NULL)
return -1;
return FCACHE(id)->version; return FCACHE(id)->version;
} }
@@ -864,6 +907,9 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
const char *fn; const char *fn;
char *expandedfn = NULL; char *expandedfn = NULL;
if (iter == NULL)
return EINVAL;
if (!iter->first) { if (!iter->first) {
krb5_clear_error_message(context); krb5_clear_error_message(context);
return KRB5_CC_END; return KRB5_CC_END;
@@ -900,6 +946,10 @@ static krb5_error_code KRB5_CALLCONV
fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
{ {
struct fcache_iter *iter = cursor; struct fcache_iter *iter = cursor;
if (iter == NULL)
return EINVAL;
free(iter); free(iter);
return 0; return 0;
} }