summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-05-12 12:48:54 +0000
committerAndrew Tridgell <tridge@samba.org>1998-05-12 12:48:54 +0000
commit1dadc7af9534977c8c384fd3e54e506710fb3659 (patch)
treedcb17d07171b884cb259475b5504c63e6fad1c15 /source3/lib
parentf888868f46a5418bac9ab528497136c152895305 (diff)
downloadsamba-1dadc7af9534977c8c384fd3e54e506710fb3659.tar.gz
samba-1dadc7af9534977c8c384fd3e54e506710fb3659.tar.bz2
samba-1dadc7af9534977c8c384fd3e54e506710fb3659.zip
a new slprintf() function. This one is totally portable but a bit of a
kludge. It is a safe kludge with our current code but I would like to revisit it at some point in the future. The problem with the one I committed yesterday is it used non-portable functions. (it also had a bug in it, but that's another matter) This one works by just using vsprintf() into a 8k buffer and a memcpy from there. No memory protection tricks or other non-portable stuff. This is safe because all calls to slprintf() in samba use strings which have been through a pstrcpy and thus are less than 1024 bytes. No call uses more than 2 of these strings. See what I mean by kludge? Note that the 8k is way overkill but I like overkill :) Someday (after autoconf) we will replace this with something better, but meanwhile this is simple, secure and portable. (This used to be commit 4cfcc398c35c6726f14f485ae8e9ebcef180392f)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/slprintf.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/source3/lib/slprintf.c b/source3/lib/slprintf.c
index 9a00585ca8..3a7e268046 100644
--- a/source3/lib/slprintf.c
+++ b/source3/lib/slprintf.c
@@ -23,47 +23,61 @@
extern int DEBUGLEVEL;
+
+/* this is like vsnprintf but the 'n' limit does not include
+ the terminating null. So if you have a 1024 byte buffer then
+ pass 1023 for n */
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;
+ if (ret > n || ret < 0) {
+ str[n] = 0;
+ return -1;
+ }
+ str[ret] = 0;
return ret;
#else
static char *buf;
- static int len;
- static int pagesize;
+ static int len=8000;
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 */
-#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);
- return -1;
- }
+ /* this code is NOT a proper vsnprintf() implementation. It
+ relies on the fact that all calls to slprintf() in Samba
+ pass strings which have already been through pstrcpy() or
+ fstrcpy() and never more than 2 strings are
+ concatenated. This means the above buffer is absolutely
+ ample and can never be overflowed.
+
+ In the future we would like to replace this with a proper
+ vsnprintf() implementation but right now we need a solution
+ that is secure and portable. This is it. */
+
+ if (!buf) {
+ buf = malloc(len);
+ if (!buf) {
+ /* can't call debug or we would recurse */
+ exit(1);
}
}
- if (!buf) {
- exit(1);
+ ret = vsprintf(buf, format, ap);
+
+ if (ret < 0) {
+ str[0] = 0;
+ return -1;
}
- ret = vsprintf(str, format, ap);
- /* we will have got a seg fault here if we overflowed the buffer */
+ if (ret < n) {
+ n = ret;
+ } else if (ret > n) {
+ ret = -1;
+ }
+
+ buf[n] = 0;
+
+ memcpy(str, buf, n+1);
+
return ret;
#endif
}