glib/glib/glib-private.h

109 lines
4.3 KiB
C
Raw Normal View History

/* glib-private.h - GLib-internal private API, shared between glib, gobject, gio
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GLIB_PRIVATE_H__
#define __GLIB_PRIVATE_H__
#include <glib.h>
#include "gwakeup.h"
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
#include "gstdioprivate.h"
GMainContext * g_get_worker_context (void);
CVE-2012-3524: Hardening for being run in a setuid environment Some programs attempt to use libglib (or even libgio) when setuid. For a long time, GTK+ simply aborted if launched in this configuration, but we never had a real policy for GLib. I'm not sure whether we should advertise such support. However, given that there are real-world programs that do this currently, we can make them safer with not too much effort. Better to fix a problem caused by an interaction between two components in *both* places if possible. This patch adds a private function g_check_setuid() which is used to first ensure we don't run an external dbus-launch binary if DBUS_SESSION_BUS_ADDRESS isn't set. Second, we also ensure the local VFS is used in this case. The gdaemonvfs extension point will end up talking to the session bus which is typically undesirable in a setuid context. Implementing g_check_setuid() is interesting - whether or not we're running in a privilege-escalated path is operating system specific. Note that GTK+'s code to check euid versus uid worked historically on Unix, more modern systems have filesystem capabilities and SELinux domain transitions, neither of which are captured by the uid comparison. On Linux/glibc, the way this works is that the kernel sets an AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on startup. If found, then glibc sets a public-but-undocumented __libc_enable_secure variable which we can use. Unfortunately, while it *previously* worked to check this variable, a combination of newer binutils and RPM break it: http://www.openwall.com/lists/owl-dev/2012/08/14/1 So for now on Linux/glibc, we fall back to the historical Unix version until we get glibc fixed. On some BSD variants, there is a issetugid() function. On other Unix variants, we fall back to what GTK+ has been doing. Reported-By: Sebastian Krahmer <krahmer@suse.de> Signed-off-by: Colin Walters <walters@verbum.org>
2012-08-22 20:26:11 +02:00
gboolean g_check_setuid (void);
GMainContext * g_main_context_new_with_next_id (guint next_id);
#ifdef G_OS_WIN32
gchar *_glib_get_dll_directory (void);
GLIB_AVAILABLE_IN_ALL
gchar *_glib_get_locale_dir (void);
#endif
GDir * g_dir_open_with_errno (const gchar *path, guint flags);
GDir * g_dir_new_from_dirp (gpointer dirp);
#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
typedef struct {
/* See gwakeup.c */
GWakeup * (* g_wakeup_new) (void);
void (* g_wakeup_free) (GWakeup *wakeup);
void (* g_wakeup_get_pollfd) (GWakeup *wakeup,
GPollFD *poll_fd);
void (* g_wakeup_signal) (GWakeup *wakeup);
void (* g_wakeup_acknowledge) (GWakeup *wakeup);
/* See gmain.c */
GMainContext * (* g_get_worker_context) (void);
CVE-2012-3524: Hardening for being run in a setuid environment Some programs attempt to use libglib (or even libgio) when setuid. For a long time, GTK+ simply aborted if launched in this configuration, but we never had a real policy for GLib. I'm not sure whether we should advertise such support. However, given that there are real-world programs that do this currently, we can make them safer with not too much effort. Better to fix a problem caused by an interaction between two components in *both* places if possible. This patch adds a private function g_check_setuid() which is used to first ensure we don't run an external dbus-launch binary if DBUS_SESSION_BUS_ADDRESS isn't set. Second, we also ensure the local VFS is used in this case. The gdaemonvfs extension point will end up talking to the session bus which is typically undesirable in a setuid context. Implementing g_check_setuid() is interesting - whether or not we're running in a privilege-escalated path is operating system specific. Note that GTK+'s code to check euid versus uid worked historically on Unix, more modern systems have filesystem capabilities and SELinux domain transitions, neither of which are captured by the uid comparison. On Linux/glibc, the way this works is that the kernel sets an AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on startup. If found, then glibc sets a public-but-undocumented __libc_enable_secure variable which we can use. Unfortunately, while it *previously* worked to check this variable, a combination of newer binutils and RPM break it: http://www.openwall.com/lists/owl-dev/2012/08/14/1 So for now on Linux/glibc, we fall back to the historical Unix version until we get glibc fixed. On some BSD variants, there is a issetugid() function. On other Unix variants, we fall back to what GTK+ has been doing. Reported-By: Sebastian Krahmer <krahmer@suse.de> Signed-off-by: Colin Walters <walters@verbum.org>
2012-08-22 20:26:11 +02:00
gboolean (* g_check_setuid) (void);
GMainContext * (* g_main_context_new_with_next_id) (guint next_id);
GDir * (* g_dir_open_with_errno) (const gchar *path,
guint flags);
GDir * (* g_dir_new_from_dirp) (gpointer dirp);
/* See glib-init.c */
void (* glib_init) (void);
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
/* See gstdio.c */
#ifdef G_OS_WIN32
W32: significant symlink code changes Put the core readlink() code into a separate _g_win32_readlink_handle_raw() function that takes a file handle, can optionally ensure NUL-terminatedness of its output (for cases where we need a NUL-terminator and do *not* need to get the exact contents of the symlink as it is stored in FS) and can either fill a caller-provided buffer *or* allocate its own buffer, and can also read the reparse tag. Put the rest of readlink() code into separate functions that do UTF-16<->UTF-8, strip inconvenient prefix and open/close the symlink file handle as needed. Split _g_win32_stat_utf16_no_trailing_slashes() into two functions - the one that takes a filename and the one that takes a file descriptor. The part of these functions that would have been duplicate is now split into the _g_win32_fill_privatestat() funcion. Add more comments explaining what each function does. Only g_win32_readlink_utf8(), which is callable from outside via private function interface, gets a real doc-comment, the rest get normal, non-doc comments. Change all callers to use the new version of the private g_win32_readlink_utf8() function, which can now NUL-terminate and allocate on demand - no need to call it in a loop. Also, the new code should correctly get reparse tag when the caller does fstat() on a symlink. Do note that this requires the caller to get a FD for the symlink, not the target. Figuring out how to do that is up to the caller. Since symlink info (target path and reparse tag) are now always read directly, via DeviceIoControl(), we don't need to use FindFirstFileW() anymore.
2018-08-24 11:16:46 +02:00
int (* g_win32_stat_utf8) (const gchar *filename,
GWin32PrivateStat *buf);
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
W32: significant symlink code changes Put the core readlink() code into a separate _g_win32_readlink_handle_raw() function that takes a file handle, can optionally ensure NUL-terminatedness of its output (for cases where we need a NUL-terminator and do *not* need to get the exact contents of the symlink as it is stored in FS) and can either fill a caller-provided buffer *or* allocate its own buffer, and can also read the reparse tag. Put the rest of readlink() code into separate functions that do UTF-16<->UTF-8, strip inconvenient prefix and open/close the symlink file handle as needed. Split _g_win32_stat_utf16_no_trailing_slashes() into two functions - the one that takes a filename and the one that takes a file descriptor. The part of these functions that would have been duplicate is now split into the _g_win32_fill_privatestat() funcion. Add more comments explaining what each function does. Only g_win32_readlink_utf8(), which is callable from outside via private function interface, gets a real doc-comment, the rest get normal, non-doc comments. Change all callers to use the new version of the private g_win32_readlink_utf8() function, which can now NUL-terminate and allocate on demand - no need to call it in a loop. Also, the new code should correctly get reparse tag when the caller does fstat() on a symlink. Do note that this requires the caller to get a FD for the symlink, not the target. Figuring out how to do that is up to the caller. Since symlink info (target path and reparse tag) are now always read directly, via DeviceIoControl(), we don't need to use FindFirstFileW() anymore.
2018-08-24 11:16:46 +02:00
int (* g_win32_lstat_utf8) (const gchar *filename,
GWin32PrivateStat *buf);
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
W32: significant symlink code changes Put the core readlink() code into a separate _g_win32_readlink_handle_raw() function that takes a file handle, can optionally ensure NUL-terminatedness of its output (for cases where we need a NUL-terminator and do *not* need to get the exact contents of the symlink as it is stored in FS) and can either fill a caller-provided buffer *or* allocate its own buffer, and can also read the reparse tag. Put the rest of readlink() code into separate functions that do UTF-16<->UTF-8, strip inconvenient prefix and open/close the symlink file handle as needed. Split _g_win32_stat_utf16_no_trailing_slashes() into two functions - the one that takes a filename and the one that takes a file descriptor. The part of these functions that would have been duplicate is now split into the _g_win32_fill_privatestat() funcion. Add more comments explaining what each function does. Only g_win32_readlink_utf8(), which is callable from outside via private function interface, gets a real doc-comment, the rest get normal, non-doc comments. Change all callers to use the new version of the private g_win32_readlink_utf8() function, which can now NUL-terminate and allocate on demand - no need to call it in a loop. Also, the new code should correctly get reparse tag when the caller does fstat() on a symlink. Do note that this requires the caller to get a FD for the symlink, not the target. Figuring out how to do that is up to the caller. Since symlink info (target path and reparse tag) are now always read directly, via DeviceIoControl(), we don't need to use FindFirstFileW() anymore.
2018-08-24 11:16:46 +02:00
int (* g_win32_readlink_utf8) (const gchar *filename,
gchar *buf,
gsize buf_size,
gchar **alloc_buf,
gboolean terminate);
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
W32: significant symlink code changes Put the core readlink() code into a separate _g_win32_readlink_handle_raw() function that takes a file handle, can optionally ensure NUL-terminatedness of its output (for cases where we need a NUL-terminator and do *not* need to get the exact contents of the symlink as it is stored in FS) and can either fill a caller-provided buffer *or* allocate its own buffer, and can also read the reparse tag. Put the rest of readlink() code into separate functions that do UTF-16<->UTF-8, strip inconvenient prefix and open/close the symlink file handle as needed. Split _g_win32_stat_utf16_no_trailing_slashes() into two functions - the one that takes a filename and the one that takes a file descriptor. The part of these functions that would have been duplicate is now split into the _g_win32_fill_privatestat() funcion. Add more comments explaining what each function does. Only g_win32_readlink_utf8(), which is callable from outside via private function interface, gets a real doc-comment, the rest get normal, non-doc comments. Change all callers to use the new version of the private g_win32_readlink_utf8() function, which can now NUL-terminate and allocate on demand - no need to call it in a loop. Also, the new code should correctly get reparse tag when the caller does fstat() on a symlink. Do note that this requires the caller to get a FD for the symlink, not the target. Figuring out how to do that is up to the caller. Since symlink info (target path and reparse tag) are now always read directly, via DeviceIoControl(), we don't need to use FindFirstFileW() anymore.
2018-08-24 11:16:46 +02:00
int (* g_win32_fstat) (int fd,
GWin32PrivateStat *buf);
W32: Add a stat() implementation for private use This commit adds new W32-only functions to gstdio.c, and a new header file, gstdioprivate.h. These functions are: g_win32_stat_utf8() g_win32_lstat_utf8() g_win32_fstat() and they fill a private structure, GWin32PrivateStat, which has all the fields that normal stat has, as well as some extras. These functions are then used throughout glib and gio to get better data about the system. Specifically: * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size) * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is) * W32 File attributes (which stat() doesn't report); in particular, this allows symlinks to be correctly identified * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows) * Allocated file size (as a W32 replacement for the missing st_blocks) st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8), this field does not contain anything unexpected. g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to. Also adds the g_win32_readlink_utf8() function, which behaves like readlink() (including its inability to return 0-terminated strings and inability to say how large the output buffer should be; these limitations are purely for compatibility with existing glib code). Thus, symlink support should now be much better, although far from being complete. A new W32-only test in gio/tests/file.c highlights the following features: * allocated size * 64-bit time * unique file IDs https://bugzilla.gnome.org/show_bug.cgi?id=788180
2017-09-29 12:14:41 +02:00
#endif
/* Add other private functions here, initialize them in glib-private.c */
} GLibPrivateVTable;
GLIB_AVAILABLE_IN_ALL
GLibPrivateVTable *glib__private__ (void);
/* Please see following for the use of ".ACP" over ""
* on Windows, although both are accepted at compile-time
* but "" renders translated console messages unreadable if
* built with Visual Studio 2012 and later (this is, unfortunately,
* undocumented):
*
* https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale
* https://gitlab.gnome.org/GNOME/glib/merge_requests/895#note_525881
* https://gitlab.gnome.org/GNOME/glib/merge_requests/895#note_525900
*
* Additional related items:
* https://stackoverflow.com/questions/22604329/php-5-5-setlocale-not-working-in-cli-on-windows
* https://bugs.php.net/bug.php?id=66265
*/
#ifdef G_OS_WIN32
# define GLIB_DEFAULT_LOCALE ".ACP"
#else
# define GLIB_DEFAULT_LOCALE ""
#endif
#endif /* __GLIB_PRIVATE_H__ */