The branch, master has been updated via efd94d1 Fix bug #8831 - Inconsistent (with manpage) command-line switch for "help" in smbtree via d497434 Who would have guessed - checking returns from strlcat found a memory overwrite bug :-). via 959516d More strlcat/strlcpy truncate checks. from 60eb162 s4 dns: Allow updating PTR records.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit efd94d159883cb0841d8ac83223a1e63098a8d72 Author: Jeremy Allison <j...@samba.org> Date: Fri Mar 30 12:23:07 2012 -0700 Fix bug #8831 - Inconsistent (with manpage) command-line switch for "help" in smbtree Autobuild-User: Jeremy Allison <j...@samba.org> Autobuild-Date: Fri Mar 30 22:59:53 CEST 2012 on sn-devel-104 commit d49743443425d874d88fe069acc91dbd5135f0e4 Author: Jeremy Allison <j...@samba.org> Date: Fri Mar 30 10:57:51 2012 -0700 Who would have guessed - checking returns from strlcat found a memory overwrite bug :-). commit 959516d61bc6ee7cdd12409dde0ec00044208f1b Author: Jeremy Allison <j...@samba.org> Date: Thu Mar 29 17:13:07 2012 -0700 More strlcat/strlcpy truncate checks. ----------------------------------------------------------------------- Summary of changes: docs-xml/build/DTD/samba.entities | 2 +- source3/auth/auth_script.c | 55 ++++++++++++++++++++++++++++++------- source3/libads/ads_struct.c | 11 ++++++- source3/modules/vfs_afsacl.c | 12 ++++++-- source3/modules/vfs_recycle.c | 12 ++++++-- source3/modules/vfs_scannedonly.c | 5 ++- source3/torture/torture.c | 12 ++++++-- source3/utils/net_rpc.c | 12 ++++++-- source3/web/swat.c | 3 +- 9 files changed, 96 insertions(+), 28 deletions(-) Changeset truncated at 500 lines: diff --git a/docs-xml/build/DTD/samba.entities b/docs-xml/build/DTD/samba.entities index d204156..f5d8cd2 100644 --- a/docs-xml/build/DTD/samba.entities +++ b/docs-xml/build/DTD/samba.entities @@ -440,7 +440,7 @@ Try to use the credentials cached by winbind. <!ENTITY stdarg.help ' <varlistentry> -<term>-h|--help</term> +<term>-?|--help</term> <listitem><para>Print a summary of command line options. </para></listitem> </varlistentry>'> diff --git a/source3/auth/auth_script.c b/source3/auth/auth_script.c index 4432ff4..dc8794b 100644 --- a/source3/auth/auth_script.c +++ b/source3/auth/auth_script.c @@ -74,32 +74,62 @@ static NTSTATUS script_check_user_credentials(const struct auth_context *auth_co return NT_STATUS_NO_MEMORY; } - strlcpy( secret_str, user_info->mapped.domain_name, secret_str_len); - strlcat( secret_str, "\n", secret_str_len); - strlcat( secret_str, user_info->client.account_name, secret_str_len); - strlcat( secret_str, "\n", secret_str_len); + if (strlcpy( secret_str, user_info->mapped.domain_name, secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + if (strlcat( secret_str, "\n", secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + if (strlcat( secret_str, user_info->client.account_name, secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + if (strlcat( secret_str, "\n", secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } for (i = 0; i < 8; i++) { slprintf(&hex_str[i*2], 3, "%02X", auth_context->challenge.data[i]); } - strlcat( secret_str, hex_str, secret_str_len); - strlcat( secret_str, "\n", secret_str_len); + if (strlcat( secret_str, hex_str, secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + if (strlcat( secret_str, "\n", secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } if (user_info->password.response.lanman.data) { for (i = 0; i < 24; i++) { slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.lanman.data[i]); } - strlcat( secret_str, hex_str, secret_str_len); + if (strlcat( secret_str, hex_str, secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + } + if (strlcat( secret_str, "\n", secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; } - strlcat( secret_str, "\n", secret_str_len); if (user_info->password.response.nt.data) { for (i = 0; i < 24; i++) { slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.nt.data[i]); } - strlcat( secret_str, hex_str, secret_str_len); + if (strlcat( secret_str, hex_str, secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; + } + } + if (strlcat( secret_str, "\n", secret_str_len) >= secret_str_len) { + /* Truncate. */ + goto cat_out; } - strlcat( secret_str, "\n", secret_str_len); DEBUG(10,("script_check_user_credentials: running %s with parameters:\n%s\n", script, secret_str )); @@ -117,6 +147,11 @@ static NTSTATUS script_check_user_credentials(const struct auth_context *auth_co /* Cause the auth system to keep going.... */ return NT_STATUS_NOT_IMPLEMENTED; + + cat_out: + + SAFE_FREE(secret_str); + return NT_STATUS_NO_MEMORY; } /* module initialisation */ diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index b6c8e99..e6220fd 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -52,10 +52,17 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int return NULL; } - strlcpy(ret,field, len); + if (strlcpy(ret,field, len) >= len) { + /* Truncate ! */ + free(r); + return NULL; + } p=strtok_r(r, sep, &saveptr); if (p) { - strlcat(ret, p, len); + if (strlcat(ret, p, len) >= len) { + free(r); + return NULL; + } while ((p=strtok_r(NULL, sep, &saveptr)) != NULL) { int retval; diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index e965e4c..61a3145 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -316,16 +316,22 @@ static bool unparse_afs_acl(struct afs_acl *acl, char *acl_str) } fstr_sprintf(line, "%d\n", positives); - strlcat(acl_str, line, MAXSIZE); + if (strlcat(acl_str, line, MAXSIZE) >= MAXSIZE) { + return false; + } fstr_sprintf(line, "%d\n", negatives); - strlcat(acl_str, line, MAXSIZE); + if (strlcat(acl_str, line, MAXSIZE) >= MAXSIZE) { + return false; + } ace = acl->acelist; while (ace != NULL) { fstr_sprintf(line, "%s\t%d\n", ace->name, ace->rights); - strlcat(acl_str, line, MAXSIZE); + if (strlcat(acl_str, line, MAXSIZE) >= MAXSIZE) { + return false; + } ace = ace->next; } return true; diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index c735dcc..8033252 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -280,13 +280,17 @@ static bool recycle_create_dir(vfs_handle_struct *handle, const char *dname) *new_dir = '\0'; if (dname[0] == '/') { /* Absolute path. */ - strlcat(new_dir,"/",len+1); + if (strlcat(new_dir,"/",len+1) >= len+1) { + goto done; + } } /* Create directory tree if neccessary */ for(token = strtok_r(tok_str, "/", &saveptr); token; token = strtok_r(NULL, "/", &saveptr)) { - strlcat(new_dir, token, len+1); + if (strlcat(new_dir, token, len+1) >= len+1) { + goto done; + } if (recycle_directory_exist(handle, new_dir)) DEBUG(10, ("recycle: dir %s already exists\n", new_dir)); else { @@ -297,7 +301,9 @@ static bool recycle_create_dir(vfs_handle_struct *handle, const char *dname) goto done; } } - strlcat(new_dir, "/", len+1); + if (strlcat(new_dir, "/", len+1) >= len+1) { + goto done; + } mode = recycle_subdir_mode(handle); } diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index 1b35388..fcd2ed0 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -327,8 +327,9 @@ static void notify_scanner(vfs_handle_struct * handle, const char *scanfile) if (gsendlen + tmplen >= SENDBUFFERSIZE) { flush_sendbuffer(handle); } - strlcat(so->gsendbuffer, tmp, SENDBUFFERSIZE + 1); - strlcat(so->gsendbuffer, "\n", SENDBUFFERSIZE + 1); + /* FIXME ! Truncate checks... JRA. */ + (void)strlcat(so->gsendbuffer, tmp, SENDBUFFERSIZE + 1); + (void)strlcat(so->gsendbuffer, "\n", SENDBUFFERSIZE + 1); } static bool is_scannedonly_file(struct Tscannedonly *so, const char *shortname) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index e2a2744..1e9e59b 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -7315,7 +7315,7 @@ static bool run_shortname_test(int dummy) bool correct = True; int i; struct sn_state s; - char fname[20]; + char fname[40]; NTSTATUS status; printf("starting shortname test\n"); @@ -7338,8 +7338,14 @@ static bool run_shortname_test(int dummy) goto out; } - strlcpy(fname, "\\shortname\\", sizeof(fname)); - strlcat(fname, "test .txt", sizeof(fname)); + if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) { + correct = false; + goto out; + } + if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) { + correct = false; + goto out; + } s.val = false; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 4aaf365..ad3f448 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3765,8 +3765,12 @@ static NTSTATUS copy_fn(const char *mnt, struct file_info *f, } /* search below that directory */ - strlcpy(new_mask, dir, sizeof(new_mask)); - strlcat(new_mask, "\\*", sizeof(new_mask)); + if (strlcpy(new_mask, dir, sizeof(new_mask)) >= sizeof(new_mask)) { + return NT_STATUS_NO_MEMORY; + } + if (strlcat(new_mask, "\\*", sizeof(new_mask)) >= sizeof(new_mask)) { + return NT_STATUS_NO_MEMORY; + } old_dir = local_state->cwd; local_state->cwd = dir; @@ -4807,7 +4811,9 @@ static bool get_user_tokens_from_file(FILE *f, token = &((*tokens)[*num_tokens-1]); - strlcpy(token->name, line, sizeof(token->name)); + if (strlcpy(token->name, line, sizeof(token->name)) >= sizeof(token->name)) { + return false; + } token->token.num_sids = 0; token->token.sids = NULL; continue; diff --git a/source3/web/swat.c b/source3/web/swat.c index 34974b4..0e17b01 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -176,7 +176,8 @@ void get_xsrf_token(const char *username, const char *pass, char tmp[3]; snprintf(tmp, sizeof(tmp), "%02x", token[i]); - strlcat(token_str, tmp, sizeof(tmp)); + /* FIXME ! Truncate check. JRA. */ + (void)strlcat(token_str, tmp, sizeof(tmp)); } } -- Samba Shared Repository