Hide libmagic symbols by default on supported platforms#21472
Hide libmagic symbols by default on supported platforms#21472orlitzky wants to merge 3 commits intophp:masterfrom
Conversation
This function isn't used, but it is declared in file.h, and that can lead to conflicts if the system also provides it. If we define HAVE_STRCASESTR=1, though, the declaration in file.h is skipped. We no longer need to compile libmagic/strcasestr.c in any case.
|
Linking of the embed SAPI looks borked on master, but if I hack these patches onto the PHP-8.5 branch, pointlessly linking the embed SAPI into a small libmagic example induces the problem: /* main.c */
#include <magic.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char *actual_file = "example.pdf";
const char *magic_full;
magic_t magic_cookie;
magic_cookie = magic_open(MAGIC_MIME);
if (magic_cookie == NULL) {
printf("unable to initialize magic library\n");
return 1;
}
printf("Loading default magic database...\n");
if (magic_load(magic_cookie, "/usr/share/misc/magic.mgc") != 0) {
printf("cannot load magic database - %s\n", magic_error(magic_cookie));
magic_close(magic_cookie);
return 1;
}
magic_full = magic_file(magic_cookie, actual_file);
printf("libmagic answer: %s\n", magic_full);
magic_close(magic_cookie);
return 0;
}Before the PR (my system copy of php-8.5): And the one I just built and installed to |
|
(example.pdf is a random PDF on my machine) |
|
Would something like this not be enough? diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h
index f8fe5889500..443ca686319 100644
--- a/ext/fileinfo/libmagic/file.h
+++ b/ext/fileinfo/libmagic/file.h
@@ -102,12 +102,12 @@
#if HAVE_VISIBILITY
# if defined(WIN32)
-# define file_public __declspec(dllexport)
+# define file_public
# ifndef file_protected
# define file_protected
# endif
# else
-# define file_public __attribute__((__visibility__("default")))
+# define file_public __attribute__((__visibility__("hidden")))
# ifndef file_protected
# define file_protected __attribute__((__visibility__("hidden")))
# endifFWIU these symbols don't need dynamic linkage. |
This approach does work but it's not quite that simple. We're not using libmagic's build system, so Afterwards, the prototypes in Around this point is where I stopped and tried the find/sed approach in the PR. It's arguably simpler (doesn't require |
Now that I think about it, the compiler accepting |
Don't we already take care of this here? https://github.com/php/php-src/blob/master/ext/fileinfo/libmagic/config.h I did test this with a static ext-fileinfo build, and |
You're right, I completely missed that. I think that tips the scale in favor of your approach. I'll redo it and force-push. |
When libphp.so (from the embed SAPI, or the apache module) is loaded
by another project that already uses libmagic, the symbols from the
two copies of libmagic...
$ objdump -TC ./libs/libphp.so | grep '\smagic_'
00000000002b2754 g DF .text 0000000000000034 Base magic_compile
00000000002b25fe g DF .text 0000000000000024 Base magic_open
00000000002b27f0 g DF .text 0000000000000034 Base magic_descriptor
00000000002b2720 g DF .text 0000000000000034 Base magic_load
00000000002b2c1a g DF .text 0000000000000032 Base magic_setflags
00000000002b27bc g DF .text 0000000000000034 Base magic_list
00000000002b2c62 g DF .text 0000000000000206 Base magic_setparam
00000000002b2bf4 g DF .text 0000000000000026 Base magic_getflags
00000000002b2bbe g DF .text 0000000000000036 Base magic_errno
00000000002b2e68 g DF .text 00000000000001f4 Base magic_getparam
00000000002b2b14 g DF .text 000000000000006e Base magic_buffer
00000000002b2b82 g DF .text 000000000000003c Base magic_error
00000000002b2788 g DF .text 0000000000000034 Base magic_check
00000000002b2c4c g DF .text 0000000000000016 Base magic_version
00000000002b26fa g DF .text 0000000000000026 Base magic_close
00000000002b2858 g DF .text 0000000000000034 Base magic_stream
00000000002b2824 g DF .text 0000000000000034 Base magic_file
can clash. To see this, we (pointlessly) link libphp.so from the
embed SAPI into a small program using the system copy of libmagic:
$ gcc $(/usr/lib/php8.5/bin/php-config --includes) main.c \
-L/usr/lib/php8.5/lib -lphp -lmagic
$ LD_LIBRARY_PATH=/usr/lib/php8.5/lib ./a.out
Segmentation fault LD_LIBRARY_PATH=/usr/lib/php8.5/lib ./a.out
To avoid this, we modify the internal "file_public" macro used by
libmagic, so that (on platforms that support it) hidden visibility is
used instead of the default. Afterwards the objdump command above
produces no output, and the test program no longer sefaults.
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
PHP-bug: https://bugs.php.net/bug.php?id=66095
Gentoo-bug: https://bugs.gentoo.org/471682
Run ext/fileinfo/generate_patch.sh to update PHP's patch against file-5.46. The diff of the diff is mostly timestamps, but it does include the recent redefinition of the "file_public" macro in libmagic/file.h. It also includes a hunk for 399cb4c where the patch re-roll was overlooked.
fd1b9bc to
b283a53
Compare
|
Good find. Here would be then also good to remove the source file from Windows: --- a/ext/fileinfo/config.w32
+++ b/ext/fileinfo/config.w32
@@ -8,7 +8,7 @@ if (PHP_FILEINFO != 'no') {
encoding.c fsmagic.c funcs.c \
is_json.c is_tar.c is_simh.c magic.c print.c \
readcdf.c softmagic.c der.c \
- strcasestr.c buffer.c is_csv.c";
+ buffer.c is_csv.c";
EXTENSION('fileinfo', 'fileinfo.c php_libmagic.c', true, "/I" + configure_module_dirname + "/libmagic /I" + configure_module_dirname);
ADD_EXTENSION_DEP('fileinfo', 'pcre');And can we then update the patch file instead of adding the HAVE_STRCASESTR to build configuration, so it's safer to not be redefined in any case. |
Trying my hand at a very old problem (PHP bug 66095, Gentoo bug 471682, FreeBSD bug 195562)
The bundled libmagic for the fileinfo extension has some visible symbols:
This works fine until you load that shared library into a process that links against the system libmagic, providing (in many cases, different versions of) the same symbols. I hit this myself several years ago when using another apache module that linked against libmagic. I can't cite any bug reports for the embed SAPI, but there is every reason to suspect that it suffers from the same issue.
As pointed out by @iluuu1994 below, hiding these symbols on platforms that support the visibility attribute is straightforward.
The
strcasestr()commit is unrelated to an extent. I noticed (grep) that the only use ofstrcasestr()in libmagic is patched out by PHP, so there is no need for it on any platform. The-DHAVE_STRCASESTR=1simply ensures that libmagic does not try to prototype it.