+2025-05-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ obstack: fix unlikely buffer overrun in glibc
+ This bug is not plausible on any Gnulib platform,
+ but it could happen in glibc if the requested size is UINT_MAX.
+ * lib/obstack.c (_obstack_newchunk): Fail if requested size is 0.
+ * lib/obstack.in.h (obstack_grow0): Check for room <= len,
+ not room <= len + 1 where len + 1 could overflow.
+
2025-05-05 Bruno Haible <bruno@clisp.org>
windows-cygpath: Make it work with the native Windows 'git' port.
# include <alignof.h>
# define __alignof__(type) alignof_type (type)
#endif
-#include <stdlib.h>
+
+#include <limits.h>
#include <stdint.h>
+#include <stdlib.h>
+
+/* Some work would need to be done to port this module
+ to unusual platforms where size_t fits in int.
+ For now, document the assumption that INT_MAX < SIZE_MAX,
+ and therefore size_t calculations are modulo SIZE_MAX + 1
+ instead of having undefined behavior on overflow. */
+#if SIZE_MAX <= INT_MAX
+ #error "SIZE_MAX <= INT_MAX"
+#endif
#ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
/* Allocate a new current chunk for the obstack *H
on the assumption that LENGTH bytes need to be added
to the current object, or a new object of length LENGTH allocated.
+ Fail if LENGTH <= 0, as this means obstack_grow0's length overflowed.
Copies any partial object from the end of the old chunk
to the beginning of the new one. */
if (new_size < h->chunk_size)
new_size = h->chunk_size;
- /* Allocate and initialize the new chunk. */
- if (obj_size <= sum1 && sum1 <= sum2)
+ /* Allocate and initialize the new chunk,
+ checking for overflow and for nonpositive LENGTH. */
+ if (obj_size < sum1 && sum1 <= sum2)
new_chunk = call_chunkfun (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler)();
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
- if (obstack_room (__o) < __len + 1) \
+ if (obstack_room (__o) <= __len) \
_obstack_newchunk (__o, __len + 1); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
# define obstack_grow0(h, where, length) \
((h)->temp.i = (length), \
- ((obstack_room (h) < (h)->temp.i + 1) \
+ ((obstack_room (h) <= (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \