Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #106168
| From | Mike Small <smallm@sdf.org> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | openssh do_log function has larger than needed buffer? |
| Date | 2017-03-15 19:49 +0000 |
| Organization | SDF Public Access UNIX System, Est. 1987 |
| Message-ID | <chx8to6l3qh.fsf@iceland.freeshell.org> (permalink) |
Hello,
I was looking at a function in OpenSSH that prepares a string for
logging and calls syslog with a format string limiting the length of
what is written. I'm puzzled by the difference between the size of the
char array used to compose the string (1024 bytes) and the limit on the
number of its characters that could be output by syslog (format
specifier "%.500s").
The only potential explanation I could think of was that it might have
something to do with multibyte strings, that maybe a string could be
devised such that the buffer would overrun from use of characters
encoded by more than one byte. But looking at the function calls before
the syslog call I'm thinking the string should be guaranteed to be nul
terminated, which I think prevents overrun even if there are multibyte
characters included. Also, if that were the reason (and the nul
character not present) I don't think roughly double the size would be
sufficient, since some utf-8 characters require more than two bytes.
I looked at the history of the file in openssh's cvs web interface
hoping to find a change with a check-in comment. The code has evolved
some but this ratio of buffer size to syslog format string precision
length existed before openssh forked Tatu Ylonen's code from the earlier
ssh project. So no such luck.
Below is the function and buffer size constant. These are from
log.c. Can you think of a reason for the difference in lengths? The
reason I ask is that I'm doubling the length of what can be logged from
500 to 1000 and wondering if I should also double the MSGBUFSIZ, this
for local purposes.
#define MSGBUFSIZ 1024
...
void
do_log(LogLevel level, const char *fmt, va_list args)
{
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
#endif
char msgbuf[MSGBUFSIZ];
char fmtbuf[MSGBUFSIZ];
char *txt = NULL;
int pri = LOG_INFO;
int saved_errno = errno;
log_handler_fn *tmp_handler;
if (level > log_level)
return;
switch (level) {
case SYSLOG_LEVEL_FATAL:
if (!log_on_stderr)
txt = "fatal";
pri = LOG_CRIT;
break;
... other cases elided for brevity ...
default:
txt = "internal error";
pri = LOG_ERR;
break;
}
if (txt != NULL && log_handler == NULL) {
snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
} else {
vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
}
strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
if (log_handler != NULL) {
/* Avoid recursion */
tmp_handler = log_handler;
log_handler = NULL;
tmp_handler(level, fmtbuf, log_handler_ctx);
log_handler = tmp_handler;
} else if (log_on_stderr) {
snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n",
(int)sizeof msgbuf - 3, fmtbuf);
(void)write(log_stderr_fd, msgbuf, strlen(msgbuf));
} else {
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
syslog_r(pri, &sdata, "%.500s", fmtbuf);
closelog_r(&sdata);
#else
openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
syslog(pri, "%.500s", fmtbuf);
closelog();
#endif
}
errno = saved_errno;
}
Just to cross my tees, because I'm not very knowledgeable about
copyright law and how it might apply to this post, this is the license
statement at the head of that file...
/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
--
Mike Small
smallm@sdf.org
Back to comp.lang.c | Previous | Next — Next in thread | Find similar | Unroll thread
openssh do_log function has larger than needed buffer? Mike Small <smallm@sdf.org> - 2017-03-15 19:49 +0000 Re: openssh do_log function has larger than needed buffer? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-16 14:25 +0000
csiph-web