From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/lib/charset.c | 4 ++- source3/lib/pidfile.c | 4 +-- source3/lib/slprintf.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ source3/lib/system.c | 2 +- source3/lib/util.c | 6 ++-- source3/lib/util_hnd.c | 6 ++-- 6 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 source3/lib/slprintf.c (limited to 'source3/lib') diff --git a/source3/lib/charset.c b/source3/lib/charset.c index fe170bdcf5..d8ce38f396 100644 --- a/source3/lib/charset.c +++ b/source3/lib/charset.c @@ -203,7 +203,9 @@ static codepage_p load_client_codepage( int client_codepage ) strcpy(codepage_file_name, CODEPAGEDIR); strcat(codepage_file_name, "/"); strcat(codepage_file_name, "codepage."); - sprintf( &codepage_file_name[strlen(codepage_file_name)], "%03d", + slprintf(&codepage_file_name[strlen(codepage_file_name)], + sizeof(pstring)-(strlen(codepage_file_name)+1), + "%03d", client_codepage); if(!file_exist(codepage_file_name,&st)) diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c index 6cad1436eb..46d6a9d5b8 100644 --- a/source3/lib/pidfile.c +++ b/source3/lib/pidfile.c @@ -37,7 +37,7 @@ void pidfile_create(char *name) pstring pidFile; int pid; - sprintf(pidFile, "%s/%s.pid", lp_lockdir(), name); + slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name); pid = pidfile_pid(name); if (pid > 0 && process_exists(pid)) { @@ -76,7 +76,7 @@ int pidfile_pid(char *name) pstring pidFile; unsigned ret; - sprintf(pidFile, "%s/%s.pid", lp_lockdir(), name); + slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name); f = fopen(pidFile, "r"); if (!f) { diff --git a/source3/lib/slprintf.c b/source3/lib/slprintf.c new file mode 100644 index 0000000000..e2dc0e1235 --- /dev/null +++ b/source3/lib/slprintf.c @@ -0,0 +1,88 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + snprintf replacement + Copyright (C) Andrew Tridgell 1998 + + 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" + +extern int DEBUGLEVEL; + +int vslprintf(char *str, int n, char *format, va_list ap) +{ +#ifdef HAVE_VSNPRINTF + int ret = vsnprintf(str, n, format, ap); + if (ret >= 0) str[ret] = 0; + return ret; +#else + static char *buf; + static int len; + static int pagesize; + int ret; + + if (!len || !buf || (len-pagesize) < n) { + pagesize = getpagesize(); + len = (2+(n/pagesize))*pagesize; + /* 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 */ + buf = memalign(pagesize, len); + if (buf) { + if (mprotect(buf+(len-pagesize), pagesize, PROT_READ) != 0) { + exit(1); + return -1; + } + } + } + + if (!buf) { + exit(1); + } + + ret = vsprintf(str, format, ap); + /* we will have got a seg fault here if we overflowed the buffer */ + return ret; +#endif +} + +#ifdef __STDC__ +int slprintf(char *str, int n, char *format, ...) +{ +#else + int slprintf(va_alist) +va_dcl +{ + char *str, *format; + int n; +#endif + va_list ap; + int ret; + +#ifdef __STDC__ + va_start(ap, format); +#else + va_start(ap); + str = va_arg(ap,char *); + n = va_arg(ap,int); + format = va_arg(ap,char *); +#endif + + ret = vslprintf(str,n,format,ap); + va_end(ap); + return ret; +} diff --git a/source3/lib/system.c b/source3/lib/system.c index 3eef8e5034..f453741fdd 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -411,7 +411,7 @@ struct hostent *sys_gethostbyname(char *name) if((strlen(name) + strlen(domain)) >= sizeof(query)) return(gethostbyname(name)); - sprintf(query, "%s%s", name, domain); + slprintf(query, sizeof(query)-1, "%s%s", name, domain); return(gethostbyname(query)); #else /* REDUCE_ROOT_DNS_LOOKUPS */ return(gethostbyname(name)); diff --git a/source3/lib/util.c b/source3/lib/util.c index 2f637e1495..ee87d48388 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -226,7 +226,7 @@ static void check_log_size(void) if (dbf && file_size(debugf) > maxlog) { pstring name; fclose(dbf); dbf = NULL; - sprintf(name,"%s.old",debugf); + slprintf(name,sizeof(name)-1,"%s.old",debugf); sys_rename(debugf,name); reopen_logs(); } @@ -313,7 +313,7 @@ va_dcl va_start(ap); format_str = va_arg(ap,char *); #endif - vsprintf(msgbuf, format_str, ap); + vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap); va_end(ap); msgbuf[255] = '\0'; @@ -3839,7 +3839,7 @@ static char *automount_lookup(char *user_name) if (strcmp(user_name, last_key)) { - sprintf(buffer, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain); + slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain); DEBUG(5, ("NIS+ querystring: %s\n", buffer)); if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL)) diff --git a/source3/lib/util_hnd.c b/source3/lib/util_hnd.c index c8eabf35b4..1d1341d16e 100644 --- a/source3/lib/util_hnd.c +++ b/source3/lib/util_hnd.c @@ -115,7 +115,7 @@ BOOL open_lsa_policy_hnd(POLICY_HND *hnd) memcpy(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)); DEBUG(4,("Opened policy hnd[%x] ", i)); - dump_data(4, hnd->data, sizeof(hnd->data)); + dump_data(4, (char *)hnd->data, sizeof(hnd->data)); return True; } @@ -143,14 +143,14 @@ int find_lsa_policy_by_hnd(POLICY_HND *hnd) if (memcmp(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)) == 0) { DEBUG(4,("Found policy hnd[%x] ", i)); - dump_data(4, hnd->data, sizeof(hnd->data)); + dump_data(4, (char *)hnd->data, sizeof(hnd->data)); return i; } } DEBUG(4,("Policy not found: ")); - dump_data(4, hnd->data, sizeof(hnd->data)); + dump_data(4, (char *)hnd->data, sizeof(hnd->data)); return -1; } -- cgit