From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/lib/charset.c | 6 +- source3/lib/genrand.c | 2 +- source3/lib/kanji.c | 26 +++---- source3/lib/pidfile.c | 2 +- source3/lib/slprintf.c | 8 +++ source3/lib/time.c | 2 +- source3/lib/util.c | 190 ++++++++++++++++++++++++++++++++----------------- 7 files changed, 152 insertions(+), 84 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/charset.c b/source3/lib/charset.c index d8ce38f396..db331af115 100644 --- a/source3/lib/charset.c +++ b/source3/lib/charset.c @@ -200,9 +200,9 @@ static codepage_p load_client_codepage( int client_codepage ) return NULL; } - strcpy(codepage_file_name, CODEPAGEDIR); - strcat(codepage_file_name, "/"); - strcat(codepage_file_name, "codepage."); + pstrcpy(codepage_file_name, CODEPAGEDIR); + pstrcat(codepage_file_name, "/"); + pstrcat(codepage_file_name, "codepage."); slprintf(&codepage_file_name[strlen(codepage_file_name)], sizeof(pstring)-(strlen(codepage_file_name)+1), "%03d", diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c index b09f683e62..5e87275ce8 100644 --- a/source3/lib/genrand.c +++ b/source3/lib/genrand.c @@ -84,7 +84,7 @@ static void do_dirrand(char *name, unsigned char *buf, int buf_len) struct stat st; if(strlen(p) <= len_left) - strcpy(pos, p); + pstrcpy(pos, p); if(sys_stat(fullname,&st) == 0) { SIVAL(buf, ((counter * 4)%(buf_len-4)), diff --git a/source3/lib/kanji.c b/source3/lib/kanji.c index 401e91e534..afe255d36a 100644 --- a/source3/lib/kanji.c +++ b/source3/lib/kanji.c @@ -419,7 +419,7 @@ static char *sj_to_euc(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy((char *) save, (char *) cvtbuf); + pstrcpy((char *) save, (char *) cvtbuf); return (char *) save; } else { return cvtbuf; @@ -451,7 +451,7 @@ static char *euc_to_sj(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy(save, (char *) cvtbuf); + pstrcpy(save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -522,7 +522,7 @@ static char *jis8_to_sj(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -578,7 +578,7 @@ static char *sj_to_jis8(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -637,7 +637,7 @@ static char *jis7_to_sj(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -713,7 +713,7 @@ static char *sj_to_jis7(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -769,7 +769,7 @@ static char *junet_to_sj(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -838,7 +838,7 @@ static char *sj_to_junet(char *from, BOOL overwrite) } *out = 0; if (overwrite) { - strcpy (save, (char *) cvtbuf); + pstrcpy (save, (char *) cvtbuf); return save; } else { return cvtbuf; @@ -864,7 +864,7 @@ static char *hex_to_sj(char *from, BOOL overwrite) } *dp = '\0'; if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); + pstrcpy ((char *) from, (char *) cvtbuf); return (char *) from; } else { return cvtbuf; @@ -900,7 +900,7 @@ static char *sj_to_hex(char *from, BOOL overwrite) } *dp = '\0'; if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); + pstrcpy ((char *) from, (char *) cvtbuf); return (char *) from; } else { return cvtbuf; @@ -932,7 +932,7 @@ static char *cap_to_sj(char *from, BOOL overwrite) } *dp = '\0'; if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); + pstrcpy ((char *) from, (char *) cvtbuf); return (char *) from; } else { return cvtbuf; @@ -960,7 +960,7 @@ static char *sj_to_cap(char *from, BOOL overwrite) } *dp = '\0'; if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); + pstrcpy ((char *) from, (char *) cvtbuf); return (char *) from; } else { return cvtbuf; @@ -973,7 +973,7 @@ static char *sj_to_cap(char *from, BOOL overwrite) static char *sj_to_sj(char *from, BOOL overwrite) { if (!overwrite) { - strcpy (cvtbuf, (char *) from); + pstrcpy (cvtbuf, (char *) from); return cvtbuf; } else { return (char *) from; diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c index 46d6a9d5b8..9cb3f5afef 100644 --- a/source3/lib/pidfile.c +++ b/source3/lib/pidfile.c @@ -58,7 +58,7 @@ void pidfile_create(char *name) } memset(buf, 0, sizeof(buf)); - sprintf(buf, "%u\n", (unsigned int) getpid()); + slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) getpid()); if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno))); diff --git a/source3/lib/slprintf.c b/source3/lib/slprintf.c index e2dc0e1235..9a00585ca8 100644 --- a/source3/lib/slprintf.c +++ b/source3/lib/slprintf.c @@ -41,7 +41,15 @@ int vslprintf(char *str, int n, char *format, va_list ap) /* note: we don't free the old memory (if any) as we don't want a malloc lib to reuse the memory as it will have the wrong permissions */ +#ifdef HAVE_MEMALIGN buf = memalign(pagesize, len); +#else /* HAVE_MEMALIGN */ +#ifdef HAVE_VALLOC + buf = valloc(len); +#else /* HAVE_VALLOC */ + buf = malloc(len); +#endif /* HAVE_VALLOC */ +#endif /* HAVE_MEMALIGN */ if (buf) { if (mprotect(buf+(len-pagesize), pagesize, PROT_READ) != 0) { exit(1); diff --git a/source3/lib/time.c b/source3/lib/time.c index 716f5d62cc..f5c40f0ba0 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -486,7 +486,7 @@ char *timestring(void ) int zone = TimeDiff(t); int absZoneMinutes = (zone<0 ? -zone : zone) / 60; size_t len = strftime(TimeBuf,sizeof(TimeBuf)-6,"%Y/%m/%d %T",tm); - sprintf(TimeBuf+len," %c%02d%02d", + slprintf(TimeBuf+len, sizeof(fstring) - len - 1, " %c%02d%02d", zone<0?'+':'-',absZoneMinutes/60,absZoneMinutes%60); } #else diff --git a/source3/lib/util.c b/source3/lib/util.c index d2600512e2..f1ea1931c5 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -178,14 +178,14 @@ void reopen_logs(void) if (DEBUGLEVEL > 0) { - strcpy(fname,debugf); + pstrcpy(fname,debugf); if (lp_loaded() && (*lp_logfile())) - strcpy(fname,lp_logfile()); + pstrcpy(fname,lp_logfile()); if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) { int oldumask = umask(022); - strcpy(debugf,fname); + pstrcpy(debugf,fname); if (dbf) fclose(dbf); if (append_log) dbf = fopen(debugf,"a"); @@ -581,7 +581,7 @@ set user socket options ****************************************************************************/ void set_socket_options(int fd, char *options) { - string tok; + fstring tok; while (next_token(&options,tok," \t,")) { @@ -767,7 +767,7 @@ int name_mangle( char *In, char *Out, char name_type ) if( '*' == In[0] ) buf[0] = '*'; else - (void)sprintf( buf, "%-15.15s%c", In, name_type ); + (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); /* Place the length of the first field into the output buffer. */ p[0] = 32; @@ -869,16 +869,16 @@ return a string representing an attribute for a file ********************************************************************/ char *attrib_string(int mode) { - static char attrstr[10]; + static fstring attrstr; attrstr[0] = 0; - if (mode & aVOLID) strcat(attrstr,"V"); - if (mode & aDIR) strcat(attrstr,"D"); - if (mode & aARCH) strcat(attrstr,"A"); - if (mode & aHIDDEN) strcat(attrstr,"H"); - if (mode & aSYSTEM) strcat(attrstr,"S"); - if (mode & aRONLY) strcat(attrstr,"R"); + if (mode & aVOLID) fstrcat(attrstr,"V"); + if (mode & aDIR) fstrcat(attrstr,"D"); + if (mode & aARCH) fstrcat(attrstr,"A"); + if (mode & aHIDDEN) fstrcat(attrstr,"H"); + if (mode & aSYSTEM) fstrcat(attrstr,"S"); + if (mode & aRONLY) fstrcat(attrstr,"R"); return(attrstr); } @@ -1244,8 +1244,8 @@ void unix_format(char *fname) if (*fname == '/') { pstrcpy(namecopy,fname); - strcpy(fname,"."); - strcat(fname,namecopy); + pstrcpy(fname,"."); + pstrcat(fname,namecopy); } } @@ -1447,7 +1447,7 @@ void dos_clean_name(char *s) *p = 0; else *s = 0; - strcat(s,s1); + pstrcat(s,s1); } trim_string(s,NULL,"\\.."); @@ -1471,7 +1471,7 @@ void unix_clean_name(char *s) if(strncmp(s, "./", 2) == 0) { trim_string(s, "./", NULL); if(*s == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); } while ((p = strstr(s,"/../")) != NULL) @@ -1485,7 +1485,7 @@ void unix_clean_name(char *s) *p = 0; else *s = 0; - strcat(s,s1); + pstrcat(s,s1); } trim_string(s,NULL,"/.."); @@ -1578,7 +1578,7 @@ char *GetWd(char *str) st.st_dev == st2.st_dev && (st2.st_mode & S_IFMT) == S_IFDIR) { - strcpy (str, ino_list[i].text); + pstrcpy (str, ino_list[i].text); /* promote it for future use */ array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); @@ -1605,7 +1605,7 @@ char *GetWd(char *str) return (NULL); } - strcpy(str,s); + pstrcpy(str,s); DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev)); @@ -1656,7 +1656,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) } if (strlen(s) == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); return(True); } @@ -1717,8 +1717,8 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) if (p && (p != base_name)) { - strcat(newname,"/"); - strcat(newname,p+1); + pstrcat(newname,"/"); + pstrcat(newname,p+1); } { @@ -1747,7 +1747,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) ChDir(wd); if (strlen(s) == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); DEBUG(3,("reduced to %s\n",s)); return(True); @@ -1802,7 +1802,7 @@ void expand_mask(char *Mask,BOOL doext) } else { - strcpy(mext,""); + pstrcpy(mext,""); if (strlen(mbeg) > 8) { pstrcpy(mext,mbeg + 8); @@ -1811,12 +1811,12 @@ void expand_mask(char *Mask,BOOL doext) } if (*mbeg == 0) - strcpy(mbeg,"????????"); + pstrcpy(mbeg,"????????"); if ((*mext == 0) && doext && !hasdot) - strcpy(mext,"???"); + pstrcpy(mext,"???"); if (strequal(mbeg,"*") && *mext==0) - strcpy(mext,"*"); + pstrcpy(mext,"*"); /* expand *'s */ expand_one(mbeg,8); @@ -1824,10 +1824,10 @@ void expand_mask(char *Mask,BOOL doext) expand_one(mext,3); pstrcpy(Mask,dirpart); - if (*dirpart || absolute) strcat(Mask,"\\"); - strcat(Mask,mbeg); - strcat(Mask,"."); - strcat(Mask,mext); + if (*dirpart || absolute) pstrcat(Mask,"\\"); + pstrcat(Mask,mbeg); + pstrcat(Mask,"."); + pstrcat(Mask,mext); DEBUG(6,("Mask expanded to [%s]\n",Mask)); } @@ -2769,7 +2769,7 @@ int name_extract(char *buf,int ofs,char *name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); - strcpy(name,""); + pstrcpy(name,""); if (d < -50 || d > 50) return(0); return(name_interpret(p,name)); } @@ -2913,7 +2913,7 @@ BOOL string_init(char **dest,char *src) return False; } - strcpy(*dest,src); + pstrcpy(*dest,src); } return(True); } @@ -3057,12 +3057,12 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) StrnCpy(p2,str,sizeof(pstring)-1); if (!strchr(p2,'.')) { - strcat(p2,"."); + pstrcat(p2,"."); } /* if (!strchr(p1,'.')) { - strcat(p1,"."); + pstrcat(p1,"."); } */ @@ -3077,7 +3077,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) /* Remove any *? and ** as they are meaningless */ for(p = p1; *p; p++) while( *p == '*' && (p[1] == '?' ||p[1] == '*')) - (void)strcpy( &p[1], &p[2]); + (void)pstrcpy( &p[1], &p[2]); if (strequal(p1,"*")) return(True); @@ -3310,11 +3310,11 @@ char *dirname_dos(char *path,char *buf) char *p = strrchr(path,'\\'); if (!p) - strcpy(buf,path); + pstrcpy(buf,path); else { *p = 0; - strcpy(buf,path); + pstrcpy(buf,path); *p = '\\'; } @@ -3330,9 +3330,9 @@ static char *filename_dos(char *path,char *buf) char *p = strrchr(path,'\\'); if (!p) - strcpy(buf,path); + pstrcpy(buf,path); else - strcpy(buf,p+1); + pstrcpy(buf,p+1); return(buf); } @@ -3373,7 +3373,7 @@ duplicate a string if (!s) return(NULL); ret = (char *)malloc(strlen(s)+1); if (!ret) return(NULL); - strcpy(ret,s); + pstrcpy(ret,s); return(ret); } #endif @@ -3748,7 +3748,7 @@ char *client_name(int fd) last_fd = fd; global_client_name_done = False; - strcpy(name_buf,"UNKNOWN"); + pstrcpy(name_buf,"UNKNOWN"); if (fd == -1) { return name_buf; @@ -3769,7 +3769,7 @@ char *client_name(int fd) StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); if (!matchname(name_buf, sockin->sin_addr)) { DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd))); - strcpy(name_buf,"UNKNOWN"); + pstrcpy(name_buf,"UNKNOWN"); } } global_client_name_done = True; @@ -3793,7 +3793,7 @@ char *client_addr(int fd) last_fd = fd; global_client_addr_done = False; - strcpy(addr_buf,"0.0.0.0"); + fstrcpy(addr_buf,"0.0.0.0"); if (fd == -1) { return addr_buf; @@ -3980,7 +3980,7 @@ char *automount_path(char *user_name) { DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n", home_path_start?(home_path_start+1):"")); - strcpy(server_path, home_path_start+1); + pstrcpy(server_path, home_path_start+1); } } #endif @@ -4029,7 +4029,7 @@ void standard_sub_basic(char *str) case 'a' : string_sub(p,"%a", remote_arch); break; case 'd' : { - sprintf(pidstr,"%d",(int)getpid()); + slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid()); string_sub(p,"%d", pidstr); break; } @@ -4184,7 +4184,7 @@ char *uidtoname(int uid) static char name[40]; struct passwd *pass = getpwuid(uid); if (pass) return(pass->pw_name); - sprintf(name,"%d",uid); + slprintf(name, sizeof(name) - 1, "%d",uid); return(name); } @@ -4196,7 +4196,7 @@ char *gidtoname(int gid) static char name[40]; struct group *grp = getgrgid(gid); if (grp) return(grp->gr_name); - sprintf(name,"%d",gid); + slprintf(name,sizeof(name) - 1, "%d",gid); return(name); } @@ -4600,23 +4600,23 @@ void set_remote_arch(enum remote_arch_types type) switch( type ) { case RA_WFWG: - strcpy(remote_arch, "WfWg"); + fstrcpy(remote_arch, "WfWg"); return; case RA_OS2: - strcpy(remote_arch, "OS2"); + fstrcpy(remote_arch, "OS2"); return; case RA_WIN95: - strcpy(remote_arch, "Win95"); + fstrcpy(remote_arch, "Win95"); return; case RA_WINNT: - strcpy(remote_arch, "WinNT"); + fstrcpy(remote_arch, "WinNT"); return; case RA_SAMBA: - strcpy(remote_arch,"Samba"); + fstrcpy(remote_arch,"Samba"); return; default: ra_type = RA_UNKNOWN; - strcpy(remote_arch, "UNKNOWN"); + fstrcpy(remote_arch, "UNKNOWN"); break; } } @@ -4793,7 +4793,7 @@ int unistrcpy(char *dst, char *src) return num_wchars; } - +#if 0 /******************************************************************* safe string copy into a fstring ********************************************************************/ @@ -4824,34 +4824,94 @@ void fstrcpy(char *dest, char *src) } /******************************************************************* -safe string copy into a pstring +safe string cat into a fstring ********************************************************************/ -void pstrcpy(char *dest, char *src) +void fstrcat(char *dest, char *src) { - int maxlength = sizeof(pstring) - 1; - int len; + int maxlength = sizeof(fstring) - 1; + int src_len, dest_len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); + DEBUG(0,("ERROR: NULL dest in fstrcat\n")); return; } if (!src) { - *dest = 0; return; } + src_len = strlen(src); + dest_len = strlen(dest); + + if (src_len + dest_len > maxlength) { + DEBUG(0,("ERROR: string overflow by %d in fstrcat [%.50s]\n", + src_len + dest_len - maxlength, src)); + src_len = maxlength - dest_len; + } + + memcpy(&dest[dest_len], src, src_len); + dest[dest_len + src_len] = 0; +} +#endif + +/******************************************************************* +safe string copy into a known length string +********************************************************************/ +char *safe_strcpy(char *dest, char *src, int maxlength) +{ + int len; + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); + return NULL; + } + + if (!src) { + *dest = 0; + return dest; + } + len = strlen(src); if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d in pstrcpy [%.50s]\n", + DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n", len-maxlength, src)); len = maxlength; } memcpy(dest, src, len); dest[len] = 0; + return dest; } +/******************************************************************* +safe string cat into a string +********************************************************************/ +char *safe_strcat(char *dest, char *src, int maxlength) +{ + int src_len, dest_len; + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); + return NULL; + } + + if (!src) { + return dest; + } + + src_len = strlen(src); + dest_len = strlen(dest); + + if (src_len + dest_len > maxlength) { + DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", + src_len + dest_len - maxlength, src)); + src_len = maxlength - dest_len; + } + + memcpy(&dest[dest_len], src, src_len); + dest[dest_len + src_len] = 0; + return dest; +} /******************************************************************* align a pointer to a multiple of 4 bytes @@ -4954,12 +5014,12 @@ char *dom_sid_to_string(DOM_SID *sid) (sid->id_auth[3] << 16) + (sid->id_auth[2] << 24); - sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia); + slprintf(sidstr, sizeof(sidstr) - 1, "S-%d-%d", sid->sid_rev_num, ia); for (i = 0; i < sid->num_auths; i++) { - sprintf(subauth, "-%d", sid->sub_auths[i]); - strcat(sidstr, subauth); + slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]); + pstrcat(sidstr, subauth); } DEBUG(7,("dom_sid_to_string returning %s\n", sidstr)); -- cgit