1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

Jeremy merged across my string parinoia fixes, but forgot to enable them! :-)

This patch catches up on the rest of the work - as much string checking
as is possible is done at compile time, and the rest at runtime.

Lots of code converted to pstrcpy() etc, and other code reworked to correctly
call sizeof().

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 0001-01-01 00:00:00 +00:00
parent 1966284321
commit c5b604e2ee
17 changed files with 90 additions and 107 deletions

View File

@ -322,7 +322,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \
printing/printfsp.o lib/util_seaccess.o \
smbd/build_options.o \
smbd/change_trust_pw.o \
$(MANGLE_OBJ)

View File

@ -2349,7 +2349,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
char *sharename;
/* make a copy so we don't modify the global string 'service' */
safe_strcpy(servicename, share, sizeof(servicename)-1);
fstrcpy(servicename, share);
sharename = servicename;
if (*sharename == '\\') {
server = sharename+2;
@ -2624,9 +2624,9 @@ static int do_message_op(void)
make_nmb_name(&calling, global_myname(), 0x0);
make_nmb_name(&called , desthost, name_type);
safe_strcpy(server_name, desthost, sizeof(server_name));
fstrcpy(server_name, desthost);
snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
safe_strcat(server_name, name_type_hex, sizeof(server_name));
fstrcat(server_name, name_type_hex);
zero_ip(&ip);
if (have_ip) ip = dest_ip;

View File

@ -202,7 +202,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
/* write out a "standard" tar format header */
hb.dbuf.name[NAMSIZ-1]='\0';
safe_strcpy(hb.dbuf.mode, amode, strlen(amode));
safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
@ -796,11 +796,11 @@ static void do_tar(file_info *finfo)
DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
safe_strcpy(exclaim, cur_dir, sizeof(pstring));
pstrcpy(exclaim, cur_dir);
*(exclaim+strlen(exclaim)-1)='\0';
safe_strcat(exclaim, "\\", sizeof(pstring));
safe_strcat(exclaim, finfo->name, sizeof(exclaim));
pstrcat(exclaim, "\\");
pstrcat(exclaim, finfo->name);
DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
@ -820,12 +820,12 @@ static void do_tar(file_info *finfo)
pstring saved_curdir;
pstring mtar_mask;
safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
pstrcpy(saved_curdir, cur_dir);
DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
safe_strcat(cur_dir,"\\", sizeof(cur_dir));
pstrcat(cur_dir,finfo->name);
pstrcat(cur_dir,"\\");
DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
@ -836,16 +836,16 @@ static void do_tar(file_info *finfo)
DEBUG(0,(" directory %s\n", cur_dir));
}
ntarf++; /* Make sure we have a file on there */
safe_strcpy(mtar_mask,cur_dir, sizeof(pstring));
safe_strcat(mtar_mask,"*", sizeof(pstring));
pstrcpy(mtar_mask,cur_dir);
pstrcat(mtar_mask,"*");
DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
do_list(mtar_mask, attribute, do_tar, False, True);
safe_strcpy(cur_dir,saved_curdir, sizeof(pstring));
pstrcpy(cur_dir,saved_curdir);
}
else
{
safe_strcpy(rname,cur_dir, sizeof(pstring));
safe_strcat(rname,finfo->name, sizeof(pstring));
pstrcpy(rname,cur_dir);
pstrcat(rname,finfo->name);
do_atar(rname,finfo->name,finfo);
}
}
@ -1362,8 +1362,8 @@ int cmd_setmode(void)
return 1;
}
safe_strcpy(fname, cur_dir, sizeof(pstring));
safe_strcat(fname, buf, sizeof(pstring));
pstrcpy(fname, cur_dir);
pstrcat(fname, buf);
while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
q=buf;
@ -1459,32 +1459,32 @@ int process_tar(void)
if (strrchr_m(cliplist[i], '\\')) {
pstring saved_dir;
safe_strcpy(saved_dir, cur_dir, sizeof(pstring));
pstrcpy(saved_dir, cur_dir);
if (*cliplist[i]=='\\') {
safe_strcpy(tarmac, cliplist[i], sizeof(pstring));
pstrcpy(tarmac, cliplist[i]);
} else {
safe_strcpy(tarmac, cur_dir, sizeof(pstring));
safe_strcat(tarmac, cliplist[i], sizeof(pstring));
pstrcpy(tarmac, cur_dir);
pstrcat(tarmac, cliplist[i]);
}
safe_strcpy(cur_dir, tarmac, sizeof(pstring));
pstrcpy(cur_dir, tarmac);
*(strrchr_m(cur_dir, '\\')+1)='\0';
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
safe_strcpy(cur_dir,saved_dir, sizeof(pstring));
pstrcpy(cur_dir,saved_dir);
} else {
safe_strcpy(tarmac, cur_dir, sizeof(pstring));
safe_strcat(tarmac, cliplist[i], sizeof(pstring));
pstrcpy(tarmac, cur_dir);
pstrcat(tarmac, cliplist[i]);
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
}
}
} else {
pstring mask;
safe_strcpy(mask,cur_dir, sizeof(pstring));
pstrcpy(mask,cur_dir);
DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
safe_strcat(mask,"\\*", sizeof(pstring));
pstrcat(mask,"\\*");
do_list(mask,attribute,do_tar,False, True);
}

View File

@ -656,6 +656,24 @@ if test x"$samba_cv_immediate_structures" = x"yes"; then
AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES,1,[Whether the compiler supports immediate structures])
fi
############################################
# check if the compiler can do immediate structures
AC_CACHE_CHECK([if the compiler will optimize out function calls],samba_cv_optimize_out_funcation_calls, [
AC_TRY_LINK([
#include <stdio.h>],
[
if (0) {
this_function_does_not_exist();
} else {
return 1;
}
],
samba_cv_optimize_out_funcation_calls=yes,samba_cv_optimize_out_funcation_calls=no)])
if test x"$samba_cv_optimize_out_funcation_calls" = x"yes"; then
AC_DEFINE(HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS,1,[Whether the compiler will optimize out function calls])
fi
############################################
# check for unix domain sockets
AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [

View File

@ -832,6 +832,7 @@ struct printjob;
/* String routines */
#include "srvstr.h"
#include "safe_string.h"
#ifdef __COMPAR_FN_T

View File

@ -129,11 +129,17 @@ size_t __unsafe_string_function_usage_here_char__(void);
safe_strcpy(dest, src, sizeof(pstring)-PTR_DIFF(dest,pstring_base)-1)
/* inside the _fn varients of these is a call to 'clobber_region' - which might
destory the stack on a buggy function. Help the debugging process by putting
the function and line it was last called from into a static buffer
/* Inside the _fn variants of these is a call to clobber_region(), -
* which might destroy the stack on a buggy function. We help the
* debugging process by putting the function and line who last caused
* a clobbering into a static buffer. If the program crashes at
* address 0xf1f1f1f1 then this function is probably, but not
* necessarily, to blame. */
But only for developers */
/* overmalloc_safe_strcpy: DEPRECATED! Used when you know the
* destination buffer is longer than maxlength, but you don't know how
* long. This is not a good situation, because we can't do the normal
* sanity checks. Don't use in new code! */
#ifdef DEVELOPER
#define overmalloc_safe_strcpy(dest,src,maxlength) safe_strcpy_fn(__FUNCTION__,__LINE__,dest,src,maxlength)
@ -214,7 +220,4 @@ size_t __unsafe_string_function_usage_here_char__(void);
#define strlower(s) strlower_m(s)
#define strupper(s) strupper_m(s)
#define safe_strcpy_base(dest, src, base, size) \
safe_strcpy(dest, src, size-PTR_DIFF(dest,base)-1)
#endif

View File

@ -66,7 +66,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
memcpy(pword, pass, passlen);
} else if (passlen > 0) {
/* Plaintext mode needed, assume plaintext supplied. */
passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
}
/* send a session setup command */
@ -774,7 +774,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
/*
* Non-encrypted passwords - convert to DOS codepage before using.
*/
passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
} else {
memcpy(pword, pass, passlen);
}

