]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdio-common/reg-printf.c
CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
[thirdparty/glibc.git] / stdio-common / reg-printf.c
CommitLineData
d4697bc9 1/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
c84142e8
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
c84142e8
UD
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
c84142e8 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
28f540f4 17
28f540f4
RM
18#include <errno.h>
19#include <limits.h>
20#include <printf.h>
8e96ae1a 21#include <stddef.h>
379c9e03 22#include <stdlib.h>
9d26efa9
UD
23#include <bits/libc-lock.h>
24
28f540f4
RM
25
26/* Array of functions indexed by format character. */
9d26efa9 27libc_freeres_ptr (printf_arginfo_size_function **__printf_arginfo_table)
c877418f 28 attribute_hidden;
6455d255 29printf_function **__printf_function_table attribute_hidden;
28f540f4 30
9d26efa9
UD
31__libc_lock_define_initialized (static, lock)
32
33int __register_printf_specifier (int, printf_function,
34 printf_arginfo_size_function);
79937577 35int __register_printf_function (int, printf_function,
9d26efa9
UD
36 printf_arginfo_function);
37
a68b0d31 38
28f540f4
RM
39/* Register FUNC to be called to format SPEC specifiers. */
40int
9d26efa9 41__register_printf_specifier (spec, converter, arginfo)
23396375
UD
42 int spec;
43 printf_function converter;
9d26efa9 44 printf_arginfo_size_function arginfo;
28f540f4
RM
45{
46 if (spec < 0 || spec > (int) UCHAR_MAX)
47 {
c4029823 48 __set_errno (EINVAL);
28f540f4
RM
49 return -1;
50 }
51
9d26efa9
UD
52 int result = 0;
53 __libc_lock_lock (lock);
54
c877418f
RM
55 if (__printf_function_table == NULL)
56 {
9d26efa9 57 __printf_arginfo_table = (printf_arginfo_size_function **)
d0f534e9 58 calloc (UCHAR_MAX + 1, sizeof (void *) * 2);
c877418f 59 if (__printf_arginfo_table == NULL)
9d26efa9
UD
60 {
61 result = -1;
62 goto out;
63 }
64
c877418f
RM
65 __printf_function_table = (printf_function **)
66 (__printf_arginfo_table + UCHAR_MAX + 1);
67 }
68
69 __printf_function_table[spec] = converter;
28f540f4 70 __printf_arginfo_table[spec] = arginfo;
28f540f4 71
9d26efa9
UD
72 out:
73 __libc_lock_unlock (lock);
74
75 return result;
76}
77weak_alias (__register_printf_specifier, register_printf_specifier)
78
79
80/* Register FUNC to be called to format SPEC specifiers. */
81int
82__register_printf_function (spec, converter, arginfo)
83 int spec;
84 printf_function converter;
85 printf_arginfo_function arginfo;
86{
87 return __register_printf_specifier (spec, converter,
88 (printf_arginfo_size_function*) arginfo);
28f540f4 89}
23396375 90weak_alias (__register_printf_function, register_printf_function)