libpkgconf/dependency.c


Log

Author Commit Date CI Message
Ariadne Conill fd7069a2 2025-05-29T11:13:39 libpkgconf: dependency: move static parsing buffer off the stack Also remove the 64KB limit for dependency list strings. Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
Ariadne Conill 10d37b61 2025-05-28T23:18:42 libpkgconf: dependency: handle memory allocation failures Found-by: GCC -fanalyzer Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
Kai Pastor 8b7e2c4e 2024-07-03T04:58:06 Process character after operator
Stefan Weil a4ecd42b 2023-11-24T19:44:04 Fix it's -> its Signed-off-by: Stefan Weil <sw@weilnetz.de>
Sam James d454f62c 2023-11-05T22:17:02 libpkgconf: fix -Walloc-size GCC 14 introduces a new -Walloc-size included in -Wextra which gives: ``` libpkgconf/personality.c:260:11: warning: allocation of insufficient size '1' for type 'pkgconf_cross_personality_t' {aka 'struct pkgconf_cross_personality_'} with size '48' [-Walloc-size] libpkgconf/queue.c:46:33: warning: allocation of insufficient size '1' for type 'pkgconf_queue_t' {aka'struct pkgconf_queue_'} with size '16' [-Walloc-size] libpkgconf/client.c:164:33: warning: allocation of insufficient size '1' for type 'pkgconf_client_t' {aka 'struct pkgconf_client_'} with size '120' [-Walloc-size] libpkgconf/path.c:105:14: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '24' [-Walloc-size] libpkgconf/path.c:237:22: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '24' [-Walloc-size] libpkgconf/tuple.c:239:34: warning: allocation of insufficient size '1' for type 'pkgconf_tuple_t' {aka 'struct pkgconf_tuple_'} with size '24' [-Walloc-size] libpkgconf/dependency.c:133:13: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '44' [-Walloc-size] libpkgconf/dependency.c:472:17: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '44' [-Walloc-size] libpkgconf/fragment.c:146:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size] libpkgconf/fragment.c:195:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size] libpkgconf/fragment.c:356:14: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '24' [-Walloc-size] libpkgconf/pkg.c:422:13: warning: allocation of insufficient size '1' for type 'pkgconf_pkg_t' {aka 'struct pkgconf_pkg_'} with size '188' [-Walloc-size] libpkgconf/client.c:164:33: warning: allocation of insufficient size '1' for type 'pkgconf_client_t' {aka 'struct pkgconf_client_'} with size '224' [-Walloc-size] libpkgconf/personality.c:260:11: warning: allocation of insufficient size '1' for type 'pkgconf_cross_personality_t' {aka 'struct pkgconf_cross_personality_'} with size '96' [-Walloc-size] libpkgconf/dependency.c:133:13: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '80' [-Walloc-size] libpkgconf/dependency.c:472:17: warning: allocation of insufficient size '1' for type 'pkgconf_dependency_t' {aka 'struct pkgconf_dependency_'} with size '80' [-Walloc-size] libpkgconf/path.c:105:14: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '48' [-Walloc-size] libpkgconf/path.c:237:22: warning: allocation of insufficient size '1' for type 'pkgconf_path_t' {aka 'struct pkgconf_path_'} with size '48' [-Walloc-size] libpkgconf/queue.c:46:33: warning: allocation of insufficient size '1' for type 'pkgconf_queue_t' {aka 'struct pkgconf_queue_'} with size '32' [-Walloc-size] libpkgconf/tuple.c:239:34: warning: allocation of insufficient size '1' for type 'pkgconf_tuple_t' {aka 'struct pkgconf_tuple_'} with size '48' [-Walloc-size] libpkgconf/fragment.c:146:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size] libpkgconf/fragment.c:195:22: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size] libpkgconf/fragment.c:356:14: warning: allocation of insufficient size '1' for type 'pkgconf_fragment_t' {aka 'struct pkgconf_fragment_'} with size '48' [-Walloc-size] libpkgconf/pkg.c:422:13: warning: allocation of insufficient size '1' for type 'pkgconf_pkg_t' {aka 'struct pkgconf_pkg_'} with size '360' [-Walloc-size] ``` The calloc prototype is: ``` void *calloc(size_t nmemb, size_t size); ``` So, just swap the number of members and size arguments to match the prototype, as we're initialising 1 struct of size `sizeof(struct ...)`. GCC then sees we're not doing anything wrong. The only exception there is for argv which I fixed while at it. Signed-off-by: Sam James <sam@gentoo.org>
Taylor R Campbell 212c8586 2023-03-17T19:32:58 Avoid undefined behaviour with the ctype(3) functions. fix https://github.com/pkgconf/pkgconf/issues/291 As defined in the C standard: In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined. This is because they're designed to work with the int values returned by getc or fgetc; they need extra work to handle a char value. If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed inputs to the ctype(3) functions are: {-1, 0, 1, 2, 3, ..., 255}. However, on platforms where char is signed, such as x86 with the usual ABI, code like char *ptr = ...; ... isspace(*ptr) ... may pass in values in the range: {-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}. This has two problems: 1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden. 2. The non-EOF byte 0xff is conflated with the value EOF = -1, so even though the input is not forbidden, it may give the wrong answer. Casting char to unsigned int first before passing the result to ctype(3) doesn't help: inputs like -128 are unchanged by this cast, because (on a two's-complement machine with 32-bit int and unsigned int), converting the signed char with integer value -128 to unsigned int gives integer value 2^32 - 128 = 0xffffff80, which is out of range, and which is converted in int back to -128, which is also out of range. It is necessary to cast char inputs to unsigned char first; you can then cast to unsigned int if you like but there's no need because the functions will always convert the argument to int by definition. So the above fragment needs to be: char *ptr = ...; ... isspace((unsigned char)*ptr) ... This patch changes unsigned int casts to unsigned char casts, and adds unsigned char casts where they are missing.
Dylan Baker 34b11020 2022-08-04T11:53:02 dependency: zero list after freeing
Dylan Baker e71a5a33 2022-08-04T11:52:26 dependency: add debug information for dependency refcounting
Dylan Baker 4a1119aa 2022-08-03T15:43:04 dependency: Fix reference counting of dependency_addraw We only want a reference to be added for the value inserted into the list, not the one returned. The returned one is unowned until it reaches the public dependency_add function, which returns an owned pointer instead. This makes things semantically more correct. Unfortunately, this means in a few cases we have to write some ugly code like: ```c pkgconf_dependency_t *dep = pkgcond_dependency_add("args"); pkgconf_dependency_unref(dep->owner, dep); ```
Ariadne Conill 297e18f2 2022-07-26T17:08:48 tuple: add flags parameter to pkgconf_tuple_parse
Ariadne Conill 197fcadd 2022-06-26T15:02:37 queue: add flattening code
Ariadne Conill 7d8cc1e4 2021-10-06T13:13:34 dependency: add pkgconf_dependency_copy()
Ariadne Conill c547edd0 2021-10-06T11:52:18 deconst the client on pkgconf_dependency_add()
Ariadne Conill 4144d506 2021-10-06T11:48:13 implement dependency refcounting
Ariadne Conill 8130dd15 2021-10-06T11:29:18 dependency: add pkgconf_dependency_free_one
Ariadne Conill df1b671c 2021-08-17T15:18:47 dependency: use dependency match owner with pkgconf_pkg_unref()
Tobias Stoeckmann fb9acedc 2020-05-26T21:42:13 libpkgconf: dependency: fix out of boundary write It is possible to trigger an out of boundary write in function pkgconf_dependency_parse_str if a dependency line contains a very long comparator. The comparator is stored in a temporary buffer which has a size of PKGCONF_ITEM_SIZE. The line which is parsed can be up to PKGCONF_BUFSIZE characters long, which is larger than PKGCONF_ITEM_SIZE (although it depends on PATH_MAX). Having a comparator which is longer than PKGCONF_ITEM_SIZE therefore leads to an out of boundary write. Although it is undefined behaviour, this can lead to an overridden compare variable, which in turn can lead to an invalid instruction pointer, i.e. most likely a crash or code execution (very unlikely). Proof of concept: $ echo "Requires: x " > poc.pc $ dd if=/dev/zero bs=1 count=65535 | tr '\0' '<' >> poc.pc $ pkgconf poc.pc Eiter compile pkgconf with address sanitizer or run pkgconf multiple times, eventually it might crash (assuming that ASLR is in place). In order to fix this, I decided to use an end pointer to avoid OOB write. Alternative would be to increase the buffer size, but I try to avoid that since this would be additional ~60 KB stack space for a very unlikely situation.
William Pitcock 3f753fa3 2018-03-18T19:03:18 libpkgconf: dependency: preference uncoloured nodes in event of a dependency collision
William Pitcock ad65bc4a 2018-03-18T18:01:59 libpkgconf: dependency: allow dependency nodes to be colored with traits
William Pitcock 74d58d1b 2017-12-05T17:34:01 libpkgconf: pkg: cache solutions for already solved dependency graph nodes in almost all cases, we partially solve the dependency graph multiple times, which just wastes resources. if we record the solution to a given dependency node, further iterations can make use of the previous solution without having to solve it again. this is safe because all provides entries (including virtuals) are knowable prior to solving the dependency graph the first time. a nice side effect of this is that all packages are preloaded when querying information about them (--cflags and related commands).
William Pitcock 4589274c 2017-10-16T12:56:19 libpkgconf: start to remove PKGCONF_BUFSIZE allocations from the stack. (closes #149) Patch by Karen Arutyunov.
William Pitcock e9fd43ca 2017-09-17T23:38:25 libpkgconf: clean up header includes (closes #137)
William Pitcock 1252d7ae 2017-09-08T19:53:52 libpkgconf: dependency: make dependency_to_str() private, use a caller-supplied buffer for reentrancy
William Pitcock 794443a9 2017-02-25T16:04:55 dependency: break API to add tracepoints to dependency list building
Igor Gnatenko 5db87c96 2017-01-22T20:31:34 remove dead assignments (#109) * remove dead assignments None of them are used. Signed-off-by: Igor Gnatenko <ignatenko@redhat.com> * The address of an object "&pkgconf_pkg_provides_vermatch_rules[pkgdep->compare]" is never null Signed-off-by: Igor Gnatenko <ignatenko@redhat.com> * Overrunning array pkgconf_pkg_comparator_names at element index 7 Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>
William Pitcock af503f21 2016-12-10T19:57:26 libpkgconf: document dependency module
William Pitcock 8213d910 2016-12-10T16:19:40 libpkgconf: migrate to using the pkgconf_ namespaced strlcat/strlcpy symbols
William Pitcock 8740c5cd 2016-12-01T15:05:03 libpkgconf: begin removing global state from libpkgconf library by introducing a "client" object which holds the state
William Pitcock d72ece6a 2016-08-26T23:40:15 dependency: add pkgconf_dependency_add for programmatically adding a dependency object
Baptiste Daroussin cb83dab4 2015-12-02T14:59:51 More casting for ctype
William Pitcock 2f4f68fb 2015-09-06T11:50:29 libpkgconf: dependency: remove some dead debug code
William Pitcock 50cf8db0 2015-09-06T11:39:55 libpkgconf: clean up PKG_MODULE_SEPARATOR() and PKG_OPERATOR_CHAR() macros
William Pitcock dd86ba43 2015-09-06T11:34:09 libpkgconf: PKG_ comparators become PKGCONF_CMP_ namespace
William Pitcock 571d9c75 2015-09-06T11:29:56 libpkgconf: PKG_BUFSIZE becomes PKGCONF_BUFSIZE, remove unused PKG_MIN/PKG_MAX.
William Pitcock ca1b0265 2015-09-06T11:20:48 libpkgconf: untangle remaining pkg_ functions related to pkgconf_pkg_t
William Pitcock 66247fae 2015-09-06T10:57:26 libpkgconf: pkg_comparator_t becomes pkgconf_pkg_comparator_t (and so on)
William Pitcock 4c71b25d 2015-09-06T10:41:40 libpkgconf: move pkg_tuple to pkgconf_tuple namespace
William Pitcock 1ee18d0e 2015-09-06T10:38:30 libpkgconf: move pkg_dependency to pkgconf_dependency namespace
William Pitcock cc2dcc1f 2015-09-06T10:31:21 libpkgconf: move pkg_node and pkg_list to pkgconf_node and pkgconf_list namespaces
William Pitcock a706b3dc 2015-09-06T09:35:08 initial libtoolization for libpkgconf