View File

@ -948,7 +948,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path)
pstring path2;
char *p;
safe_strcpy(path2,path,sizeof(pstring));
pstrcpy(path2,path);
trim_string(path2,NULL,"\\");
if (!*path2) *path2 = '\\';

View File

@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,6,info_level);
SIVAL(param,8,0);
p = param+12;
p += clistr_push(cli, param+12, mask, -1,
p += clistr_push(cli, param+12, mask, sizeof(param)-12,
STR_TERMINATE);
} else {
setup = TRANSACT2_FINDNEXT;
@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SIVAL(param,6,0); /* ff_resume_key */
SSVAL(param,10,8+4+2); /* continue + resume required + close on end */
p = param+12;
p += clistr_push(cli, param+12, mask, -1,
p += clistr_push(cli, param+12, mask, sizeof(param)-12,
STR_TERMINATE);
}

View File

@ -137,8 +137,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
safe_strcat(response,state->request.data.winsreq,maxlen);
safe_strcat(response,"\t",maxlen);
fstrcat(response,state->request.data.winsreq);
fstrcat(response,"\t");
for (i = 0; i < count; i++) {
/* ignore group names */
if (status[i].flags & 0x80) continue;
@ -148,8 +148,8 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
SAFE_FREE(status);
return WINBINDD_ERROR;
}
safe_strcat(response, status[i].name, maxlen);
safe_strcat(response, " ", maxlen);
fstrcat(response, status[i].name);
fstrcat(response, " ");
}
}
/* make last character a newline */
@ -190,16 +190,16 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
/* Clear out the newline character */
response[strlen(response)-1] = ' ';
}
safe_strcat(response,addr,maxlen);
safe_strcat(response,"\t",maxlen);
fstrcat(response,addr);
fstrcat(response,"\t");
}
size = strlen(state->request.data.winsreq) + strlen(response);
if (size > maxlen) {
SAFE_FREE(ip_list);
return WINBINDD_ERROR;
}
safe_strcat(response,state->request.data.winsreq,maxlen);
safe_strcat(response,"\n",maxlen);
fstrcat(response,state->request.data.winsreq);
fstrcat(response,"\n");
SAFE_FREE(ip_list);
} else
return WINBINDD_ERROR;

View File

