summaryrefslogtreecommitdiff
path: root/docs/users_guide/safe_haskell.rst
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-01-15 19:52:49 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-01-25 05:24:19 -0500
commit0a5e4f5f7d6cef16b6b11ac8d3a269b92016ed5d (patch)
tree9456f70f36a1d2fcc9ff6bf6bc6eab1c2beda862 /docs/users_guide/safe_haskell.rst
parentb1a32170a1b8e7a31c2dd28eb1b02f1375ea3998 (diff)
downloadhaskell-0a5e4f5f7d6cef16b6b11ac8d3a269b92016ed5d.tar.gz
Split glasgow_exts into several files (#17316)
Diffstat (limited to 'docs/users_guide/safe_haskell.rst')
-rw-r--r--docs/users_guide/safe_haskell.rst868
1 files changed, 0 insertions, 868 deletions
diff --git a/docs/users_guide/safe_haskell.rst b/docs/users_guide/safe_haskell.rst
deleted file mode 100644
index edfedda4b2..0000000000
--- a/docs/users_guide/safe_haskell.rst
+++ /dev/null
@@ -1,868 +0,0 @@
-.. _safe-haskell:
-
-Safe Haskell
-============
-
-.. index::
- single: safe haskell
-
-Safe Haskell is an extension to the Haskell language that is implemented
-in GHC as of version 7.2. It allows for unsafe code to be securely
-included in a trusted code base by restricting the features of GHC
-Haskell the code is allowed to use. Put simply, it makes the types of
-programs trustable.
-
-While a primary use case of Safe Haskell is running untrusted code, Safe
-Haskell doesn't provide this directly. Instead, Safe Haskell provides
-strict type safety. Without Safe Haskell, GHC allows many exceptions to
-the type system which can subvert any abstractions. By providing strict
-type safety, Safe Haskell enables developers to build their own library
-level sandbox mechanisms to run untrusted code.
-
-While Safe Haskell is an extension, it actually runs in the background
-for every compilation with GHC. It does this to track the type
-violations of modules to infer their safety, even when they aren't
-explicitly using Safe Haskell. Please refer to section
-:ref:`safe-inference` for more details of this.
-
-The design of Safe Haskell covers the following aspects:
-
-- A :ref:`safe language <safe-language>` dialect of Haskell that provides
- stricter guarantees about the code. It allows types and module boundaries to
- be trusted.
-
-- A *safe import* extension that specifies that the module being imported must
- be trusted.
-
-- A definition of *trust* (or safety) and how it operates, along with ways of
- defining and changing the trust of modules and packages.
-
-Safe Haskell, however, *does not offer* compilation safety. During
-compilation time it is possible for arbitrary processes to be launched,
-using for example the :ref:`custom pre-processor <pre-processor>` flag.
-This can be manipulated to either compromise a user's system at
-compilation time, or to modify the source code just before compilation
-to try to alter Safe Haskell flags. This is discussed further in section
-:ref:`safe-compilation`.
-
-.. _safe-use-cases:
-
-Uses of Safe Haskell
---------------------
-
-.. index::
- single: safe haskell uses
-
-Safe Haskell has been designed with two use cases in mind:
-
-- Enforcing strict type safety at compile time
-- Compiling and executing untrusted code
-
-Strict type-safety (good style)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Haskell offers a powerful type system and separation of pure and effectual
-functions through the ``IO`` monad. However, there are several loop holes in the
-type system, the most obvious being the ``unsafePerformIO :: IO a -> a``
-function. The safe language dialect of Safe Haskell disallows the use of such
-functions. This can be useful restriction as it makes Haskell code easier to
-analyse and reason about. It also codifies the existing culture in the Haskell
-community of trying to avoid unsafe functions unless absolutely necessary. As
-such, using the safe language (through the ``-XSafe`` flag) can be thought of as
-a way of enforcing good style, similar to the function of ``-Wall``.
-
-Building secure systems (restricted IO Monads)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. index::
- single: secure haskell
-
-Systems such as information flow control security, capability based
-security systems and DSLs for working with encrypted data.. etc can be
-built in the Haskell language as a library. However they require
-guarantees about the properties of Haskell that aren't true in general
-due to the presence of functions like ``unsafePerformIO``. Safe Haskell
-gives users enough guarantees about the type system to allow them to
-build such secure systems.
-
-As an example, let's define an interface for a plugin system where the
-plugin authors are untrusted, possibly malicious third-parties. We do
-this by restricting the plugin interface to pure functions or to a
-restricted ``IO`` monad that we have defined. The restricted ``IO``
-monad will only allow a safe subset of ``IO`` actions to be executed. We
-define the plugin interface so that it requires the plugin module,
-``Danger``, to export a single computation, ``Danger.runMe``, of type
-``RIO ()``, where ``RIO`` is a monad defined as follows:
-
-::
-
- -- While we use `Safe', the `Trustworthy' pragma would also be
- -- fine. We simply want to ensure that:
- -- 1) The module exports an interface that untrusted code can't
- -- abuse.
- -- 2) Untrusted code can import this module.
- --
- {-# LANGUAGE Safe #-}
-
- module RIO (RIO(), runRIO, rioReadFile, rioWriteFile) where
-
- -- Notice that symbol UnsafeRIO is not exported from this module!
- newtype RIO a = UnsafeRIO { runRIO :: IO a }
-
- instance Monad RIO where
- return = UnsafeRIO . return
- (UnsafeRIO m) >>= k = UnsafeRIO $ m >>= runRIO . k
-
- -- Returns True iff access is allowed to file name
- pathOK :: FilePath -> IO Bool
- pathOK file = {- Implement some policy based on file name -}
-
- rioReadFile :: FilePath -> RIO String
- rioReadFile file = UnsafeRIO $ do
- ok <- pathOK file
- if ok then readFile file else return ""
-
- rioWriteFile :: FilePath -> String -> RIO ()
- rioWriteFile file contents = UnsafeRIO $ do
- ok <- pathOK file
- if ok then writeFile file contents else return ()
-
-We then compile the ``Danger`` plugin using the new Safe Haskell
-``-XSafe`` flag:
-::
-
- {-# LANGUAGE Safe #-}
- module Danger ( runMe ) where
-
- runMe :: RIO ()
- runMe = ...
-
-Before going into the Safe Haskell details, let's point out some of the
-reasons this security mechanism would fail without Safe Haskell:
-
-- The design attempts to restrict the operations that ``Danger`` can perform by
- using types, specifically the ``RIO`` type wrapper around ``IO`` . The author
- of ``Danger`` can subvert this though by simply writing arbitrary ``IO``
- actions and using ``unsafePerformIO :: IO a -> a`` to execute them as pure
- functions.
-
-- The design also relies on ``Danger`` not being able to access the
- ``UnsafeRIO`` constructor. Unfortunately Template Haskell can be used to
- subvert module boundaries and so could be used to gain access to this
- constructor.
-
-- There is no way to place restrictions on the modules that ``Danger`` can
- import. This gives the author of ``Danger`` a very large attack surface,
- essentially any package currently installed on the system. Should any of
- these packages have a vulnerability, then the ``Danger`` module can exploit
- it.
-
-Safe Haskell prevents all these attacks. This is done by compiling the
-RIO module with the :extension:`Safe` or :extension:`Trustworthy` flag and compiling
-``Danger`` with the :extension:`Safe` flag. We explain each below.
-
-The use of :extension:`Safe` to compile ``Danger`` restricts the features of
-Haskell that can be used to a `safe subset <#safe-language>`__. This
-includes disallowing ``unsafePerformIO``, Template Haskell, pure FFI
-functions, RULES and restricting the operation of Overlapping Instances.
-The :extension:`Safe` flag also restricts the modules can be imported by
-``Danger`` to only those that are considered trusted. Trusted modules
-are those compiled with :extension:`Safe`, where GHC provides a mechanical
-guarantee that the code is safe. Or those modules compiled with
-:extension:`Trustworthy`, where the module author claims that the module is
-Safe.
-
-This is why the RIO module is compiled with :extension:`Safe` or
-:extension:`Trustworthy`>, to allow the ``Danger`` module to import it. The
-:extension:`Trustworthy` flag doesn't place any restrictions on the module like
-:extension:`Safe` does (expect to restrict overlapping instances to `safe
-overlapping instances <#safe-overlapping-instances>`__). Instead the
-module author claims that while code may use unsafe features internally,
-it only exposes an API that can used in a safe manner.
-
-However, the unrestricted use of :extension:`Trustworthy` is a problem as an
-arbitrary module can use it to mark themselves as trusted, yet
-:extension:`Trustworthy` doesn't offer any guarantees about the module, unlike
-:extension:`Safe`. To control the use of trustworthy modules it is recommended
-to use the :ghc-flag:`-fpackage-trust` flag. This flag adds an extra requirement
-to the trust check for trustworthy modules. It requires that for a
-trustworthy modules to be considered trusted, and allowed to be used in
-:extension:`Safe` compiled code, the client C compiling the code must tell GHC
-that they trust the package the trustworthy module resides in. This is
-essentially a way of for C to say, while this package contains
-trustworthy modules that can be used by untrusted modules compiled with
-:extension:`Safe`, I trust the author(s) of this package and trust the modules
-only expose a safe API. The trust of a package can be changed at any
-time, so if a vulnerability found in a package, C can declare that
-package untrusted so that any future compilation against that package
-would fail. For a more detailed overview of this mechanism see
-:ref:`safe-trust`.
-
-In the example, ``Danger`` can import module ``RIO`` because ``RIO`` is
-compiled with :extension:`Safe`. Thus, ``Danger`` can make use of the
-``rioReadFile`` and ``rioWriteFile`` functions to access permitted file
-names. The main application then imports both ``RIO`` and ``Danger``. To
-run the plugin, it calls ``RIO.runRIO Danger.runMe`` within the ``IO``
-monad. The application is safe in the knowledge that the only ``IO`` to
-ensue will be to files whose paths were approved by the ``pathOK`` test.
-
-The Safe Haskell checks can be disabled for a module by passing the
-:ghc-flag:`-fno-safe-haskell` flag. This is useful in particular when compiling
-with source plugins as running a plugin marks the module as unsafe and can then
-cause downstream modules to fail the safety checks.
-
-.. _safe-language:
-
-Safe Language
--------------
-
-.. index::
- single: safe language
-
-The Safe Haskell *safe language* (enabled by ``-XSafe``) guarantees the
-following properties:
-
-- *Referential transparency* — The types can be trusted. Any pure function, is
- guaranteed to be pure. Evaluating them is deterministic and won't cause any
- side effects. Functions in the ``IO`` monad are still allowed and behave as
- usual. So, for example, the ``unsafePerformIO :: IO a -> a`` function is
- disallowed in the safe language to enforce this property.
-
-- *Module boundary control* — Only symbols that are publicly available through
- other module export lists can be accessed in the safe language. Values using
- data constructors not exported by the defining module, cannot be examined or
- created. As such, if a module ``M`` establishes some invariants through
- careful use of its export list, then code written in the safe language that
- imports ``M`` is guaranteed to respect those invariants.
-
-- *Semantic consistency* — For any module that imports a module written in the
- safe language, expressions that compile both with and without the safe import
- have the same meaning in both cases. That is, importing a module written in
- the safe language cannot change the meaning of existing code that isn't
- dependent on that module. So, for example, there are some restrictions placed
- on the use of :ref:`OverlappingInstances <instance-overlap>`, as these can
- violate this property.
-
-- *Strict subset* — The safe language is strictly a subset of Haskell as
- implemented by GHC. Any expression that compiles in the safe language has the
- same meaning as it does when compiled in normal Haskell.
-
-These four properties guarantee that in the safe language you can trust
-the types, can trust that module export lists are respected, and can
-trust that code that successfully compiles has the same meaning as it
-normally would.
-
-To achieve these properties, in the safe language dialect we disable
-completely the following features:
-
-- :extension:`TemplateHaskell` — Can be used to gain access to constructors and
- abstract data types that weren't exported by a module, subverting module
- boundaries.
-
-Furthermore, we restrict the following features:
-
-- :extension:`ForeignFunctionInterface` — Foreign import declarations that
- import a function with a non-``IO`` type are disallowed.
-
-- ``RULES`` — Rewrite rules defined in a module M compiled with
- :extension:`Safe` are dropped. Rules defined in Trustworthy modules that
- ``M`` imports are still valid and will fire as usual.
-
-- :extension:`OverlappingInstances` — There is no restriction on the creation
- of overlapping instances, but we do restrict their use at a particular call
- site. This is a detailed restriction, please refer to :ref:`Safe Overlapping
- Instances <safe-overlapping-instances>` for details.
-
-- :extension:`GeneralisedNewtypeDeriving` — GND is not allowed in the safe
- language. This is due to the ability of it to violate module boundaries when
- module authors forget to put nominal role annotations on their types as
- appropriate. For this reason, the ``Data.Coerce`` module is also considered
- unsafe. We are hoping to find a better solution here in the future.
-
-- ``GHC.Generics`` — Hand crafted instances of the ``Generic`` type class are
- not allowed in Safe Haskell. Such instances aren't strictly unsafe, but
- there is an important invariant that a ``Generic`` instance should adhere to
- the structure of the data type for which the instance is defined, and
- allowing manually implemented ``Generic`` instances would break that
- invariant. Derived instances (through the :extension:`DeriveGeneric`
- extension) are still allowed. Note that the only allowed
- :ref:`deriving strategy <deriving-strategies>` for deriving ``Generic`` under
- Safe Haskell is ``stock``, as another strategy (e.g., ``anyclass``) would
- produce an instance that violates the invariant.
-
- Refer to the
- :ref:`generic programming <generic-programming>` section for more details.
-
-.. _safe-overlapping-instances:
-
-Safe Overlapping Instances
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Due to the semantic consistency guarantee of Safe Haskell, we must
-restrict the function of overlapping instances. We don't restrict their
-ability to be defined, as this is a global property and not something we
-can determine by looking at a single module. Instead, when a module
-calls a function belonging to a type-class, we check that the instance
-resolution done is considered 'safe'. This check is enforced for modules
-compiled with both ``-XSafe`` and ``-XTrustworthy``.
-
-More specifically, consider the following modules:
-
-::
-
- {-# LANGUAGE Safe #-}
- module Class (TC(..)) where
- class TC a where { op :: a -> String }
-
- {-# LANGUAGE Safe #-}
- module Dangerous (TC(..)) where
- import Class
-
- instance
- {-# OVERLAPS #-}
- TC [Int] where { op _ = "[Int]" }
-
- {-# LANGUAGE Safe #-}
- module TCB_Runner where
- import Class
- import Dangerous
-
- instance
- TC [a] where { op _ = "[a]" }
-
- f :: String
- f = op ([1,2,3,4] :: [Int])
-
-Both module ``Class`` and module ``Dangerous`` will compile under :extension:`Safe`
-without issue. However, in module ``TCB_Runner``, we must check if the call
-to ``op`` in function ``f`` is safe.
-
-What does it mean to be Safe? That importing a module compiled with
-:extension:`Safe` shouldn't change the meaning of code that compiles fine
-without importing the module. This is the Safe Haskell property known as
-*semantic consistency*.
-
-In our situation, module ``TCB_Runner`` compiles fine without importing
-module ``Dangerous``. So when deciding which instance to use for the call to
-``op``, if we determine the instance ``TC [Int]`` from module Dangerous
-is the most specific, this is unsafe. This prevents code written by
-third-parties we don't trust (which is compiled using ``-XSafe`` in Safe
-Haskell) from changing the behaviour of our existing code.
-
-Specifically, we apply the following rule to determine if a type-class
-method call is *unsafe* when overlapping instances are involved:
-
-- Most specific instance, ``Ix``, defined in an ``-XSafe`` compiled module.
-- ``Ix`` is an orphan instance or a multi-parameter-type-class.
-- At least one overlapped instance, ``Iy``, is both:
-
- - From a different module than ``Ix``
- - ``Iy`` is not marked ``OVERLAPPABLE``
-
-This is a slightly involved heuristic, but captures the situation of an
-imported module ``N`` changing the behaviour of existing code. For example,
-if the second condition isn't violated, then the module author ``M`` must
-depend either on a type-class or type defined in ``N``.
-
-When a particular type-class method call is considered unsafe due to
-overlapping instances, and the module being compiled is using :extension:`Safe`
-or :extension:`Trustworthy`, then compilation will fail. For :extension:`Unsafe`, no
-restriction is applied, and for modules using safe inference, they will
-be inferred unsafe.
-
-.. _safe-imports:
-
-Safe Imports
-------------
-
-.. index::
- single: safe imports
-
-Safe Haskell enables a small extension to the usual import syntax of
-Haskell, adding a ``safe`` keyword:
-
-.. code-block:: none
-
- impdecl -> import [safe] [qualified] modid [as modid] [impspec]
-
-When used, the module being imported with the safe keyword must be a
-trusted module, otherwise a compilation error will occur. The safe
-import extension is enabled by either of the ``-XSafe`` , ``-XTrustworthy`` , or
-``-XUnsafe`` flags. When the ``-XSafe`` flag is used, the ``safe`` keyword is
-allowed but meaningless, as every import is treated as a safe import.
-
-.. _safe-trust:
-
-Trust and Safe Haskell Modes
-----------------------------
-
-.. index::
- single: safe haskell trust
- single: trust
-
-Safe Haskell introduces the following three language flags:
-
-- :extension:`Safe` — Enables the safe language dialect, asking GHC to guarantee trust.
- The safe language dialect requires that all imports be trusted or a
- compilation error will occur. Safe Haskell will also infer this safety type
- for modules automatically when possible. Please refer to section
- :ref:`safe-inference` for more details of this.
-
-- :extension:`Trustworthy` — Means that while this module may invoke unsafe functions
- internally, the module's author claims that it exports an API that can't be
- used in an unsafe way. This doesn't enable the safe language. It does however
- restrict the resolution of overlapping instances to only allow :ref:`safe
- overlapping instances <safe-overlapping-instances>`. The trust guarantee is
- provided by the module author, not GHC. An import statement with the ``safe``
- keyword results in a compilation error if the imported module is not trusted.
- An import statement without the keyword behaves as usual and can import any
- module whether trusted or not.
-
-- :extension:`Unsafe` — Marks the module being compiled as unsafe so that modules
- compiled using :extension:`Safe` can't import it. You may want to explicitly mark a
- module unsafe when it exports internal constructors that can be used to
- violate invariants.
-
-While these are flags, they also correspond to Safe Haskell module types
-that a module can have. You can think of using these as declaring an
-explicit contract (or type) that a module must have. If it is invalid,
-then compilation will fail. GHC will also infer the correct type for
-Safe Haskell, please refer to section :ref:`safe-inference` for more
-details.
-
-The procedure to check if a module is trusted or not depends on if the
-:ghc-flag:`-fpackage-trust` flag is present. The check is similar in both cases
-with the :ghc-flag:`-fpackage-trust` flag enabling an extra requirement for
-trustworthy modules to be regarded as trusted.
-
-Trust check (``-fpackage-trust`` disabled)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. index::
- single: trust check
-
-A module ``M`` in a package ``P`` is trusted by a client C if and only if:
-
-- Both of these hold:
-
- - The module was compiled with :extension:`Safe`
- - All of M's direct imports are trusted by C
-
-- *or* all of these hold:
-
- - The module was compiled with :extension:`Trustworthy`
- - All of ``M``\'s direct *safe imports* are trusted by C
-
-The above definition of trust has an issue. Any module can be compiled
-with :extension:`Trustworthy` and it will be trusted. To control this, there is
-an additional definition of package trust (enabled with the
-:ghc-flag:`-fpackage-trust` flag). The point of package trust is to require that
-the client C explicitly say which packages are allowed to contain
-trustworthy modules. Trustworthy packages are only trusted if they
-reside in a package trusted by C.
-
-Trust check (``-fpackage-trust`` enabled)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. index::
- single: trust check
- single: -fpackage-trust
-
-When the :ghc-flag:`-fpackage-trust` flag is enabled, whether or not a module is
-trusted depends on if certain packages are trusted. Package trust is
-determined by the client C invoking GHC (i.e. you).
-
-Specifically, a package *P is trusted* when one of these hold:
-
-- C's package database records that ``P`` is trusted (and no command-line
- arguments override this)
-- C's command-line flags say to trust ``P`` regardless of what is recorded
- in the package database.
-
-In either case, C is the only authority on package trust. It is up to
-the client to decide which `packages they trust <#safe-package-trust>`__.
-
-When the :ghc-flag:`-fpackage-trust` flag is used a *module M from package P is
-trusted by a client C* if and only if:
-
-- Both of these hold:
-
- - The module was compiled with :extension:`Safe`
- - All of ``M``\'s direct imports are trusted by C
-
-- *or* all of these hold:
-
- - The module was compiled with :extension:`Trustworthy`
- - All of ``M``\'s direct safe imports are trusted by C
- - Package ``P`` is trusted by C
-
-For the first trust definition the trust guarantee is provided by GHC
-through the restrictions imposed by the safe language. For the second
-definition of trust, the guarantee is provided initially by the module
-author. The client C then establishes that they trust the module author
-by indicating they trust the package the module resides in. This trust
-chain is required as GHC provides no guarantee for :extension:`Trustworthy`
-compiled modules.
-
-The reason there are two modes of checking trust is that the extra
-requirement enabled by :ghc-flag:`-fpackage-trust` causes the design of Safe
-Haskell to be invasive. Packages using Safe Haskell when the flag is
-enabled may or may not compile depending on the state of trusted
-packages on a user's machine. This is both fragile, and causes
-compilation failures for everyone, even if they aren't trying to use any
-of the guarantees provided by Safe Haskell. Disabling
-:ghc-flag:`-fpackage-trust` by default and turning it into a flag makes Safe
-Haskell an opt-in extension rather than an always on feature.
-
-.. _safe-trust-example:
-
-Example
-~~~~~~~
-
-::
-
- Package Wuggle:
- {-# LANGUAGE Safe #-}
- module Buggle where
- import Prelude
- f x = ...blah...
-
- Package P:
- {-# LANGUAGE Trustworthy #-}
- module M where
- import System.IO.Unsafe
- import safe Buggle
-
-Suppose a client C decides to trust package ``P`` and package ``base``. Then
-does C trust module ``M``? Well ``M`` is marked :extension:`Trustworthy`, so we don't
-restrict the language. However, we still must check ``M``\'s imports:
-
-- First, ``M`` imports ``System.IO.Unsafe``. This is an unsafe module, however
- ``M`` was compiled with :extension:`Trustworthy` , so ``P``\'s author takes
- responsibility for that import. ``C`` trusts ``P``\'s author, so this import
- is fine.
-
-- Second, ``M`` safe imports ``Buggle``. For this import ``P``\'s author takes
- no responsibility for the safety, instead asking GHC to check whether
- ``Buggle`` is trusted by ``C``. Is it?
-
-- ``Buggle``, is compiled with ``-XSafe``, so the code is machine-checked to be
- OK, but again under the assumption that all of ``Buggle``\'s imports are
- trusted by ``C``. We must recursively check all imports!
-
-- Buggle only imports ``Prelude``, which is compiled with :extension:`Trustworthy`.
- ``Prelude`` resides in the ``base`` package, which ``C`` trusts, and (we'll
- assume) all of ``Prelude``\'s imports are trusted. So ``C`` trusts
- ``Prelude``, and so ``C`` also trusts Buggle. (While ``Prelude`` is typically
- imported implicitly, it still obeys the same rules outlined here).
-
-Notice that C didn't need to trust package Wuggle; the machine checking
-is enough. C only needs to trust packages that contain :extension:`Trustworthy`
-modules.
-
-.. _trustworthy-guarantees:
-
-Trustworthy Requirements
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. index::
- single: trustworthy
-
-Module authors using the :extension:`Trustworthy` language extension for a
-module ``M`` should ensure that ``M``\'s public API (the symbols exposed by its
-export list) can't be used in an unsafe manner. This mean that symbols exported
-should respect type safety and referential transparency.
-
-.. _safe-package-trust:
-
-Package Trust
-~~~~~~~~~~~~~
-
-.. index::
- single: package trust
-
-Safe Haskell gives packages a new Boolean property, that of trust.
-Several new options are available at the GHC command-line to specify the
-trust property of packages:
-
-.. ghc-flag:: -trust ⟨pkg⟩
- :shortdesc: Expose package ⟨pkg⟩ and set it to be trusted. See
- :ref:`safe-haskell`.
- :type: dynamic
- :category: packages
-
- Exposes package ⟨pkg⟩ if it was hidden and considers it a
- trusted package regardless of the package database.
-
-.. ghc-flag:: -distrust ⟨pkg⟩
- :shortdesc: Expose package ⟨pkg⟩ and set it to be distrusted. See
- :ref:`safe-haskell`.
- :type: dynamic
- :category: packages
-
- Exposes package ⟨pkg⟩ if it was hidden and considers it
- an untrusted package regardless of the package database.
-
-.. ghc-flag:: -distrust-all-packages
- :shortdesc: Distrust all packages by default. See :ref:`safe-haskell`.
- :type: dynamic
- :category: packages
-
- Considers all packages distrusted unless they are
- explicitly set to be trusted by subsequent command-line options.
-
-To set a package's trust property in the package database please refer
-to :ref:`packages`.
-
-.. _safe-inference:
-
-Safe Haskell Inference
-----------------------
-
-.. index::
- single: safe inference
-
-In the case where a module is compiled without one of :extension:`Safe`,
-:extension:`Trustworthy` or :extension:`Unsafe` being used, GHC will try to figure out
-itself if the module can be considered safe. This safety inference will
-never mark a module as trustworthy, only as either unsafe or as safe.
-GHC uses a simple method to determine this for a module M: If M would
-compile without error under the :extension:`Safe` flag, then M is marked as
-safe. Otherwise, it is marked as unsafe.
-
-When should you use Safe Haskell inference and when should you use an
-explicit :extension:`Safe` flag? The later case should be used when you have a
-hard requirement that the module be safe. This is most useful for the
-:ref:`safe-use-cases` of Safe Haskell: running untrusted code. Safe
-inference is meant to be used by ordinary Haskell programmers. Users who
-probably don't care about Safe Haskell.
-
-Haskell library authors have a choice. Most should just use Safe
-inference. Assuming you avoid any unsafe features of the language then
-your modules will be marked safe. Inferred vs. Explicit has the
-following trade-offs:
-
-- *Inferred* — This works well and adds no dependencies on the Safe Haskell type
- of any modules in other packages. It does mean that the Safe Haskell type of
- your own modules could change without warning if a dependency changes. One
- way to deal with this is through the use of :ref:`Safe Haskell warning flags
- <safe-flag-summary>` that will warn if GHC infers a Safe Haskell type
- different from expected.
-
-- *Explicit* — This gives your library a stable Safe Haskell type that others
- can depend on. However, it will increase the chance of compilation failure
- when your package dependencies change.
-
-.. _safe-flag-summary:
-
-Safe Haskell Flag Summary
--------------------------
-
-.. index::
- single: Safe Haskell flags
-
-In summary, Safe Haskell consists of the following three language flags:
-
-.. extension:: Safe
- :shortdesc: Enable the :ref:`Safe Haskell <safe-haskell>` Safe mode.
-
- :since: 7.2.1
-
- Restricts the module to the safe language. All of the module's
- direct imports must be trusted, but the module itself need not
- reside in a trusted package, because the compiler vouches for its
- trustworthiness. The "safe" keyword is allowed but meaningless in
- import statements, as regardless, every import is required to be
- safe.
-
- - *Module Trusted* — Yes
- - *Haskell Language* — Restricted to Safe Language
- - *Imported Modules* — All forced to be safe imports, all must be trusted.
-
-.. extension:: Trustworthy
- :shortdesc: Enable the :ref:`Safe Haskell <safe-haskell>` Trustworthy mode.
-
- :since: 7.2.1
-
- This establishes that the module is trusted, but the guarantee is
- provided by the module's author. A client of this module then
- specifies that they trust the module author by specifying they trust
- the package containing the module. :extension:`Trustworthy` doesn't restrict the
- module to the safe language. It does however restrict the resolution of
- overlapping instances to only allow :ref:`safe overlapping instances
- <safe-overlapping-instances>`. It also allows the use of the safe import
- keyword.
-
- - *Module Trusted* — Yes.
- - *Module Trusted* (:ghc-flag:`-fpackage-trust` enabled) — Yes but only if the package
- the module resides in is also trusted.
- - *Haskell Language* — Unrestricted, except only safe overlapping instances
- allowed.
- - *Imported Modules* — Under control of module author which ones must be
- trusted.
-
-.. extension:: Unsafe
- :shortdesc: Enable :ref:`Safe Haskell <safe-haskell>` Unsafe mode.
-
- :since: 7.4.1
-
- Mark a module as unsafe so that it can't be imported by code
- compiled with :extension:`Safe`. Also enable the Safe Import extension so that a
- module can require
- a dependency to be trusted.
-
- - *Module Trusted* — No
- - *Haskell Language* — Unrestricted
- - *Imported Modules* — Under control of module author which ones must be
- trusted.
-
-A flag to disable Safe Haskell checks:
-
-.. ghc-flag:: -fno-safe-haskell
- :shortdesc: Disable :ref:`Safe Haskell <safe-haskell>`
- :type: dynamic
-
- This flag can be enabled to override any declared safety property of the
- module (Safe, Unsafe, Trustworthy) so compilation proceeds as if none of
- these flags were specified. This is particularly useful when compiling
- using plugins, which usually results in the compiled modules being marked
- as unsafe.
-
-And one general flag:
-
-.. ghc-flag:: -fpackage-trust
- :shortdesc: Enable :ref:`Safe Haskell <safe-haskell>` trusted package
- requirement for trustworthy modules.
- :type: dynamic
- :category: packages
-
- When enabled, turn on an extra check for a trustworthy module ``M``,
- requiring the package that ``M`` resides in be considered trusted, for ``M``
- to be considered trusted.
-
-And five warning flags:
-
-.. ghc-flag:: -Wunsafe
- :shortdesc: warn if the module being compiled is regarded to be unsafe.
- See :ref:`safe-haskell`
- :type: dynamic
- :reverse: -Wno-unsafe
- :category: warnings
-
- Issue a warning if the module being compiled is regarded to be
- unsafe. Should be used to check the safety type of modules when
- using safe inference.
-
-.. ghc-flag:: -Wsafe
- :shortdesc: warn if the module being compiled is regarded to be safe.
- :type: dynamic
- :reverse: -Wno-safe
- :category: warnings
-
- Issue a warning if the module being compiled is regarded to be safe.
- Should be used to check the safety type of modules when using safe
- inference. If the module is explicitly marked as safe then no warning will
- be issued.
-
-.. ghc-flag:: -Wtrustworthy-safe
- :shortdesc: warn if the module being compiled is marked as
- :extension:`Trustworthy` but it could instead be marked as
- :extension:`Safe`, a more informative bound.
- :type: dynamic
- :reverse: -Wno-safe
- :category: warnings
-
- Issue a warning if the module being compiled is marked as
- -XTrustworthy but it could instead be marked as
- -XSafe , a more informative bound. Can be used to detect once a Safe Haskell
- bound can be improved as dependencies are updated.
-
-.. ghc-flag:: -Winferred-safe-imports
- :shortdesc: warn when an explicitly Safe Haskell module imports a Safe-Inferred one
- :type: dynamic
- :reverse: -Wno-inferred-safe-imports
- :category:
-
- :since: 8.10.1
-
- .. index::
- single: safe haskell imports, warning
-
- The module ``A`` below is annotated to be explicitly ``Safe``, but it imports
- ``Safe-Inferred`` module. ::
-
- {-# LANGUAGE Safe #-}
- module A where
-
- import B (double)
-
- quad :: Int -> Int
- quad = double . double
-
-
- module B where
-
- double :: Int -> Int
- double n = n + n
-
- The inferred status is volatile: if an unsafe import is added to the module
- ``B``, it will cause compilation error of ``A``. When
- :ghc-flag:`-Winferred-safe-imports` is enabled, the compiler will emit a
- warning about this.
- This option is off by default.
-
-.. ghc-flag:: -Wmissing-safe-haskell-mode
- :shortdesc: warn when the Safe Haskell mode is not explicitly specified.
- :type: dynamic
- :reverse: -Wno-missing-safe-haskell-mode
- :category:
-
- :since: 8.10.1
-
- .. index::
- single: safe haskell mode, missing
-
- The compiler will warn when none of :extension:`Safe`,
- :extension:`Trustworthy` or :extension:`Unsafe` is specified.
- This option is off by default.
-
-.. _safe-compilation:
-
-Safe Compilation
-----------------
-
-.. index::
- single: safe compilation
-
-GHC includes a variety of flags that allow arbitrary processes to be run
-at compilation time. One such example is the
-:ref:`custom pre-processor <pre-processor>` flag. Another is the ability of
-Template Haskell to execute Haskell code at compilation time, including
-IO actions. Safe Haskell *does not address this danger* (although,
-Template Haskell is a disallowed feature).
-
-Due to this, it is suggested that when compiling untrusted source code
-that has had no manual inspection done, the following precautions be
-taken:
-
-- Compile in a sandbox, such as a chroot or similar container
- technology. Or simply as a user with very reduced system access.
-
-- Compile untrusted code with the ``-XSafe``
- flag being specified on the command line. This will ensure that
- modifications to the source being compiled can't disable the use of
- the Safe Language as the command line flag takes precedence over a
- source level pragma.
-
-- Ensure that all untrusted code is imported as a
- :ref:`safe import <safe-imports>` and that the :ghc-flag:`-fpackage-trust`
- flag (see :ref:`flag <safe-package-trust>`) is used with packages from
- untrusted sources being marked as untrusted.
-
-There is a more detailed discussion of the issues involved in
-compilation safety and some potential solutions on the
-:ghc-wiki:`GHC Wiki <safe-haskell/safe-compilation>`.
-
-Additionally, the use of :ref:`annotations <annotation-pragmas>` is forbidden,
-as that would allow bypassing Safe Haskell restrictions. See :ghc-ticket:`10826`
-for details.