>Number: 2941
>Category: apache-api
>Synopsis: ap_log_printf interprets constructed string as printf format
>string, not literal
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: apache
>State: open
>Class: sw-bug
>Submitter-Id: apache
>Arrival-Date: Tue Sep 1 14:40:01 PDT 1998
>Last-Modified:
>Originator: [EMAIL PROTECTED]
>Organization:
apache
>Release: 1.3.1
>Environment:
Solaris 2.5.1, Linux 2.x
>Description:
ap_log_printf calls ap_log_error to print the expanded string.
ap_log_error treats that processed string as a printf-style format,
not a literal.
API_EXPORT(void) ap_log_error (const char *file, int line, int level,
const server_rec *s, const char *fmt, ...);
API_EXPORT(void) ap_log_printf (const server_rec *s, const char *fmt, ...)
{
char buf[MAX_STRING_LEN];
va_list args;
va_start(args, fmt);
ap_vsnprintf(buf, sizeof(buf), fmt, args); /* construct buffer from
varargs */
ap_log_error(APLOG_MARK, APLOG_ERR, s, buf); /* use buffer as format, not
literal */
va_end(args);
}
This will cause ap_log_error_old and ap_log_unixerr to barf, too,
if the string contains %.
>How-To-Repeat:
One example:
int tripod_auth_fixups(request_rec *r) {
/* testing */
ap_log_printf(r->server, "a string: \"%s\"\n", "a string with %s escapes");
/* ap_log_error_old("a string with %s escapes",r->server); */
/* ap_log_unixerr("a routine","a file","a string with %s
escapes",r->server); */
}
running the server under gdb gives:
Program received signal SIGSEGV, Segmentation fault.
0xef5a3e74 in strlen ()
(gdb) bt
#0 0xef5a3e74 in strlen ()
#1 0x72094 in ap_vformatter (flush_func=0x72acc <snprintf_flush>,
vbuff=0xefffb508, fmt=0xefffd632 "s escapes\"\n",
ap=0xefffd60c) at ap_snprintf.c:766
#2 0x72c0c in ap_vsnprintf (buf=0xefffb5d9 "a string: \"a string with ",
len=8127,
format=0xefffd618 "a string: \"a string with %s escapes\"\n",
ap=0xefffd608) at ap_snprintf.c:1022
#3 0x52ab8 in ap_log_error (file=0x89aa8 "http_log.c", line=453, level=3,
s=0xd34a0,
fmt=0xefffd618 "a string: \"a string with %s escapes\"\n") at http_log.c:403
#4 0x52d4c in ap_log_printf (s=0xd34a0, fmt=0x80ac8 "a string: \"%s\"\n") at
http_log.c:453
#5 0x25dfc in tripod_auth_fixups (r=0xecc68) at mod_auth_tripod.c:499
#6 0x47d9c in run_method (r=0xecc68, offset=21, run_all=1) at http_config.c:357
#7 0x47f10 in ap_run_fixups (r=0xecc68) at http_config.c:384
#8 0x61d20 in process_request_internal (r=0xecc68) at http_request.c:1207
#9 0x61dc4 in ap_process_request (r=0xecc68) at http_request.c:1229
#10 0x571f4 in child_main (child_num_arg=2) at http_main.c:3638
#11 0x57534 in make_child (s=0xc2d40, slot=2, now=904684385) at http_main.c:3758
#12 0x5764c in startup_children (number_to_start=18) at http_main.c:3785
#13 0x57f28 in standalone_main (argc=3, argv=0xeffffba4) at http_main.c:4063
#14 0x58980 in main (argc=3, argv=0xeffffba4) at http_main.c:4336
>Fix:
ap_log_printf calls ap_log_error to print the processed string.
ap_log_error treats the processed string as a printf-style format,
not a literal. If ap_log_printf (and the other ap_log_* functions
that take a string literal) called a log-error function
that prints an unmolested string literal, the problem would be solved.
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <[EMAIL PROTECTED]> in the Cc line ]
[and leave the subject line UNCHANGED. This is not done]
[automatically because of the potential for mail loops. ]
[If you do not include this Cc, your reply may be ig- ]
[nored unless you are responding to an explicit request ]
[from a developer. ]
[Reply only with text; DO NOT SEND ATTACHMENTS! ]