In certain cases, fnmatch() could access the next byte beyond the end of
he passed pattern. A triggering pattern to match is the following
invocation:
fnmatch("[A-Z[.", "F", 0)
The normal A-Z group match gets us to fnmatch_loop.c:421 and then to
fnmatch_loop:599. The F in the filaname matches this expression and
we end up in fnmatch_loop:867 which handles skipping the rest of a
bracked expression that already matched. Here we enter the case where
the next chars to parse are a collating symbol starting with "[."
(fnmatch_loop:918). Currently the p pointer is then advanced by one,
moving it beyond the "." and to the \0 byte of the pattern string
(fnmatch_loop:920). Inside the while loop the pointer is then
incremented again and immediately dereferenced, reaching beyond the
end of the pattern string.
The increment before the while loop must be removed, because only inside
the while loop (after the other increment) a check for the end of the
string is performend. This is sufficient and the check of the end of
the collating symbol is only performed if p[1] is at most the
terminating \0 byte.
Signed-Off-By: Frank Mehnert <frank.mehnert(a)kernkonzept.com>
---
libc/misc/fnmatch/fnmatch_loop.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/libc/misc/fnmatch/fnmatch_loop.c b/libc/misc/fnmatch/fnmatch_loop.c
index 32ee079a3..025510de6 100644
--- a/libc/misc/fnmatch/fnmatch_loop.c
+++ b/libc/misc/fnmatch/fnmatch_loop.c
@@ -917,7 +917,6 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
}
else if (c == L('[') && *p == L('.'))
{
- ++p;
while (1)
{
c = *++p;
--
2.42.0
From: Pavel Kozlov <pavel.kozlov(a)synopsys.com>
Remove read ahead in the per-word compare loop as it can cause a
segmentation fault in certain circumstances (when a string crosses a
page boundary). For baremetal this relaxed approach is suitable but
in Linux with MMU we should be more restrictive.
Signed-off-by: Pavel Kozlov <pavel.kozlov(a)synopsys.com>
---
libc/string/arc/strcmp.S | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/libc/string/arc/strcmp.S b/libc/string/arc/strcmp.S
index 3f64ac421acc..48d2d7ec1d83 100644
--- a/libc/string/arc/strcmp.S
+++ b/libc/string/arc/strcmp.S
@@ -103,23 +103,21 @@ ENTRY(strcmp)
brne r2, 0, @.Lcharloop
;;; s1 and s2 are word aligned
- ld.ab r2, [r0, 4]
mov_s r12, 0x01010101
ror r11, r12
.align 4
.LwordLoop:
+ ld.ab r2, [r0, 4]
+ sub r4, r2, r12
ld.ab r3, [r1, 4]
;; Detect NULL char in str1
- sub r4, r2, r12
- ld.ab r5, [r0, 4]
bic r4, r4, r2
and r4, r4, r11
brne.d.nt r4, 0, .LfoundNULL
;; Check if the read locations are the same
cmp r2, r3
- beq.d .LwordLoop
- mov.eq r2, r5
+ beq .LwordLoop
;; A match is found, spot it out
#ifdef __LITTLE_ENDIAN__
--
2.25.1
From: Marcus Hähnel <marcus.haehnel(a)kernkonzept.com>
Commit 21cbb6fe ("unistd.h: put getppid under XOPEN2K8") introduced a
new __THROWNL specification for non-leaf throws. It also made use of
these in the setjmp.h header. The functions that use this specification
(longjmp and siglongjmp) have their extern __libc__* equivalent
definition prototype specified using __typeof__ for the internal
function signatures. For C++ this copies the throw() specifier, since
this is part of the type for C++. The attribute in C is not.
This commit explicitly types out the signature for the two functions to
be compatible between the C++ and C worlds.
An alternative would be to keep the __typeof__ declaration and use
the copy attribute. Then the __THROWNL part could be thrown out since
the C attribute would be copied and the C++ exception specifier would
be part of the signature from __type__. However, since the copy
attribute is not supported for all compilers supported by uclibc-ng
this is not viable at this time.
---
include/setjmp.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/setjmp.h b/include/setjmp.h
index 27cac9500..41337aa9f 100644
--- a/include/setjmp.h
+++ b/include/setjmp.h
@@ -108,8 +108,10 @@ __END_DECLS
#ifdef _LIBC
extern void __longjmp(__jmp_buf __env, int __val) __THROWNL attribute_noreturn;
libc_hidden_proto(__longjmp)
-extern __typeof(longjmp) __libc_longjmp __THROWNL attribute_noreturn;
-extern __typeof(siglongjmp) __libc_siglongjmp __THROWNL attribute_noreturn;
+extern void __libc_longjmp(struct __jmp_buf_tag __env[1], int __val)
+ __THROWNL attribute_noreturn;
+extern void __libc_siglongjmp(sigjmp_buf __env, int __val)
+ __THROWNL attribute_noreturn;
extern void _longjmp_unwind(jmp_buf __env, int __val);
libc_hidden_proto(_longjmp_unwind)
extern int __sigjmp_save(sigjmp_buf __env, int __savemask) attribute_hidden;
--
2.42.0
elf-fdpic.h is included by link.h. When a C++ program includes <link.h>,
we get the following build failure:
<...>/usr/include/bits/elf-fdpic.h: In function ‘void* __reloc_pointer(void*, const elf32_fdpic_loadmap*)’:
<...>/usr/include/bits/elf-fdpic.h:94:54: error: invalid use of ‘void’
94 | unsigned long offset = p - (void*)map->segs[c].p_vaddr;
| ^~~~~~~
void pointer addition and subtraction is not allowed in C++ as it has
undetermined size, however in C with language extension it is possible
because sizeof void is treated as one byte.
This patch was previously applied to Blackfin, FR-V and C6x, but not
ARM.
Signed-off-by: Ben Wolsieffer <ben.wolsieffer(a)hefring.com>
---
libc/sysdeps/linux/arm/bits/elf-fdpic.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/sysdeps/linux/arm/bits/elf-fdpic.h b/libc/sysdeps/linux/arm/bits/elf-fdpic.h
index 3d6db54af..f2ef9aeca 100644
--- a/libc/sysdeps/linux/arm/bits/elf-fdpic.h
+++ b/libc/sysdeps/linux/arm/bits/elf-fdpic.h
@@ -91,7 +91,7 @@ __reloc_pointer (void *p,
/* This should be computed as part of the pointer comparison
above, but we want to use the carry in the comparison, so we
can't convert it to an integer type beforehand. */
- unsigned long offset = p - (void*)map->segs[c].p_vaddr;
+ unsigned long offset = (char*)p - (char*)map->segs[c].p_vaddr;
/* We only check for one-past-the-end for the last segment,
assumed to be the data segment, because other cases are
ambiguous in the absence of padding between segments, and
--
2.42.0
Hi all,
in certain cases,
fnmatch(pattern, string, flags)
reads beyond the end of pattern. This can be triggered by parameters
like this:
fnmatch(""[A-Z[.", "F", 0);
The corresponding code can be found here:
https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/misc/fnmatch/fn…
After line 920 is executed, p points to '\0' (the end of the pattern).
Then, in line 923, p is unconditionally increased again and the value
_after_ the end of the pattern is read (to find out if the pattern has
ended).
Suggested fix: Just remove line 920.
Kind regards,
Frank
--
Dr.-Ing. Frank Mehnert, frank.mehnert(a)kernkonzept.com, +49-351-41 883 224
Kernkonzept GmbH. Sitz: Dresden. Amtsgericht Dresden, HRB 31129.
Geschäftsführer: Dr.-Ing. Michael Hohmuth