@ -167,7 +167,7 @@ static int reply_lanman2(char *inbuf, char *outbuf)
static int negprot_spnego(char *p)
{
DATA_BLOB blob;
uint8 guid[16];
uint8 guid[17];
const char *OIDs_krb5[] = {OID_KERBEROS5,
OID_KERBEROS5_OLD,
OID_NTLMSSP,
@ -178,8 +178,8 @@ static int negprot_spnego(char *p)
global_spnego_negotiated = True;
memset(guid, 0, 16);
safe_strcpy((char *)guid, global_myname(), 16);
ZERO_STRUCT(guid);
safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1);
strlower((char *)guid);
#if 0

View File

@ -161,7 +161,7 @@ int reply_tcon(connection_struct *conn,
*service_buf = *password = *dev = 0;
p = smb_buf(inbuf)+1;
p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
p += pwlen;
p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;

View File

@ -1,41 +0,0 @@
/*
Unix SMB/CIFS implementation.
server specific string routines
Copyright (C) Andrew Tridgell 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
int srvstr_push(void *base_ptr, void *dest, const char *src, int dest_len, int flags)
{
return push_string(base_ptr, dest, src, dest_len, flags);
}
int srvstr_pull(void *base_ptr, char *dest, const void *src, int dest_len, int src_len,
int flags)
{
return pull_string(base_ptr, dest, src, dest_len, src_len, flags);
}
/* pull a string from the smb_buf part of a packet. In this case the
string can either be null terminated or it can be terminated by the
end of the smbbuf area
*/
int srvstr_pull_buf(void *inbuf, char *dest, const void *src, int dest_len, int flags)
{
return pull_string(inbuf, dest, src, dest_len, smb_bufrem(inbuf, src), flags);
}

View File

@ -241,7 +241,7 @@ BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *dom
if (!lookup_dc_name(global_myname(), domain_name, server_ip, dc_name))
return False;
safe_strcpy(server_name, dc_name, FSTRING_LEN);
fstrcpy(server_name, dc_name);
return True;
} else
return False;

View File

@ -638,7 +638,7 @@ static int rap_user_add(int argc, const char **argv)
if (!(cli = net_make_ipc_connection(0)))
return -1;
safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name));
safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name)-1);
if (opt_flags == -1)
opt_flags = 0x21;
@ -755,7 +755,7 @@ static int rap_group_add(int argc, const char **argv)
return -1;
/* BB check for length 21 or smaller explicitly ? BB */
safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name));
safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
grinfo.reserved1 = '\0';
grinfo.comment = smb_xstrdup(opt_comment);

View File

@ -363,20 +363,21 @@ static int new_machine (struct pdb_context *in, const char *machine_in)
{
SAM_ACCOUNT *sam_pwent=NULL;
fstring machinename;
fstring machineaccount;
struct passwd *pwd = NULL;
char name[16];
fstrcpy(machinename, machine_in);
machinename[15]= '\0';
if (machinename[strlen (machinename) -1] == '$')
machinename[strlen (machinename) -1] = '\0';
strlower_m(machinename);
safe_strcpy (name, machinename, 16);
safe_strcat (name, "$", 16);
fstrcpy(machineaccount, machinename);
fstrcat(machineaccount, "$");
if ((pwd = getpwnam_alloc(name))) {
if ((pwd = getpwnam_alloc(machineaccount))) {
if (!NT_STATUS_IS_OK(pdb_init_sam_pw( &sam_pwent, pwd))) {
fprintf(stderr, "Could not init sam from pw\n");
passwd_free(&pwd);
@ -392,14 +393,14 @@ static int new_machine (struct pdb_context *in, const char *machine_in)
pdb_set_plaintext_passwd (sam_pwent, machinename);
pdb_set_username (sam_pwent, name, PDB_CHANGED);
pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED);
pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED);
pdb_set_group_sid_from_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS, PDB_CHANGED);
if (NT_STATUS_IS_OK(in->pdb_add_sam_account (in, sam_pwent))) {
print_user_info (in, name, True, False);
print_user_info (in, machineaccount, True, False);
} else {
fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
pdb_free_sam (&sam_pwent);
@ -435,12 +436,13 @@ static int delete_user_entry (struct pdb_context *in, const char *username)
static int delete_machine_entry (struct pdb_context *in, const char *machinename)
{
char name[16];
fstring name;
SAM_ACCOUNT *samaccount = NULL;
safe_strcpy (name, machinename, 16);
if (name[strlen(name)] != '$')
safe_strcat (name, "$", 16);
fstrcpy(name, machinename);
name[15] = '\0';
if (name[strlen(name)-1] != '$')
fstrcat (name, "$");
if (!NT_STATUS_IS_OK(pdb_init_sam (&samaccount))) {
return -1;

View File

@ -916,7 +916,7 @@ You can string acls together with spaces, commas or newlines\n\
if (filename[0] != '\\') {
pstring s;
s[0] = '\\';
safe_strcpy(&s[1], filename, sizeof(pstring)-1);
safe_strcpy(&s[1], filename, sizeof(pstring)-2);
pstrcpy(filename, s);
}