Add a section about writing GLib applications

For now, this includes some information about threads and security.
This commit is contained in:
Matthias Clasen 2012-09-11 22:41:18 -04:00
parent 6a50dc511b
commit fc7dc33113
2 changed files with 124 additions and 8 deletions

View File

@ -20,18 +20,13 @@
GLib is a general-purpose utility library, which provides many useful GLib is a general-purpose utility library, which provides many useful
data types, macros, type conversions, string utilities, file utilities, data types, macros, type conversions, string utilities, file utilities,
a mainloop abstraction, and so on. It works on many UNIX-like platforms, a mainloop abstraction, and so on. It works on many UNIX-like platforms,
Windows, OS/2 and BeOS. GLib is released under the GNU Library General as well as Windows and OS X. GLib is released under the GNU Library
Public License (GNU LGPL). General Public License (GNU LGPL).
</para>
<para>
The general policy of GLib is that all functions are invisibly threadsafe
with the exception of data structure manipulation functions, where, if
you have two threads manipulating the <emphasis>same</emphasis> data
structure, they must use a lock to synchronize their operation.
</para> </para>
<xi:include href="building.xml" /> <xi:include href="building.xml" />
<xi:include href="cross.xml" /> <xi:include href="cross.xml" />
<xi:include href="programming.xml" />
<xi:include href="xml/compiling.xml" /> <xi:include href="xml/compiling.xml" />
<xi:include href="running.xml" /> <xi:include href="running.xml" />
<xi:include href="changes.xml" /> <xi:include href="changes.xml" />

View File

@ -0,0 +1,121 @@
<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<refentry id="glib-programming">
<refmeta>
<refentrytitle>Writing GLib Applications</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GLib Library</refmiscinfo>
</refmeta>
<refnamediv>
<refname>Writing GLib Applications</refname>
<refpurpose>
General considerations when programming with GLib
</refpurpose>
</refnamediv>
<refsect1>
<title>Writing GLib Applications</title>
<refsect2>
<title>Threads</title>
<para>
The general policy of GLib is that all functions are invisibly threadsafe
with the exception of data structure manipulation functions, where, if
you have two threads manipulating the <emphasis>same</emphasis> data
structure, they must use a lock to synchronize their operation.
</para>
<para>
GLib is creating a worker thread for its own purposes, so GLib applications
will always have at least 2 threads.
</para>
<para>
See the sections on <link linkend="glib-Threads">threads</link> and
<link linkend="glib-Thread-Pools">threadpools</link> for GLib APIs that
support multithreaded applications.
</para>
</refsect2>
<refsect2>
<title>Security</title>
<para>
When your program needs to carry out some privileged operation (say,
create a new user account), there are various ways in which you can go
about this:
<itemizedlist>
<listitem><para>
Implement a daemon that offers the privileged operation. A convenient
way to do this is as a D-Bus system-bus service. The daemon will probably
need ways to check the identity and authorization of the caller before
executing the operation. <ulink url="http://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html">polkit</ulink> is a framework that allows this.
</para></listitem>
<listitem><para>
Use a small helper that is executed with elevated privileges via
pkexec. <ulink url="http://www.freedesktop.org/software/polkit/docs/latest/pkexec.1.html">pkexec</ulink> is a small program launcher that is part of polkit.
</para></listitem>
<listitem><para>
Use a small helper that is executed with elevated privileges by
being suid root.
</para></listitem>
</itemizedlist>
None of these approaches is the clear winner, they all have their
advantages and disadvantages.
</para>
<para>
When writing code that runs with elevated privileges, it is important
to follow some basic rules of secure programming. David Wheeler has an
excellent book on this topic,
<ulink url="http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/index.html">Secure Programming for Linux and Unix HOWTO</ulink>.
</para>
<para>
When it comes to GLib and its associated libraries, GLib and
GObject are generally fine to use in code that runs with elevated
privileges; they don't load modules (executable code in shared objects)
or run other programs 'behind your back'.
</para>
<para>
When using GIO, you have to be more careful, since GIO has extension
points whose implementations get loaded from modules. However, GIO will
never load modules from your home-directory except when explictly asked
to do so via an environment variable.
</para>
<para>
In most cases, your helper program should be so small that you don't
need GIO, whose APIs are largely designed to support full-blown desktop
applications. If you can't resist the convenience of these APIs, here
are some steps you should take:
<itemizedlist>
<listitem><para>
Clear the environment, e.g. using the <function>clearenv()</function>
function.
David Wheeler has a good <ulink url="http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html">explanation</ulink> for why it is
important to sanitize the environment.
See the GIO <ulink url="http://developer.gnome.org/gio/stable/ch03.html">documentation</ulink>
for a list of all environment variables affecting GIO. In particular,
<envar>PATH</envar> (used to locate binaries), <envar>GIO_EXTRA_MODULES</envar> (used to locate loadable modules) and <envar>DBUS_{SYSTEM,SESSION}_BUS_ADDRESS</envar> (used to locate the D-Bus system and session bus) are important.
</para></listitem>
<listitem><para>
Don't use GVfs, by setting <envar>GIO_USE_VFS=local</envar> in the environment.
The reason to avoid GVfs in security-sensitive programs is that it uses
many libraries which have not necessarily been audited for security problems.
Gvfs is also heavily distributed and relies on a session bus to be present.
</para></listitem>
</itemizedlist>
</para>
</refsect2>
</refsect1>
</refentry>