snprintf() implements the ability to foce a negative value through the (unsigned) size_t len parameter to allow the formatter to use a maximum size string. This is point less, we don't have as much memory and this is a recipe for all kinds of vulnerabilities. Kill the whole thing, the testcase it represents and thank Coverity for finding this thing. Whatever use it had before, it has no more. Change-Id: If422246548664699d8aa328a1b9304ef13cab7ea Coverity-ID: 131625 Coverity-ID: 131626 Signed-off-by: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
112 lines
2.3 KiB
C
112 lines
2.3 KiB
C
/* sprintf.c */
|
|
|
|
/*
|
|
* Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
extern int _prf(int (*func)(), void *dest,
|
|
const char *format, va_list vargs);
|
|
|
|
struct emitter {
|
|
char *ptr;
|
|
int len;
|
|
};
|
|
|
|
static int sprintf_out(int c, struct emitter *p)
|
|
{
|
|
if (p->len > 1) { /* need to reserve a byte for EOS */
|
|
*(p->ptr) = c;
|
|
p->ptr += 1;
|
|
p->len -= 1;
|
|
}
|
|
return 0; /* indicate keep going so we get the total count */
|
|
}
|
|
|
|
int snprintf(char *_Restrict s, size_t len, const char *_Restrict format, ...)
|
|
{
|
|
va_list vargs;
|
|
|
|
struct emitter p;
|
|
int r;
|
|
char dummy;
|
|
|
|
if (len == 0) {
|
|
s = &dummy; /* write final NUL to dummy, can't change *s */
|
|
}
|
|
|
|
p.ptr = s;
|
|
p.len = (int) len;
|
|
|
|
va_start(vargs, format);
|
|
r = _prf(sprintf_out, (void *) (&p), format, vargs);
|
|
va_end(vargs);
|
|
|
|
*(p.ptr) = 0;
|
|
return r;
|
|
}
|
|
|
|
int sprintf(char *_Restrict s, const char *_Restrict format, ...)
|
|
{
|
|
va_list vargs;
|
|
|
|
struct emitter p;
|
|
int r;
|
|
|
|
p.ptr = s;
|
|
p.len = (int) 0x7fffffff; /* allow up to "maxint" characters */
|
|
|
|
va_start(vargs, format);
|
|
r = _prf(sprintf_out, (void *) (&p), format, vargs);
|
|
va_end(vargs);
|
|
|
|
*(p.ptr) = 0;
|
|
return r;
|
|
}
|
|
|
|
int vsnprintf(char *_Restrict s, size_t len, const char *_Restrict format, va_list vargs)
|
|
{
|
|
struct emitter p;
|
|
int r;
|
|
char dummy;
|
|
|
|
if (len == 0) {
|
|
s = &dummy; /* write final NUL to dummy, can't change * *s */
|
|
}
|
|
|
|
p.ptr = s;
|
|
p.len = (int) len;
|
|
|
|
r = _prf(sprintf_out, (void *) (&p), format, vargs);
|
|
|
|
*(p.ptr) = 0;
|
|
return r;
|
|
}
|
|
|
|
int vsprintf(char *_Restrict s, const char *_Restrict format, va_list vargs)
|
|
{
|
|
struct emitter p;
|
|
int r;
|
|
|
|
p.ptr = s;
|
|
p.len = (int) 0x7fffffff; /* allow up to "maxint" characters */
|
|
|
|
r = _prf(sprintf_out, (void *) (&p), format, vargs);
|
|
|
|
*(p.ptr) = 0;
|
|
return r;
|
|
}
|