]>
Commit | Line | Data |
---|---|---|
1be32c85 OB |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> | |
3 | Date: Mon, 27 Jan 2020 10:24:09 +0100 | |
4 | Subject: [PATCH 1/2] util: add slirp_fmt() helpers | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | Various calls to snprintf() in libslirp assume that snprintf() returns | |
10 | "only" the number of bytes written (excluding terminating NUL). | |
11 | ||
12 | https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04 | |
13 | ||
14 | "Upon successful completion, the snprintf() function shall return the | |
15 | number of bytes that would be written to s had n been sufficiently | |
16 | large excluding the terminating null byte." | |
17 | ||
18 | Introduce slirp_fmt() that handles several pathological cases the | |
19 | way libslirp usually expect: | |
20 | ||
21 | - treat error as fatal (instead of silently returning -1) | |
22 | ||
23 | - fmt0() will always \0 end | |
24 | ||
25 | - return the number of bytes actually written (instead of what would | |
26 | have been written, which would usually result in OOB later), including | |
27 | the ending \0 for fmt0() | |
28 | ||
29 | - warn if truncation happened (instead of ignoring) | |
30 | ||
31 | Other less common cases can still be handled with strcpy/snprintf() etc. | |
32 | ||
33 | Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> | |
34 | Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org> | |
35 | Message-Id: <20200127092414.169796-2-marcandre.lureau@redhat.com> | |
36 | Signed-off-by: Oguz Bektas <o.bektas@proxmox.com> | |
37 | --- | |
38 | slirp/src/util.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
39 | slirp/src/util.h | 3 +++ | |
40 | 2 files changed, 65 insertions(+) | |
41 | ||
42 | diff --git a/slirp/src/util.c b/slirp/src/util.c | |
43 | index e596087..e3b6257 100644 | |
44 | --- a/slirp/src/util.c | |
45 | +++ b/slirp/src/util.c | |
46 | @@ -364,3 +364,65 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str) | |
47 | } | |
48 | *q = '\0'; | |
49 | } | |
50 | + | |
51 | +static int slirp_vsnprintf(char *str, size_t size, | |
52 | + const char *format, va_list args) | |
53 | +{ | |
54 | + int rv = vsnprintf(str, size, format, args); | |
55 | + | |
56 | + if (rv < 0) { | |
57 | + g_error("vsnprintf() failed: %s", g_strerror(errno)); | |
58 | + } | |
59 | + | |
60 | + return rv; | |
61 | +} | |
62 | + | |
63 | +/* | |
64 | + * A snprintf()-like function that: | |
65 | + * - returns the number of bytes written (excluding optional \0-ending) | |
66 | + * - dies on error | |
67 | + * - warn on truncation | |
68 | + */ | |
69 | +int slirp_fmt(char *str, size_t size, const char *format, ...) | |
70 | +{ | |
71 | + va_list args; | |
72 | + int rv; | |
73 | + | |
74 | + va_start(args, format); | |
75 | + rv = slirp_vsnprintf(str, size, format, args); | |
76 | + va_end(args); | |
77 | + | |
78 | + if (rv > size) { | |
79 | + g_critical("vsnprintf() truncation"); | |
80 | + } | |
81 | + | |
82 | + return MIN(rv, size); | |
83 | +} | |
84 | + | |
85 | +/* | |
86 | + * A snprintf()-like function that: | |
87 | + * - always \0-end (unless size == 0) | |
88 | + * - returns the number of bytes actually written, including \0 ending | |
89 | + * - dies on error | |
90 | + * - warn on truncation | |
91 | + */ | |
92 | +int slirp_fmt0(char *str, size_t size, const char *format, ...) | |
93 | +{ | |
94 | + va_list args; | |
95 | + int rv; | |
96 | + | |
97 | + va_start(args, format); | |
98 | + rv = slirp_vsnprintf(str, size, format, args); | |
99 | + va_end(args); | |
100 | + | |
101 | + if (rv >= size) { | |
102 | + g_critical("vsnprintf() truncation"); | |
103 | + if (size > 0) | |
104 | + str[size - 1] = '\0'; | |
105 | + rv = size; | |
106 | + } else { | |
107 | + rv += 1; /* include \0 */ | |
108 | + } | |
109 | + | |
110 | + return rv; | |
111 | +} | |
112 | diff --git a/slirp/src/util.h b/slirp/src/util.h | |
113 | index 3c6223c..0558dfc 100644 | |
114 | --- a/slirp/src/util.h | |
115 | +++ b/slirp/src/util.h | |
116 | @@ -177,4 +177,7 @@ static inline int slirp_socket_set_fast_reuse(int fd) | |
117 | ||
118 | void slirp_pstrcpy(char *buf, int buf_size, const char *str); | |
119 | ||
120 | +int slirp_fmt(char *str, size_t size, const char *format, ...); | |
121 | +int slirp_fmt0(char *str, size_t size, const char *format, ...); | |
122 | + | |
123 | #endif | |
124 | -- | |
125 | 2.20.1 | |
126 |