From 52571d9201c7bef4dc5ebdf14a41db1f7baddc8e Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Thu, 12 Jul 2007 23:33:25 +0000 Subject: [PATCH] Avoid use of unchecked sprintf in libraries. Use asprintf if the output buffer is allocated according to the size of data to be written, or snprintf otherwise. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19703 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/generic/disp_major_status.c | 7 +-- src/lib/gssapi/mechglue/oid_ops.c | 12 ++--- src/lib/kadm5/alt_prof.c | 21 ++++---- src/lib/kadm5/chpass_util.c | 60 +++++++++++----------- src/lib/kadm5/clnt/client_init.c | 48 ++++++++--------- src/lib/kadm5/logger.c | 14 ++--- src/lib/kadm5/srv/server_kdb.c | 7 ++- src/lib/kdb/kdb5.c | 10 ++-- src/lib/krb4/CCache-glue.c | 2 +- src/lib/krb4/RealmsConfig-glue.c | 2 +- src/lib/krb4/klog.c | 2 +- src/lib/krb4/password_to_key.c | 14 ++--- src/lib/krb4/stime.c | 6 +-- src/lib/krb4/tkt_string.c | 3 +- src/lib/krb5/asn.1/asn1_encode.c | 9 ++-- src/lib/krb5/ccache/ccapi/stdcc.c | 2 +- src/lib/krb5/ccache/ser_cc.c | 12 ++--- src/lib/krb5/ccache/t_cc.c | 7 ++- src/lib/krb5/keytab/kt_file.c | 13 +++-- src/lib/krb5/krb/gic_pwd.c | 48 +++++++++-------- src/lib/krb5/krb/preauth2.c | 44 ++++++++-------- src/lib/krb5/krb/srv_rcache.c | 2 +- src/lib/krb5/krb/str_conv.c | 18 +++---- src/lib/krb5/krb/t_ser.c | 29 ++++++----- src/lib/krb5/os/ccdefname.c | 7 +-- src/lib/krb5/os/dnssrv.c | 6 ++- src/lib/krb5/os/gen_rname.c | 10 ++-- src/lib/krb5/os/hst_realm.c | 3 +- src/lib/krb5/os/ktdefname.c | 2 +- src/lib/krb5/os/locate_kdc.c | 7 ++- src/lib/krb5/os/sendto_kdc.c | 15 +++--- src/lib/krb5/rcache/rc_io.c | 48 +++++++---------- src/lib/krb5/rcache/ser_rc.c | 12 ++--- src/lib/rpc/clnt_perror.c | 55 +++++++++++--------- src/util/profile/prof_file.c | 17 +++--- src/util/support/errors.c | 3 +- src/util/support/plugins.c | 31 +++++------ 37 files changed, 306 insertions(+), 302 deletions(-) diff --git a/src/lib/gssapi/generic/disp_major_status.c b/src/lib/gssapi/generic/disp_major_status.c index 218370d14..0648192a1 100644 --- a/src/lib/gssapi/generic/disp_major_status.c +++ b/src/lib/gssapi/generic/disp_major_status.c @@ -115,11 +115,8 @@ display_unknown(kind, value, buffer) { char *str; - if ((str = - (char *) xmalloc(strlen(unknown_error)+strlen(kind)+7)) == NULL) - return(0); - - sprintf(str, unknown_error, kind, value); + if (asprintf(&str, unknown_error, kind, value) < 0) + return(0); buffer->length = strlen(str); buffer->value = str; diff --git a/src/lib/gssapi/mechglue/oid_ops.c b/src/lib/gssapi/mechglue/oid_ops.c index 5c2ceb321..2dfbfeae7 100644 --- a/src/lib/gssapi/mechglue/oid_ops.c +++ b/src/lib/gssapi/mechglue/oid_ops.c @@ -249,9 +249,9 @@ generic_gss_oid_to_str(minor_status, oid, oid_str) numshift = 0; cp = (unsigned char *) oid->elements; number = (unsigned long) cp[0]; - sprintf(numstr, "%lu ", (unsigned long)number/40); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40); string_length += strlen(numstr); - sprintf(numstr, "%lu ", (unsigned long)number%40); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40); string_length += strlen(numstr); for (i=1; ilength; i++) { if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) {/* XXX */ @@ -262,7 +262,7 @@ generic_gss_oid_to_str(minor_status, oid, oid_str) return(GSS_S_FAILURE); } if ((cp[i] & 0x80) == 0) { - sprintf(numstr, "%lu ", (unsigned long)number); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number); string_length += strlen(numstr); number = 0; numshift = 0; @@ -276,16 +276,16 @@ generic_gss_oid_to_str(minor_status, oid, oid_str) if ((bp = (char *) malloc(string_length))) { strcpy(bp, "{ "); number = (OM_uint32) cp[0]; - sprintf(numstr, "%lu ", (unsigned long)number/40); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40); strcat(bp, numstr); - sprintf(numstr, "%lu ", (unsigned long)number%40); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40); strcat(bp, numstr); number = 0; cp = (unsigned char *) oid->elements; for (i=1; ilength; i++) { number = (number << 7) | (cp[i] & 0x7f); if ((cp[i] & 0x80) == 0) { - sprintf(numstr, "%lu ", (unsigned long)number); + snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number); strcat(bp, numstr); number = 0; } diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index 5567b0c24..6802090d5 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -468,20 +468,17 @@ krb5_error_code kadm5_get_config_params(context, use_kdc_config, * admin database name and lockfile are now always derived from dbname */ if (params.mask & KADM5_CONFIG_DBNAME) { - params.admin_dbname = (char *) malloc(strlen(params.dbname) + 7); - if (params.admin_dbname) { - sprintf(params.admin_dbname, "%s.kadm5", params.dbname); - params.mask |= KADM5_CONFIG_ADBNAME; - } + if (asprintf(¶ms.admin_dbname, "%s.kadm5", params.dbname) > 0) + params.mask |= KADM5_CONFIG_ADBNAME; + else + params.admin_dbname = NULL; } if (params.mask & KADM5_CONFIG_ADBNAME) { - params.admin_lockfile = (char *) malloc(strlen(params.admin_dbname) - + 6); - if (params.admin_lockfile) { - sprintf(params.admin_lockfile, "%s.lock", params.admin_dbname); - params.mask |= KADM5_CONFIG_ADB_LOCKFILE; - } + if (asprintf(¶ms.admin_lockfile, "%s.lock", params.admin_dbname) > 0) + params.mask |= KADM5_CONFIG_ADB_LOCKFILE; + else + params.admin_lockfile = NULL; } /* Get the value for the admin (policy) database lock file*/ @@ -816,7 +813,7 @@ kadm5_get_admin_service_name(krb5_context ctx, ret = ENOMEM; goto err_params; } - sprintf(admin_name, "kadmin/%s", hp->h_name); + snprintf(admin_name, maxlen, "kadmin/%s", hp->h_name); err_params: kadm5_free_config_params(ctx, ¶ms_out); diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c index dc6ebb61b..8f6f8c5d7 100644 --- a/src/lib/kadm5/chpass_util.c +++ b/src/lib/kadm5/chpass_util.c @@ -139,12 +139,13 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, if ((code != KADM5_PASS_Q_TOOSHORT) && (code != KADM5_PASS_REUSE) &&(code != KADM5_PASS_Q_CLASS) && (code != KADM5_PASS_Q_DICT) && (code != KADM5_PASS_TOOSOON)) { - /* Can't get more info for other errors */ - sprintf(buffer, "%s %s", error_message(code), - string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); - sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), - buffer); - return(code); + /* Can't get more info for other errors */ + snprintf(buffer, sizeof(buffer), "%s %s", error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); + snprintf(msg_ret, msg_len, "%s\n%s\n", + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + buffer); + return(code); } /* Ok, we have a password quality error. Return a good message */ @@ -200,31 +201,31 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, code2 = kadm5_get_policy(lhandle, princ_ent.policy, &policy_ent); if (code2 != 0) { - sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2), - string_text(CHPASS_UTIL_GET_POLICY_INFO), - error_message(code), - string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), - string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); - (void) kadm5_free_principal_ent(lhandle, &princ_ent); - return(code); + snprintf(msg_ret, msg_len, "%s %s\n%s %s\n\n%s\n ", error_message(code2), + string_text(CHPASS_UTIL_GET_POLICY_INFO), + error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + return(code); } if (code == KADM5_PASS_Q_TOOSHORT) { - sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SHORT), - policy_ent.pw_min_length); - (void) kadm5_free_principal_ent(lhandle, &princ_ent); - (void) kadm5_free_policy_ent(lhandle, &policy_ent); - return(code); + snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_PASSWORD_TOO_SHORT), + policy_ent.pw_min_length); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); } /* Can't get more info for other errors */ if (code == KADM5_PASS_Q_CLASS) { - sprintf(msg_ret, string_text(CHPASS_UTIL_TOO_FEW_CLASSES), - policy_ent.pw_min_classes); - (void) kadm5_free_principal_ent(lhandle, &princ_ent); - (void) kadm5_free_policy_ent(lhandle, &policy_ent); - return(code); + snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_TOO_FEW_CLASSES), + policy_ent.pw_min_classes); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); } if (code == KADM5_PASS_TOOSOON) { @@ -237,18 +238,19 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, if (*(ptr = &time_string[strlen(time_string)-1]) == '\n') *ptr = '\0'; - sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SOON), - time_string); + snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_PASSWORD_TOO_SOON), + time_string); (void) kadm5_free_principal_ent(lhandle, &princ_ent); (void) kadm5_free_policy_ent(lhandle, &policy_ent); return(code); } /* We should never get here, but just in case ... */ - sprintf(buffer, "%s %s", error_message(code), - string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); - sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), - buffer); + snprintf(buffer, sizeof(buffer), "%s %s", error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); + snprintf(msg_ret, msg_len, "%s\n%s\n", + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + buffer); (void) kadm5_free_principal_ent(lhandle, &princ_ent); (void) kadm5_free_policy_ent(lhandle, &policy_ent); return(code); diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index 92cb715b2..bdef3e293 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -405,23 +405,21 @@ kadm5_get_init_creds(kadm5_server_handle_t handle, if (init_type == INIT_CREDS) { ccache = ccache_in; - handle->cache_name = (char *) - malloc(strlen(krb5_cc_get_type(handle->context, ccache)) + - strlen(krb5_cc_get_name(handle->context, ccache)) + 2); - if (handle->cache_name == NULL) { - code = ENOMEM; - goto error; + if (asprintf(&handle->cache_name, "%s:%s", + krb5_cc_get_type(handle->context, ccache), + krb5_cc_get_name(handle->context, ccache)) < 0) { + handle->cache_name = NULL; + code = ENOMEM; + goto error; } - sprintf(handle->cache_name, "%s:%s", - krb5_cc_get_type(handle->context, ccache), - krb5_cc_get_name(handle->context, ccache)); } else { static int counter = 0; - handle->cache_name = malloc(sizeof("MEMORY:kadm5_") - + 3*sizeof(counter)); - sprintf(handle->cache_name, "MEMORY:kadm5_%u", counter++); - + if (asprintf(&handle->cache_name, "MEMORY:kadm5_%u", counter++) < 0) { + handle->cache_name = NULL; + code = ENOMEM; + goto error; + } code = krb5_cc_resolve(handle->context, handle->cache_name, &ccache); if (code) @@ -477,6 +475,7 @@ kadm5_gic_iter(kadm5_server_handle_t handle, krb5_keytab kt; krb5_get_init_creds_opt opt; krb5_creds mcreds, outcreds; + int n; ctx = handle->context; kt = NULL; @@ -487,20 +486,17 @@ kadm5_gic_iter(kadm5_server_handle_t handle, code = ENOMEM; if (realm) { - if ((strlen(svcname) + strlen(realm) + 1) >= full_svcname_len) - goto error; - sprintf(full_svcname, "%s@%s", svcname, realm); + n = snprintf(full_svcname, full_svcname_len, "%s@%s", + svcname, realm); + if (n < 0 || n >= full_svcname_len) + goto error; } else { - /* krb5_princ_realm(client) is not null terminated */ - if ((strlen(svcname) + krb5_princ_realm(ctx, client)->length + 1) - >= full_svcname_len) - goto error; - - strcpy(full_svcname, svcname); - strcat(full_svcname, "@"); - strncat(full_svcname, - krb5_princ_realm(ctx, client)->data, - krb5_princ_realm(ctx, client)->length); + /* krb5_princ_realm(client) is not null terminated */ + n = snprintf(full_svcname, full_svcname_len, "%s@%.*s", + svcname, krb5_princ_realm(ctx, client)->length, + krb5_princ_realm(ctx, client)->data); + if (n < 0 || n >= full_svcname_len) + goto error; } if (init_type != INIT_CREDS) diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c index 86abf48e9..dabb399c1 100644 --- a/src/lib/kadm5/logger.c +++ b/src/lib/kadm5/logger.c @@ -189,7 +189,7 @@ klog_com_err_proc(const char *whoami, long int code, const char *format, va_list char *syslogp; /* Make the header */ - sprintf(outbuf, "%s: ", whoami); + snprintf(outbuf, sizeof(outbuf), "%s: ", whoami); /* * Squirrel away address after header for syslog since syslog makes * a header @@ -844,13 +844,13 @@ klog_vsyslog(int priority, const char *format, va_list arglist) cp += 15; #endif /* HAVE_STRFTIME */ #ifdef VERBOSE_LOGS - sprintf(cp, " %s %s[%ld](%s): ", - log_control.log_hostname ? log_control.log_hostname : "", - log_control.log_whoami ? log_control.log_whoami : "", - (long) getpid(), - severity2string(priority)); + snprintf(cp, sizeof(outbuf) - (cp-outbuf), " %s %s[%ld](%s): ", + log_control.log_hostname ? log_control.log_hostname : "", + log_control.log_whoami ? log_control.log_whoami : "", + (long) getpid(), + severity2string(priority)); #else - sprintf(cp, " "); + snprintf(cp, sizeof(outbuf) - (cp-outbuf), " "); #endif syslogp = &outbuf[strlen(outbuf)]; diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index 6392ef10d..700b53a66 100644 --- a/src/lib/kadm5/srv/server_kdb.c +++ b/src/lib/kadm5/srv/server_kdb.c @@ -113,11 +113,10 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r) realm = r; } - if ((hist_name = (char *) malloc(strlen(KADM5_HIST_PRINCIPAL) + - strlen(realm) + 2)) == NULL) + if (asprintf(&hist_name, "%s@%s", KADM5_HIST_PRINCIPAL, realm) < 0) { + hist_name = NULL; goto done; - - (void) sprintf(hist_name, "%s@%s", KADM5_HIST_PRINCIPAL, realm); + } if ((ret = krb5_parse_name(handle->context, hist_name, &hist_princ))) goto done; diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index a20af6b17..2b6ed2c64 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -269,8 +269,9 @@ kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) } else #endif { - sprintf(buf, "Program not built to support %s database type\n", - lib_name); + snprintf(buf, sizeof(buf), + "Program not built to support %s database type\n", + lib_name); status = KRB5_KDB_DBTYPE_NOSUP; krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); goto clean_n_exit; @@ -282,8 +283,9 @@ kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) if ((status = (*lib)->vftabl.init_library())) { /* ERROR. library not initialized cleanly */ - sprintf(buf, "%s library initialization failed, error code %ld\n", - lib_name, status); + snprintf(buf, sizeof(buf), + "%s library initialization failed, error code %ld\n", + lib_name, status); status = KRB5_KDB_DBTYPE_INIT; krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); goto clean_n_exit; diff --git a/src/lib/krb4/CCache-glue.c b/src/lib/krb4/CCache-glue.c index 2ccbb153a..a078c9f69 100644 --- a/src/lib/krb4/CCache-glue.c +++ b/src/lib/krb4/CCache-glue.c @@ -93,7 +93,7 @@ krb_in_tkt ( err = cc_initialize (&cc_context, ccapi_version_3, &cc_version, NULL); if (err == ccNoError) { - sprintf (principal, "%s%s%s@%s", pname, (pinst [0] == '\0') ? "" : ".", pinst, realm); + snprintf (principal, sizeof(principal), "%s%s%s@%s", pname, (pinst [0] == '\0') ? "" : ".", pinst, realm); } if (err == ccNoError) { diff --git a/src/lib/krb4/RealmsConfig-glue.c b/src/lib/krb4/RealmsConfig-glue.c index 740d881c4..df663adb5 100644 --- a/src/lib/krb4/RealmsConfig-glue.c +++ b/src/lib/krb4/RealmsConfig-glue.c @@ -473,7 +473,7 @@ krb_get_krbhst( return KFAILURE; if (strlen(entry->host) + 6 >= MAXHOSTNAMELEN) return KFAILURE; - sprintf(host, "%s:%d", entry->host, entry->port); + snprintf(host, MAXHOSTNAMELEN, "%s:%d", entry->host, entry->port); return KSUCCESS; } #endif diff --git a/src/lib/krb4/klog.c b/src/lib/krb4/klog.c index da48efeb2..4e9661a89 100644 --- a/src/lib/krb4/klog.c +++ b/src/lib/krb4/klog.c @@ -91,7 +91,7 @@ char * klog(type,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0) logtype_array[L_ERR_UNK] = 1; } - (void) sprintf(logtxt,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); + (void) snprintf(logtxt,sizeof(logtxt),format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a0); if (!logtype_array[type]) return(logtxt); diff --git a/src/lib/krb4/password_to_key.c b/src/lib/krb4/password_to_key.c index c6e60d98c..d5ca7a5cc 100644 --- a/src/lib/krb4/password_to_key.c +++ b/src/lib/krb4/password_to_key.c @@ -35,6 +35,8 @@ #include "krb.h" #include "krb4int.h" +#include "k5-platform.h" + /* * passwd_to_key(): given a password, return a DES key. * There are extra arguments here which (used to be?) @@ -107,17 +109,15 @@ krb5_passwd_to_key( char *passwd, C_Block key) { - size_t len, tlen; char *p; if (user && instance && realm && passwd) { - len = MAX_K_NAME_SZ + strlen(passwd) + 1; - tlen = strlen(passwd) + strlen(realm) + strlen(user) + strlen(instance) + 1; - if (tlen > len) + if (strlen(realm) + strlen(user) + strlen(instance) > MAX_K_NAME_SZ) + /* XXX Is this right? The old code returned 0, which is + also what it returns after sucessfully generating a + key. The other error path returns -1. */ return 0; - p = malloc (tlen); - if (p != NULL) { - sprintf (p, "%s%s%s%s", passwd, realm, user, instance); + if (asprintf(&p, "%s%s%s%s", passwd, realm, user, instance) >= 0) { des_string_to_key (p, key); free (p); return 0; diff --git a/src/lib/krb4/stime.c b/src/lib/krb4/stime.c index 92c86895e..f73c6f520 100644 --- a/src/lib/krb4/stime.c +++ b/src/lib/krb4/stime.c @@ -49,9 +49,9 @@ char *krb_stime(t) adjusted_time = *t - CONVERT_TIME_EPOCH; tm = localtime(&adjusted_time); - (void) sprintf(st,"%2d-%s-%d %02d:%02d:%02d",tm->tm_mday, - month_sname(tm->tm_mon + 1),1900+tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); + (void) snprintf(st,sizeof(st),"%2d-%s-%d %02d:%02d:%02d",tm->tm_mday, + month_sname(tm->tm_mon + 1),1900+tm->tm_year, + tm->tm_hour, tm->tm_min, tm->tm_sec); return st; } diff --git a/src/lib/krb4/tkt_string.c b/src/lib/krb4/tkt_string.c index 123596ca2..f6ed927b7 100644 --- a/src/lib/krb4/tkt_string.c +++ b/src/lib/krb4/tkt_string.c @@ -74,7 +74,8 @@ const char *tkt_string() } else { /* 32 bits of signed integer will always fit in 11 characters (including the sign), so no need to worry about overflow */ - (void) sprintf(krb_ticket_string, "%s%d",TKT_ROOT,(int) getuid()); + (void) snprintf(krb_ticket_string, sizeof(krb_ticket_string), + "%s%d",TKT_ROOT,(int) getuid()); } } return krb_ticket_string; diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c index c5e3452b8..5ef2a3efa 100644 --- a/src/lib/krb5/asn.1/asn1_encode.c +++ b/src/lib/krb5/asn.1/asn1_encode.c @@ -261,9 +261,12 @@ asn1_error_code asn1_encode_generaltime(asn1buf *buf, time_t val, gtime->tm_mday > 31 || gtime->tm_hour > 23 || gtime->tm_min > 59 || gtime->tm_sec > 59) return ASN1_BAD_GMTIME; - sprintf(s, "%04d%02d%02d%02d%02d%02dZ", - 1900+gtime->tm_year, gtime->tm_mon+1, gtime->tm_mday, - gtime->tm_hour, gtime->tm_min, gtime->tm_sec); + if (snprintf(s, sizeof(s), "%04d%02d%02d%02d%02d%02dZ", + 1900+gtime->tm_year, gtime->tm_mon+1, gtime->tm_mday, + gtime->tm_hour, gtime->tm_min, gtime->tm_sec) + >= sizeof(s)) + /* Shouldn't be possible given above tests. */ + return ASN1_BAD_GMTIME; sp = s; } diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c index babfea48b..8f98ef7db 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ b/src/lib/krb5/ccache/ccapi/stdcc.c @@ -1060,7 +1060,7 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_generate_new /* create a unique name */ cc_get_change_time(gCntrlBlock, &change_time); - sprintf(name, "gen_new_cache%d", change_time); + snprintf(name, 256, "gen_new_cache%d", change_time); /* create the new cache */ err = cc_create(gCntrlBlock, name, name, CC_CRED_V5, 0L, diff --git a/src/lib/krb5/ccache/ser_cc.c b/src/lib/krb5/ccache/ser_cc.c index a7d34f93d..d2abf532d 100644 --- a/src/lib/krb5/ccache/ser_cc.c +++ b/src/lib/krb5/ccache/ser_cc.c @@ -120,13 +120,13 @@ krb5_ccache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu fnamep = krb5_cc_get_name(kcontext, ccache); namelen += (strlen(fnamep)+1); - if ((ccname = (char *) malloc(namelen))) { - /* Format the ccache name. */ - if (ccache->ops && ccache->ops->prefix) - sprintf(ccname, "%s:%s", ccache->ops->prefix, fnamep); - else - strcpy(ccname, fnamep); + if (ccache->ops && ccache->ops->prefix) { + if (asprintf(&ccname, "%s:%s", ccache->ops->prefix, fnamep) < 0) + ccname = NULL; + } else + ccname = strdup(fnamep); + if (ccname) { /* Put the length of the file name */ (void) krb5_ser_pack_int32((krb5_int32) strlen(ccname), &bp, &remain); diff --git a/src/lib/krb5/ccache/t_cc.c b/src/lib/krb5/ccache/t_cc.c index 393ac92cd..862411509 100644 --- a/src/lib/krb5/ccache/t_cc.c +++ b/src/lib/krb5/ccache/t_cc.c @@ -170,7 +170,7 @@ static void cc_test(krb5_context context, const char *name, int flags) { /* Copy the cache test*/ - sprintf(newcache, "%s.new", name); + snprintf(newcache, sizeof(newcache), "%s.new", name); kret = krb5_cc_resolve(context, newcache, &id2); CHECK(kret, "resolve of new cache"); @@ -212,12 +212,11 @@ static void cc_test(krb5_context context, const char *name, int flags) */ static int check_registered(krb5_context context, const char *prefix) { - char name[300]; krb5_error_code kret; krb5_ccache id; - sprintf(name, "%s/tmp/cctest.%ld", prefix, (long) getpid()); + snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid()); kret = krb5_cc_resolve(context, name, &id); if(kret != KRB5_OK) { @@ -242,7 +241,7 @@ static void do_test(krb5_context context, const char *prefix) { char name[300]; - sprintf(name, "%s/tmp/cctest.%ld", prefix, (long) getpid()); + snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid()); printf("Starting test on %s\n", name); cc_test (context, name, 0); cc_test (context, name, !0); diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c index df0a80501..2652c00af 100644 --- a/src/lib/krb5/keytab/kt_file.c +++ b/src/lib/krb5/keytab/kt_file.c @@ -607,14 +607,13 @@ krb5_ktf_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet fnamep = ktfile_def_name; namelen += (strlen(fnamep)+1); - if ((ktname = (char *) malloc(namelen))) { - /* Format the keytab name. */ - if (keytab->ops && keytab->ops->prefix) - sprintf(ktname, "%s:%s", keytab->ops->prefix, fnamep); - - else - strcpy(ktname, fnamep); + if (keytab->ops && keytab->ops->prefix) { + if (asprintf(&ktname, "%s:%s", keytab->ops->prefix, fnamep) < 0) + ktname = NULL; + } else + ktname = strdup(fnamep); + if (ktname) { /* Fill in the file-specific keytab information. */ if (ktdata) { if (ktdata->openf) { diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 02d344c5d..dd3f011d9 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -257,10 +257,12 @@ krb5_get_init_creds_password(krb5_context context, if (strcmp(pw0.data, pw1.data) != 0) { ret = KRB5_LIBOS_BADPWDMATCH; - sprintf(banner, "%s. Please try again.", error_message(ret)); + snprintf(banner, sizeof(banner), + "%s. Please try again.", error_message(ret)); } else if (pw0.length == 0) { ret = KRB5_CHPW_PWDNULL; - sprintf(banner, "%s. Please try again.", error_message(ret)); + snprintf(banner, sizeof(banner), + "%s. Please try again.", error_message(ret)); } else { int result_code; krb5_data code_string; @@ -295,11 +297,11 @@ krb5_get_init_creds_password(krb5_context context, if (result_string.length > (sizeof(banner)-100)) result_string.length = sizeof(banner)-100; - sprintf(banner, "%.*s%s%.*s. Please try again.\n", - (int) code_string.length, code_string.data, - result_string.length ? ": " : "", - (int) result_string.length, - result_string.data ? result_string.data : ""); + snprintf(banner, sizeof(banner), "%.*s%s%.*s. Please try again.\n", + (int) code_string.length, code_string.data, + result_string.length ? ": " : "", + (int) result_string.length, + result_string.data ? result_string.data : ""); krb5_xfree(code_string.data); krb5_xfree(result_string.data); @@ -340,14 +342,16 @@ cleanup: ((hours = ((as_reply->enc_part2->key_exp-now)/(60*60))) <= 7*24) && (hours >= 0)) { if (hours < 1) - sprintf(banner, - "Warning: Your password will expire in less than one hour."); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in less than one hour."); else if (hours <= 48) - sprintf(banner, "Warning: Your password will expire in %d hour%s.", - hours, (hours == 1)?"":"s"); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in %d hour%s.", + hours, (hours == 1)?"":"s"); else - sprintf(banner, "Warning: Your password will expire in %d days.", - hours/24); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in %d days.", + hours/24); /* ignore an error here */ /* PROMPTER_INVOCATION */ @@ -376,17 +380,17 @@ cleanup: delta = (*last_req)->value - now; if (delta < 3600) - sprintf(banner, - "Warning: Your password will expire in less than one " - "hour on %s", ts); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in less than one hour on %s", + ts); else if (delta < 86400*2) - sprintf(banner, - "Warning: Your password will expire in %d hour%s on %s", - delta / 3600, delta < 7200 ? "" : "s", ts); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in %d hour%s on %s", + delta / 3600, delta < 7200 ? "" : "s", ts); else - sprintf(banner, - "Warning: Your password will expire in %d days on %s", - delta / 86400, ts); + snprintf(banner, sizeof(banner), + "Warning: Your password will expire in %d days on %s", + delta / 86400, ts); /* ignore an error here */ /* PROMPTER_INVOCATION */ (*prompter)(context, data, 0, banner, 0, 0); diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index f59b899c6..7be2becfe 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -799,21 +799,21 @@ krb5_error_code pa_sam(krb5_context context, prompter_data, salt, s2kparams, as_key, gak_data))) return(ret); } - sprintf(name, "%.*s", - SAMDATA(sam_challenge->sam_type_name, "SAM Authentication", - sizeof(name) - 1)); + snprintf(name, sizeof(name), "%.*s", + SAMDATA(sam_challenge->sam_type_name, "SAM Authentication", + sizeof(name) - 1)); - sprintf(banner, "%.*s", - SAMDATA(sam_challenge->sam_challenge_label, - sam_challenge_banner(sam_challenge->sam_type), - sizeof(banner)-1)); + snprintf(banner, sizeof(banner), "%.*s", + SAMDATA(sam_challenge->sam_challenge_label, + sam_challenge_banner(sam_challenge->sam_type), + sizeof(banner)-1)); /* sprintf(prompt, "Challenge is [%s], %s: ", challenge, prompt); */ - sprintf(prompt, "%s%.*s%s%.*s", - sam_challenge->sam_challenge.length?"Challenge is [":"", - SAMDATA(sam_challenge->sam_challenge, "", 20), - sam_challenge->sam_challenge.length?"], ":"", - SAMDATA(sam_challenge->sam_response_prompt, "passcode", 55)); + snprintf(prompt, sizeof(prompt), "%s%.*s%s%.*s", + sam_challenge->sam_challenge.length?"Challenge is [":"", + SAMDATA(sam_challenge->sam_challenge, "", 20), + sam_challenge->sam_challenge.length?"], ":"", + SAMDATA(sam_challenge->sam_response_prompt, "passcode", 55)); response_data.data = response; response_data.length = sizeof(response); @@ -1064,20 +1064,20 @@ krb5_error_code pa_sam_2(krb5_context context, } } - sprintf(name, "%.*s", + snprintf(name, sizeof(name), "%.*s", SAMDATA(sc2b->sam_type_name, "SAM Authentication", sizeof(name) - 1)); - sprintf(banner, "%.*s", - SAMDATA(sc2b->sam_challenge_label, - sam_challenge_banner(sc2b->sam_type), - sizeof(banner)-1)); + snprintf(banner, sizeof(banner), "%.*s", + SAMDATA(sc2b->sam_challenge_label, + sam_challenge_banner(sc2b->sam_type), + sizeof(banner)-1)); - sprintf(prompt, "%s%.*s%s%.*s", - sc2b->sam_challenge.length?"Challenge is [":"", - SAMDATA(sc2b->sam_challenge, "", 20), - sc2b->sam_challenge.length?"], ":"", - SAMDATA(sc2b->sam_response_prompt, "passcode", 55)); + snprintf(prompt, sizeof(prompt), "%s%.*s%s%.*s", + sc2b->sam_challenge.length?"Challenge is [":"", + SAMDATA(sc2b->sam_challenge, "", 20), + sc2b->sam_challenge.length?"], ":"", + SAMDATA(sc2b->sam_response_prompt, "passcode", 55)); response_data.data = response; response_data.length = sizeof(response); diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c index f88df5ee5..c8cbe72bc 100644 --- a/src/lib/krb5/krb/srv_rcache.c +++ b/src/lib/krb5/krb/srv_rcache.c @@ -84,7 +84,7 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece, continue; } if (!isvalidrcname((int) piece->data[i])) { - sprintf(tmp, "%03o", piece->data[i]); + snprintf(tmp, sizeof(tmp), "%03o", piece->data[i]); cachename[p++] = '-'; cachename[p++] = tmp[0]; cachename[p++] = tmp[1]; diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c index d0a11db28..a650496fc 100644 --- a/src/lib/krb5/krb/str_conv.c +++ b/src/lib/krb5/krb/str_conv.c @@ -264,9 +264,9 @@ krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen if (!ndone) { #define sftime_default_len 2+1+2+1+4+1+2+1+2+1 if (buflen >= sftime_default_len) { - sprintf(buffer, "%02d/%02d/%4d %02d:%02d", - tmp->tm_mday, tmp->tm_mon+1, 1900+tmp->tm_year, - tmp->tm_hour, tmp->tm_min); + snprintf(buffer, buflen, "%02d/%02d/%4d %02d:%02d", + tmp->tm_mday, tmp->tm_mon+1, 1900+tmp->tm_year, + tmp->tm_hour, tmp->tm_min); ndone = strlen(buffer); } } @@ -309,14 +309,14 @@ krb5_deltat_to_string(krb5_deltat deltat, char *buffer, size_t buflen) memset (tmpbuf, 0, sizeof (tmpbuf)); if (days == 0) - sprintf(buffer, "%d:%02d:%02d", hours, minutes, seconds); + snprintf(buffer, buflen, "%d:%02d:%02d", hours, minutes, seconds); else if (hours || minutes || seconds) - sprintf(buffer, "%d %s %02d:%02d:%02d", days, - (days > 1) ? "days" : "day", - hours, minutes, seconds); + snprintf(buffer, buflen, "%d %s %02d:%02d:%02d", days, + (days > 1) ? "days" : "day", + hours, minutes, seconds); else - sprintf(buffer, "%d %s", days, - (days > 1) ? "days" : "day"); + snprintf(buffer, buflen, "%d %s", days, + (days > 1) ? "days" : "day"); if (tmpbuf[sizeof(tmpbuf)-1] != 0) /* Something must be very wrong with my math above, or the assumptions going into it... */ diff --git a/src/lib/krb5/krb/t_ser.c b/src/lib/krb5/krb/t_ser.c index d62bceeb7..383b6708d 100644 --- a/src/lib/krb5/krb/t_ser.c +++ b/src/lib/krb5/krb/t_ser.c @@ -203,7 +203,7 @@ ser_kcontext_test(krb5_context kcontext, int verbose) profile_t sprofile; char dbname[128]; - sprintf(dbname, "temp_%d", (int) getpid()); + snprintf(dbname, sizeof(dbname), "temp_%d", (int) getpid()); sprofile = kcontext->profile; kcontext->profile = (profile_t) NULL; if (!(kret = ser_data(verbose, "> Context with no profile", @@ -320,7 +320,8 @@ ser_acontext_test(krb5_context kcontext, int verbose) */ memset(&aent, 0, sizeof(aent)); aent.magic = KV5M_AUTHENTICATOR; - sprintf(clname, "help/me/%d@this.is.a.test", (int) getpid()); + snprintf(clname, sizeof(clname), + "help/me/%d@this.is.a.test", (int) getpid()); actx->authentp = &aent; if (!(kret = krb5_parse_name(kcontext, clname, &aent.client)) && @@ -368,9 +369,10 @@ ser_ccache_test(krb5_context kcontext, int verbose) krb5_ccache ccache; krb5_principal principal; - sprintf(ccname, "temp_cc_%d", (int) getpid()); - sprintf(princname, "zowie%d/instance%d@this.is.a.test", - (int) getpid(), (int) getpid()); + snprintf(ccname, sizeof(ccname), "temp_cc_%d", (int) getpid()); + snprintf(princname, sizeof(princname), + "zowie%d/instance%d@this.is.a.test", + (int) getpid(), (int) getpid()); if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) && !(kret = ser_data(verbose, "> Resolved default ccache", (krb5_pointer) ccache, KV5M_CCACHE)) && @@ -380,9 +382,9 @@ ser_ccache_test(krb5_context kcontext, int verbose) (krb5_pointer) ccache, KV5M_CCACHE)) && !(kret = krb5_cc_destroy(kcontext, ccache))) { krb5_free_principal(kcontext, principal); - sprintf(ccname, "FILE:temp_cc_%d", (int) getpid()); - sprintf(princname, "xxx%d/i%d@this.is.a.test", - (int) getpid(), (int) getpid()); + snprintf(ccname, sizeof(ccname), "FILE:temp_cc_%d", (int) getpid()); + snprintf(princname, sizeof(princname), "xxx%d/i%d@this.is.a.test", + (int) getpid(), (int) getpid()); if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) && !(kret = ser_data(verbose, "> Resolved FILE ccache", (krb5_pointer) ccache, KV5M_CCACHE)) && @@ -412,7 +414,7 @@ ser_keytab_test(krb5_context kcontext, int verbose) char ccname[128]; krb5_keytab keytab; - sprintf(ccname, "temp_kt_%d", (int) getpid()); + snprintf(ccname, sizeof(ccname), "temp_kt_%d", (int) getpid()); if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) && !(kret = ser_data(verbose, "> Resolved default keytab", (krb5_pointer) keytab, KV5M_KEYTAB)) && @@ -422,7 +424,8 @@ ser_keytab_test(krb5_context kcontext, int verbose) !(kret = ser_data(verbose, "> Resolved FILE keytab", (krb5_pointer) keytab, KV5M_KEYTAB)) && !(kret = krb5_kt_close(kcontext, keytab))) { - sprintf(ccname, "WRFILE:temp_kt_%d", (int) getpid()); + snprintf(ccname, sizeof(ccname), + "WRFILE:temp_kt_%d", (int) getpid()); if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) && !(kret = ser_data(verbose, "> Resolved WRFILE keytab", (krb5_pointer) keytab, KV5M_KEYTAB)) && @@ -447,7 +450,7 @@ ser_rcache_test(krb5_context kcontext, int verbose) char rcname[128]; krb5_rcache rcache; - sprintf(rcname, "dfl:temp_rc_%d", (int) getpid()); + snprintf(rcname, sizeof(rcname), "dfl:temp_rc_%d", (int) getpid()); if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname)) && !(kret = ser_data(verbose, "> Resolved FILE rcache", (krb5_pointer) rcache, KV5M_RCACHE)) && @@ -527,7 +530,9 @@ ser_princ_test(krb5_context kcontext, int verbose) krb5_principal princ; char pname[1024]; - sprintf(pname, "the/quick/brown/fox/jumped/over/the/lazy/dog/%d@this.is.a.test", (int) getpid()); + snprintf(pname, sizeof(pname), + "the/quick/brown/fox/jumped/over/the/lazy/dog/%d@this.is.a.test", + (int) getpid()); if (!(kret = krb5_parse_name(kcontext, pname, &princ))) { if (!(kret = ser_data(verbose, "> Principal", (krb5_pointer) princ, KV5M_PRINCIPAL))) { diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c index d140b0896..8fa52f7b8 100644 --- a/src/lib/krb5/os/ccdefname.c +++ b/src/lib/krb5/os/ccdefname.c @@ -213,7 +213,8 @@ static krb5_error_code get_from_os(char *name_buf, int name_size) result = ENOMEM; goto cleanup; } else { - sprintf (name_buf, "API:%s", default_name -> data); + snprintf (name_buf, name_size, "API:%s", + default_name -> data); } } @@ -233,8 +234,8 @@ cleanup: #if !(defined(_WIN32)) static krb5_error_code get_from_os(char *name_buf, int name_size) { - sprintf(name_buf, "FILE:/tmp/krb5cc_%ld", (long) getuid()); - return 0; + snprintf(name_buf, name_size, "FILE:/tmp/krb5cc_%ld", (long) getuid()); + return 0; } #endif #endif diff --git a/src/lib/krb5/os/dnssrv.c b/src/lib/krb5/os/dnssrv.c index d1c96b291..d726fb7e5 100644 --- a/src/lib/krb5/os/dnssrv.c +++ b/src/lib/krb5/os/dnssrv.c @@ -84,8 +84,10 @@ krb5int_make_srv_query_realm(const krb5_data *realm, if ( strlen(service) + strlen(protocol) + realm->length + 6 > MAXDNAME ) return 0; - sprintf(host, "%s.%s.%.*s", service, protocol, (int) realm->length, - realm->data); + if (snprintf(host, sizeof(host), "%s.%s.%.*s", + service, protocol, (int) realm->length, + realm->data) >= sizeof(host)) + return 0; /* Realm names don't (normally) end with ".", but if the query doesn't end with "." and doesn't get an answer as is, the diff --git a/src/lib/krb5/os/gen_rname.c b/src/lib/krb5/os/gen_rname.c index 7978a5dbc..609815338 100644 --- a/src/lib/krb5/os/gen_rname.c +++ b/src/lib/krb5/os/gen_rname.c @@ -36,14 +36,16 @@ krb5_gen_replay_name(krb5_context context, const krb5_address *address, const ch { char * tmp; int i; + int len; - if ((*string = malloc(strlen(uniq) + (address->length * 2) + 1)) == NULL) + len = strlen(uniq) + (address->length * 2) + 1; + if ((*string = malloc(len)) == NULL) return ENOMEM; - sprintf(*string, "%s", uniq); - tmp = (*string) + strlen(uniq); + snprintf(*string, len, "%s", uniq); + tmp = *string + strlen(uniq); for (i = 0; i < address->length; i++) { - sprintf(tmp, "%.2x", address->contents[i] & 0xff); + snprintf(tmp, len - (tmp-*string), "%.2x", address->contents[i] & 0xff); tmp += 2; } return 0; diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c index 7e24b8d6d..983637864 100644 --- a/src/lib/krb5/os/hst_realm.c +++ b/src/lib/krb5/os/hst_realm.c @@ -105,7 +105,8 @@ krb5_try_realm_txt_rr(const char *prefix, const char *name, char **realm) } else { if ( strlen(prefix) + strlen(name) + 3 > MAXDNAME ) return KRB5_ERR_HOST_REALM_UNKNOWN; - sprintf(host,"%s.%s", prefix, name); + if (snprintf(host, sizeof(host), "%s.%s", prefix, name) >= sizeof(host)) + return KRB5_ERR_HOST_REALM_UNKNOWN; /* Realm names don't (normally) end with ".", but if the query doesn't end with "." and doesn't get an answer as is, the diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c index 925b6e1b5..28fac5dee 100644 --- a/src/lib/krb5/os/ktdefname.c +++ b/src/lib/krb5/os/ktdefname.c @@ -70,7 +70,7 @@ krb5_kt_default_name(krb5_context context, char *name, size_t namesize) defname[len]= '\0'; if ( (len + strlen(krb5_defkeyname) + 1) > namesize ) return KRB5_CONFIG_NOTENUFSPACE; - sprintf(name, krb5_defkeyname, defname); + snprintf(name, namesize, krb5_defkeyname, defname); } #else if (namesize < (strlen(krb5_defkeyname)+1)) diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index 566213d35..f03568b36 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -257,8 +257,11 @@ krb5int_add_host_to_list (struct addrlist *lp, const char *hostname, #ifdef AI_NUMERICSERV hint.ai_flags = AI_NUMERICSERV; #endif - sprintf(portbuf, "%d", ntohs(port)); - sprintf(secportbuf, "%d", ntohs(secport)); + if (snprintf(portbuf, sizeof(portbuf), "%d", ntohs(port)) >= sizeof(portbuf)) + /* XXX */ + return EINVAL; + if (snprintf(secportbuf, sizeof(secportbuf), "%d", ntohs(secport)) >= sizeof(secportbuf)) + return EINVAL; err = getaddrinfo (hostname, portbuf, &hint, &addrs); if (err) { Tprintf ("\tgetaddrinfo(\"%s\", \"%s\", ...)\n\treturns %d: %s\n", diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index a476ef400..3be46de9f 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -122,7 +122,7 @@ krb5int_debug_fprint (const char *fmt, ...) va_start(args, fmt); -#define putf(FMT,X) (sprintf(tmpbuf,FMT,X),putstr(tmpbuf)) +#define putf(FMT,X) (snprintf(tmpbuf,sizeof(tmpbuf),FMT,X),putstr(tmpbuf)) for (; *fmt; fmt++) { if (*fmt != '%') { @@ -152,7 +152,7 @@ krb5int_debug_fprint (const char *fmt, ...) case 'E': /* %E => krb5_error_code */ kerr = va_arg(args, krb5_error_code); - sprintf(tmpbuf, "%lu/", (unsigned long) kerr); + snprintf(tmpbuf, sizeof(tmpbuf), "%lu/", (unsigned long) kerr); putstr(tmpbuf); p = error_message(kerr); putstr(p); @@ -204,7 +204,7 @@ krb5int_debug_fprint (const char *fmt, ...) /* %t => struct timeval * */ tv = va_arg(args, struct timeval *); if (tv) { - sprintf(tmpbuf, "%ld.%06ld", + snprintf(tmpbuf, sizeof(tmpbuf), "%ld.%06ld", (long) tv->tv_sec, (long) tv->tv_usec); putstr(tmpbuf); } else @@ -226,7 +226,7 @@ krb5int_debug_fprint (const char *fmt, ...) else if (ai->ai_socktype == SOCK_STREAM) strcpy(tmpbuf, "stream"); else - sprintf(tmpbuf, "socktype%d", ai->ai_socktype); + snprintf(tmpbuf, sizeof(tmpbuf), "socktype%d", ai->ai_socktype); if (0 != getnameinfo (ai->ai_addr, ai->ai_addrlen, addrbuf, sizeof (addrbuf), portbuf, sizeof (portbuf), @@ -234,9 +234,12 @@ krb5int_debug_fprint (const char *fmt, ...) if (ai->ai_addr->sa_family == AF_UNSPEC) strcpy(tmpbuf + strlen(tmpbuf), " AF_UNSPEC"); else - sprintf(tmpbuf + strlen(tmpbuf), " af%d", ai->ai_addr->sa_family); + snprintf(tmpbuf + strlen(tmpbuf), + sizeof(tmpbuf)-strlen(tmpbuf), + " af%d", ai->ai_addr->sa_family); } else - sprintf(tmpbuf + strlen(tmpbuf), " %s.%s", addrbuf, portbuf); + snprintf(tmpbuf + strlen(tmpbuf), sizeof(tmpbuf)-strlen(tmpbuf), + " %s.%s", addrbuf, portbuf); putstr(tmpbuf); break; case 'D': diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c index adc6a8c49..32357283e 100644 --- a/src/lib/krb5/rcache/rc_io.c +++ b/src/lib/krb5/rcache/rc_io.c @@ -76,8 +76,7 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn) size_t dirlen; GETDIR; - if (fn && *fn) - { + if (fn && *fn) { if (!(d->fn = malloc(strlen(*fn) + dirlen + 1))) return KRB5_RC_IO_MALLOC; (void) strcpy(d->fn, dir); @@ -85,43 +84,34 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn) (void) strcat(d->fn, *fn); d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, 0600); - } - else - { - /* %d is max 11 digits (-, 10 digits of 32-bit number) - * 11 + /krb5_RC + aaa = 24, +6 for slop */ - if (!(d->fn = malloc(30 + dirlen))) + } else { + if (asprintf(&d->fn, "%s%skrb5_RC%daaa", + dir, PATH_SEPARATOR, (int) UNIQUE) < 0) { + d->fn = NULL; return KRB5_RC_IO_MALLOC; - if (fn) - if (!(*fn = malloc(35))) { - FREE(d->fn); - return KRB5_RC_IO_MALLOC; - } - (void) sprintf(d->fn, "%s%skrb5_RC%d", dir, PATH_SEPARATOR, - (int) UNIQUE); - c = d->fn + strlen(d->fn); - (void) strcpy(c, "aaa"); + } + c = d->fn + strlen(d->fn) - 3; while ((d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | - O_EXCL | O_BINARY, 0600)) == -1) - { - if ((c[2]++) == 'z') - { + O_EXCL | O_BINARY, 0600)) == -1) { + if ((c[2]++) == 'z') { c[2] = 'a'; - if ((c[1]++) == 'z') - { + if ((c[1]++) == 'z') { c[1] = 'a'; if ((c[0]++) == 'z') break; /* sigh */ } } } - if (fn) - (void) strcpy(*fn, d->fn + dirlen); + if (fn) { + *fn = strdup(d->fn + dirlen); + if (*fn == NULL) { + free(d->fn); + return KRB5_RC_IO_MALLOC; + } + } } - if (d->fd == -1) - { - switch(errno) - { + if (d->fd == -1) { + switch(errno) { case EFBIG: #ifdef EDQUOT case EDQUOT: diff --git a/src/lib/krb5/rcache/ser_rc.c b/src/lib/krb5/rcache/ser_rc.c index 0b3d098a8..af19edf7a 100644 --- a/src/lib/krb5/rcache/ser_rc.c +++ b/src/lib/krb5/rcache/ser_rc.c @@ -121,13 +121,13 @@ krb5_rcache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu fnamep = krb5_rc_get_name(kcontext, rcache); namelen += (strlen(fnamep)+1); - if ((rcname = (char *) malloc(namelen))) { - /* Format the rcache name. */ - if (rcache->ops && rcache->ops->type) - sprintf(rcname, "%s:%s", rcache->ops->type, fnamep); - else - strcpy(rcname, fnamep); + if (rcache->ops && rcache->ops->type) { + if (asprintf(&rcname, "%s:%s", rcache->ops->type, fnamep) < 0) + rcname = NULL; + } else + rcname = strdup(fnamep); + if (rcname) { /* Put the length of the file name */ (void) krb5_ser_pack_int32((krb5_int32) strlen(rcname), &bp, &remain); diff --git a/src/lib/rpc/clnt_perror.c b/src/lib/rpc/clnt_perror.c index 85935a8b0..0a52885a3 100644 --- a/src/lib/rpc/clnt_perror.c +++ b/src/lib/rpc/clnt_perror.c @@ -81,9 +81,11 @@ clnt_sperror(CLIENT *rpch, char *s) char *bufstart = get_buf(); char *str = bufstart; char *strstart = str; + char *strend; if (str == 0) return (0); + strend = str + BUFSIZ; CLNT_GETERR(rpch, &e); strncpy (str, s, BUFSIZ - 1); @@ -113,19 +115,19 @@ clnt_sperror(CLIENT *rpch, char *s) case RPC_CANTSEND: case RPC_CANTRECV: /* 10 for the string */ - if(str - bufstart + 10 + strlen(strerror(e.re_errno)) < BUFSIZ) - (void) sprintf(str, "; errno = %s", - strerror(e.re_errno)); + if (str - bufstart + 10 + strlen(strerror(e.re_errno)) < BUFSIZ) + (void) snprintf(str, strend-str, "; errno = %s", + strerror(e.re_errno)); str += strlen(str); break; case RPC_VERSMISMATCH: /* 33 for the string, 22 for the numbers */ if(str - bufstart + 33 + 22 < BUFSIZ) - (void) sprintf(str, - "; low version = %lu, high version = %lu", - (u_long) e.re_vers.low, - (u_long) e.re_vers.high); + (void) snprintf(str, strend-str, + "; low version = %lu, high version = %lu", + (u_long) e.re_vers.low, + (u_long) e.re_vers.high); str += strlen(str); break; @@ -133,17 +135,17 @@ clnt_sperror(CLIENT *rpch, char *s) err = auth_errmsg(e.re_why); /* 8 for the string */ if(str - bufstart + 8 < BUFSIZ) - (void) sprintf(str,"; why = "); + (void) snprintf(str, strend-str, "; why = "); str += strlen(str); if (err != NULL) { if(str - bufstart + strlen(err) < BUFSIZ) - (void) sprintf(str, "%s",err); + (void) snprintf(str, strend-str, "%s",err); } else { /* 33 for the string, 11 for the number */ if(str - bufstart + 33 + 11 < BUFSIZ) - (void) sprintf(str, - "(unknown authentication error - %d)", - (int) e.re_why); + (void) snprintf(str, strend-str, + "(unknown authentication error - %d)", + (int) e.re_why); } str += strlen(str); break; @@ -151,25 +153,25 @@ clnt_sperror(CLIENT *rpch, char *s) case RPC_PROGVERSMISMATCH: /* 33 for the string, 22 for the numbers */ if(str - bufstart + 33 + 22 < BUFSIZ) - (void) sprintf(str, - "; low version = %lu, high version = %lu", - (u_long) e.re_vers.low, - (u_long) e.re_vers.high); + (void) snprintf(str, strend-str, + "; low version = %lu, high version = %lu", + (u_long) e.re_vers.low, + (u_long) e.re_vers.high); str += strlen(str); break; default: /* unknown */ /* 14 for the string, 22 for the numbers */ if(str - bufstart + 14 + 22 < BUFSIZ) - (void) sprintf(str, - "; s1 = %lu, s2 = %lu", - (u_long) e.re_lb.s1, - (u_long) e.re_lb.s2); + (void) snprintf(str, strend-str, + "; s1 = %lu, s2 = %lu", + (u_long) e.re_lb.s1, + (u_long) e.re_lb.s2); str += strlen(str); break; } - if(str - bufstart + 1 < BUFSIZ) - (void) sprintf(str, "\n"); + if (str - bufstart + 1 < BUFSIZ) + (void) snprintf(str, strend-str, "\n"); return(strstart) ; } @@ -252,10 +254,12 @@ char * clnt_spcreateerror(char *s) { char *str = get_buf(); + char *strend; if (str == 0) return(0); - (void) sprintf(str, "%s: ", s); + strend = str+BUFSIZ; + (void) snprintf(str, strend-str, "%s: ", s); str[BUFSIZ - 1] = '\0'; (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1); switch (rpc_createerr.cf_stat) { @@ -273,8 +277,9 @@ clnt_spcreateerror(char *s) if (m) (void) strncat(str, m, BUFSIZ - 1 - strlen(str)); else - (void) sprintf(&str[strlen(str)], "Error %d", - rpc_createerr.cf_error.re_errno); + (void) snprintf(&str[strlen(str)], BUFSIZ - strlen(str), + "Error %d", + rpc_createerr.cf_error.re_errno); } break; diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c index 265ccd6cf..74d553ee6 100644 --- a/src/util/profile/prof_file.c +++ b/src/util/profile/prof_file.c @@ -407,15 +407,14 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile, retval = ENOMEM; new_file = old_file = 0; - new_file = malloc(strlen(outfile) + 5); - if (!new_file) - goto errout; - old_file = malloc(strlen(outfile) + 5); - if (!old_file) - goto errout; - - sprintf(new_file, "%s.$$$", outfile); - sprintf(old_file, "%s.bak", outfile); + if (asprintf(&new_file, "%s.$$$", outfile) < 0) { + new_file = NULL; + goto errout; + } + if (asprintf(&old_file, "%s.bak", outfile) < 0) { + old_file = NULL; + goto errout; + } errno = 0; diff --git a/src/util/support/errors.c b/src/util/support/errors.c index e2101a2a9..94290f857 100644 --- a/src/util/support/errors.c +++ b/src/util/support/errors.c @@ -125,7 +125,8 @@ krb5int_get_error (struct errinfo *ep, long code) return r2; } format_number: - sprintf (ep->scratch_buf, _("error %ld"), code); + snprintf (ep->scratch_buf, sizeof(ep->scratch_buf), + _("error %ld"), code); return ep->scratch_buf; } r = (char *) fptr(code); diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c index b26726fab..99d3aea57 100644 --- a/src/util/support/plugins.c +++ b/src/util/support/plugins.c @@ -49,6 +49,8 @@ #include #endif +#include "k5-platform.h" + #include static void Tprintf (const char *fmt, ...) { @@ -377,15 +379,11 @@ krb5int_get_plugin_filenames (const char * const *filebases, char ***filenames) if (!err) { int j; for (i = 0; !err && (filebases[i] != NULL); i++) { - size_t baselen = strlen (filebases[i]); for (j = 0; !err && (fileexts[j] != NULL); j++) { - size_t len = baselen + strlen (fileexts[j]) + 2; /* '.' + NULL */ - tempnames[i+j] = malloc (len * sizeof (char)); - if (tempnames[i+j] == NULL) { - err = errno; - } else { - sprintf (tempnames[i+j], "%s%s", filebases[i], fileexts[j]); - } + if (asprintf(&tempnames[i+j], "%s%s", filebases[i], fileexts[j]) < 0) { + tempnames[i+j] = NULL; + err = errno; + } } } } @@ -426,7 +424,6 @@ krb5int_open_plugin_dirs (const char * const *dirnames, } for (i = 0; !err && dirnames[i] != NULL; i++) { - size_t dirnamelen = strlen (dirnames[i]) + 1; /* '/' */ if (filenames != NULL) { /* load plugins with names from filenames from each directory */ int j; @@ -436,11 +433,9 @@ krb5int_open_plugin_dirs (const char * const *dirnames, char *filepath = NULL; if (!err) { - filepath = malloc (dirnamelen + strlen (filenames[j]) + 1); /* NULL */ - if (filepath == NULL) { - err = errno; - } else { - sprintf (filepath, "%s/%s", dirnames[i], filenames[j]); + if (asprintf(&filepath, "%s/%s", dirnames[i], filenames[j]) < 0) { + filepath = NULL; + err = errno; } } @@ -472,11 +467,9 @@ krb5int_open_plugin_dirs (const char * const *dirnames, if (!err) { int len = NAMELEN (d); - filepath = malloc (dirnamelen + len + 1); /* NULL */ - if (filepath == NULL) { - err = errno; - } else { - sprintf (filepath, "%s/%*s", dirnames[i], len, d->d_name); + if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) { + filepath = NULL; + err = errno; } } -- 2.26.2