summaryrefslogtreecommitdiff
path: root/docs/users_guide/safe_haskell.xml
blob: 04a244b3aff70750402e6d3dca0f56d78255df01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
<?xml version="1.0" encoding="iso-8859-1"?>
<sect1 id="safe-haskell">
  <title>Safe Haskell</title>
  <indexterm><primary>safe haskell</primary></indexterm>

  <para>
  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. Safe
  Haskell is aimed to be as minimal as possible while still providing strong
  enough guarantees about compiled Haskell code for more advance secure systems
  to be built on top of it.
  </para>

  <para>
  While this is the use case that Safe Haskell was motivated by it is important
  to understand that what Safe Haskell is tracking and enforcing is a stricter
  form of type safety than is usually guaranteed in Haskell. As part of this,
  Safe Haskell is run during every compilation of GHC, tracking safety and
  inferring it even for modules that don't explicitly use Safe Haskell. Please
  refer to section <xref linkend="safe-inference"/> for more details of this.
  This also means that there are some design choices that from a security point
  of view may seem strange but when thought of from the angle of tracking type
  safety are logical. Feedback on the current design and this tension between
  the security and type safety view points is welcome.
  </para>

  <para>
  The design of Safe Haskell covers the following aspects:

  <itemizedlist>
    <listitem>A <link linkend="safe-language">safe language</link> dialect of
      Haskell that provides guarantees about the code. It allows types and
      module boundaries to be trusted.
    </listitem>
    <listitem>A <emphasis>safe import</emphasis> extension that specifies that
      the module being imported must be trusted.
    </listitem>
    <listitem>A definition of <emphasis>trust</emphasis> (or safety) and how it
      operates, along with ways of defining and changing the trust of modules
      and packages.
    </listitem>
  </itemizedlist>
  </para>

  <para>
  Safe Haskell, however, <emphasis>does not offer</emphasis> compilation
  safety. During compilation time it is possible for arbitrary processes to be
  launched, using for example the <link linkend="pre-processor">custom
    pre-processor</link> flag. This can be manipulated to either compromise a
  users system at compilation time, or to modify the source code just before
  compilation to try to alter set Safe Haskell flags. This is discussed further
  in section <xref linkend="safe-compilation"/>.
  </para>

  <sect2 id="safe-use-cases">
    <title>Uses of Safe Haskell</title>
    <indexterm><primary>safe haskell uses</primary></indexterm>

    <para>
    Safe Haskell has been designed with two use cases in mind:

    <itemizedlist>
      <listitem>Enforcing strict type safety at compile time</listitem>
      <listitem>Compiling and executing untrusted code</listitem>
    </itemizedlist>
    </para>

    <sect3>
      <title>Strict type-safety (good style)</title>

      Haskell offers a powerful type system and separation of pure and
      effectual functions through the <literal>IO</literal> monad. There are
      several loop holes in the type system though, the most obvious offender
      being the <literal>unsafePerformIO :: IO a -> a</literal> function. The
      safe language dialect of Safe Haskell disallows the use of such
      functions. This can be useful for a variety of purposes as it makes
      Haskell code easier to analyse and reason about. It also codifies an
      existing culture in the Haskell community of trying to avoid using such
      unsafe functions unless absolutely necessary. As such using the safe
      language (through the <option>-XSafe</option> flag) can be thought of as
      a way of enforcing good style, similar to the function of
      <option>-Wall</option>.
    </sect3>

    <sect3>
      <title>Building secure systems (restricted IO Monads)</title>
      <indexterm><primary>secure haskell</primary></indexterm>

      <para>
      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 simply as a library. However they require
      guarantees about the properties of the Haskell language that aren't true
      in the general case where uses of functions like <literal>unsafePerformIO
      </literal> are allowed. Safe Haskell is designed to give users enough
      guarantees about the safety properties of compiled code so that such
      secure systems can be built.
      </para>

      <para>
      As an example lets 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 <literal>IO</literal> monad that we have defined that only
      allows a safe subset of <literal>IO</literal> actions to be executed. We
      define the plugin interface here so that it requires the plugin module,
      <literal>Danger</literal>, to export a single computation,
      <literal>Danger.runMe</literal>, of type <literal>RIO ()</literal>, where
      <literal>RIO</literal> is a new monad defined as follows:
      </para>

      <programlisting>
        -- Either of the following Safe Haskell pragmas would do
        {-# LANGUAGE Trustworthy #-}
        {-# 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 &lt;- pathOK file
          if ok then readFile file else return ""

        rioWriteFile :: FilePath -> String -> RIO ()
        rioWriteFile file contents = UnsafeRIO $ do
          ok &lt;- pathOK file
          if ok then writeFile file contents else return ()
      </programlisting>

      We compile Danger using the new Safe Haskell <option>-XSafe</option> flag:

      <programlisting>
        {-# LANGUAGE Safe #-}
        module Danger ( runMe ) where

        runMe :: RIO ()
        runMe = ...
      </programlisting>

      <para>
      Before going into the Safe Haskell details, lets point out some of
      the reasons this design would fail without Safe Haskell:
      </para>

      <itemizedlist>
        <listitem>The design attempts to restrict the operations that Danger
          can perform by using types, specifically the <literal>RIO</literal>
          type wrapper around <literal>IO</literal>. The author of Danger can
          subvert this though by simply writing arbitrary
          <literal>IO</literal> actions and using <literal>unsafePerformIO ::
          IO a -> a</literal> to execute them as pure functions.
        </listitem>
        <listitem>The design also relies on the Danger module not being able
          to access the <literal>UnsafeRIO</literal> constructor.
          Unfortunately Template Haskell can be used to subvert module
          boundaries and so could be used to gain access to this constructor.
        </listitem>
        <listitem>There is no way to place restrictions on the modules that
          the untrusted Danger module 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 this. The
          only way to stop this would be to patch or remove packages with
          known vulnerabilities even if they should only be used by
          trusted code such as the RIO module.
        </listitem>
      </itemizedlist>

      <para>
      To stop these attacks Safe Haskell can be used. This is done by compiling
      the RIO module with the <option>-XTrustworthy</option> flag and compiling
      the Danger module with the <option>-XSafe</option> flag.
      </para>

      <para>
      The use of the <option>-XSafe</option> flag to compile the Danger module
      restricts the features of Haskell that can be used to a
      <link linkend="safe-language">safe subset</link>. This includes
      disallowing <literal>unsafePerformIO</literal>, Template Haskell, pure
      FFI functions, Generalized Newtype Deriving, RULES and restricting the
      operation of Overlapping Instances. The <option>-XSafe</option> flag also
      restricts the modules can be imported by Danger to only those that are
      considered trusted. Trusted modules are those compiled with
      <option>-XSafe</option>, where GHC provides a mechanical guarantee that
      the code is safe. Or those modules compiled with
      <option>-XTrustworthy</option>, where the module author claims that the
      module is Safe.
      </para>

      <para>
      This is why the RIO module is compiled with
      <option>-XTrustworthy</option>, to allow the Danger module to import it.
      The <option>-XTrustworthy</option> flag doesn't place any restrictions on
      the module like <option>-XSafe</option> does. 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. The use of
      <option>-XTrustworthy</option> by itself marks the module as trusted.
      There is an issue here as <option>-XTrustworthy</option> may be used by
      an arbitrary module and module author. To control the use of trustworthy
      modules it is recommended to use the <option>-fpackage-trust</option>
      flag. This flag adds an extra requirement to the trust check for
      trustworthy modules, such that for trustworthy modules to be considered
      trusted, and allowed to be used in <option>-XSafe</option> 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 <option>-XSafe </option>, 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 <xref linkend="safe-trust"/>.
      </para>

      <para>
      In the example, Danger can import module RIO because RIO is marked
      trustworthy. 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.
      </para>
    </sect3>
  </sect2>

  <sect2 id="safe-language">
    <title>Safe Language</title>
    <indexterm><primary>safe language</primary></indexterm>

    The Safe Haskell <emphasis>safe language</emphasis> guarantees the
    following properties:

    <itemizedlist>
      <listitem><emphasis>Referential transparency</emphasis> &mdash; Functions
        in the safe language are deterministic, evaluating them will not
        cause any side effects. Functions in the <literal>IO</literal> monad
        are still allowed and behave as usual. Any pure function though, as
        according to its type, is guaranteed to indeed be pure. This property
        allows a user of the safe language to trust the types. This means,
        for example, that the <literal>unsafePerformIO :: IO a -> a</literal>
        function is disallowed in the safe language.
      </listitem>
      <listitem><emphasis>Module boundary control</emphasis> &mdash; Haskell
        code compiled using the safe language is guaranteed to only access
        symbols that are publicly available to it through other modules export
        lists. An important part of this is that safe compiled code is not
        able to examine or create data values using data constructors
        that it cannot import. If a module M establishes some invariants
        through careful use of its export list then code compiled using the
        safe language that imports M is guaranteed to respect those invariants.
        Because of this, <emphasis><link linkend="template-haskell">Template
        Haskell</link></emphasis> and <emphasis>
        <link linkend="newtype-deriving">GeneralizedNewtypeDeriving</link>
        </emphasis> are disabled in the safe language as they can be used
        to violate this property.
      </listitem>
      <listitem><emphasis>Semantic consistency</emphasis> &mdash; 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. In addition, in any module
        that imports a safe language module, expressions that compile both
        with and without the safe import have the same meaning in both cases.
        That is, importing a module using 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 <emphasis>
        <link linkend="instance-overlap">Overlapping Instances</link>
        </emphasis> extension as it can violate this property.
      </listitem>
    </itemizedlist>

    <para>
    These three 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.
    </para>

    Lets now look at the details of the safe language. In the safe language
    dialect (enabled by <option>-XSafe</option>) we disable completely the
    following features:

    <itemizedlist>
      <listitem><emphasis>GeneralizedNewtypeDeriving</emphasis> &mdash; It can
        be used to violate constructor access control, by allowing untrusted
        code to manipulate protected data types in ways the data type author
        did not intend, breaking invariants they have established.</listitem>
      <listitem><emphasis>TemplateHaskell</emphasis> &mdash; Is particularly
        dangerous, as it can cause side effects even at compilation time and
        can be used to access constructors of abstract data types.</listitem>
   </itemizedlist>

    In the safe language dialect we restrict the following features:
    <itemizedlist>
      <listitem><emphasis>ForeignFunctionInterface</emphasis> &mdash; This is
        mostly safe, but foreign import declarations that import a function
        with a non-IO type are disallowed. All FFI imports must reside in the
        IO Monad.</listitem>
      <listitem><emphasis>RULES</emphasis> &mdash; As they can change the
        behaviour of trusted code in unanticipated ways, violating semantic
        consistency, they are restricted in function. Specifically any RULES
        defined in a module M compiled with <option>-XSafe</option> are
        dropped. RULES defined in trustworthy modules that M imports are still
        valid and will fire as usual.</listitem>
      <listitem><emphasis>OverlappingInstances</emphasis> &mdash; This
        extension can be used to violate semantic consistency, because
        malicious code could redefine a type instance (by containing a more
        specific instance definition) in a way that changes the behaviour of
        code importing the untrusted module. The extension is not disabled for
        a module M compiled with <option>-XSafe</option> but restricted. While M
        can define overlapping instance declarations, they can only overlap
        other instance declaration defined in M. If in a module N that imports
        M, at a call site that uses a type-class function there is a choice of
        which instance to use (i.e. an overlap) and the most specific instances
        is from M, then all the other choices must also be from M. If not, a
        compilation error will occur. A simple way to think of this is a
        <emphasis>same origin policy</emphasis> for overlapping instances
        defined in Safe compiled modules.</listitem>
     <listitem><emphasis>Data.Typeable</emphasis> &mdash; We restrict Typeable
        instances to only derived ones (offered by GHC through the 
        <link linkend="deriving-typeable"><option>-XDeriveDataTypeable</option>
        </link> extension). Hand crafted instances of the Typeable type class
        are not allowed in Safe Haskell as this can easily be abused to 
        unsafely coerce between types.</listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="safe-imports">
    <title>Safe Imports</title>
    <indexterm><primary>safe imports</primary></indexterm>

    Safe Haskell enables a small extension to the usual import syntax of
    Haskell, adding a <emphasis>safe</emphasis> keyword:
    <programlisting>
      impdecl -> import [safe] [qualified] modid [as modid] [impspec]
    </programlisting>

    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 <option>-XSafe</option>,
    <option>-XTrustworthy</option>, or <option>-XUnsafe</option>
    flags and corresponding PRAGMA's. When the <option>-XSafe</option> flag
    is used, the safe keyword is allowed but meaningless, every import
    is required to be safe regardless.
  </sect2>

  <sect2 id="safe-trust">
    <title>Trust and Safe Haskell Modes</title>
    <indexterm><primary>safe haskell trust</primary></indexterm>
    <indexterm><primary>trust</primary></indexterm>

    The Safe Haskell extension introduces the following three language flags:

    <itemizedlist>
      <listitem><emphasis>-XSafe</emphasis> &mdash; 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.</listitem>
      <listitem><emphasis>-XTrustworthy</emphasis> &mdash; 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 or place any restrictions on the
        allowed Haskell code. 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.</listitem>
      <listitem><emphasis>-XUnsafe</emphasis> &mdash; Marks the module being
        compiled as unsafe so that modules compiled using
        <option>-XSafe</option> can't import it.
      </listitem>
    </itemizedlist>

    <para>
    The procedure to check if a module is trusted or not depends on if the
    <option>-fpackage-trust</option> flag is present. The check is very similar
    in both cases with the presence of the <option>-fpackage-trust</option>
    flag simply enabling an extra requirement for trustworthy modules to be
    regarded as trusted.
    </para>

    <sect3>
      <title>Trust check (<option>-fpackage-trust</option> disabled)</title>
      <indexterm><primary>trust check</primary></indexterm>

      <para>
      A <emphasis>module M in a package P is trusted by a client C</emphasis>
      if and only if:

      <itemizedlist>
        <listitem>Both of these hold:
          <itemizedlist>
            <listitem>The module was compiled with <option>-XSafe</option>
              </listitem>
            <listitem>All of M's direct imports are trusted by C</listitem>
          </itemizedlist>
        </listitem>
        <listitem><emphasis>OR</emphasis> all of these hold:
          <itemizedlist>
            <listitem>The module was compiled with
              <option>-XTrustworthy</option></listitem>
            <listitem>All of M's direct safe imports are trusted by C</listitem>
          </itemizedlist>
        </listitem>
      </itemizedlist>
      </para>

      <para>
      The above definition of trust has an issue. Any module can be compiled
      with -XTrustworthy and it will be trusted regardless of what it does. To
      control this there is an additional definition of package trust (enabled
      with the <option>-fpackage-trust</option> flag). The point of package
      trusts is to require that the client C explicitly say which packages are
      allowed to contain trustworthy modules. That is, C establishes that it
      trusts a package P and its author and so trust the modules in P that use
      <option>-XTrustworthy</option>. When package trust is enabled, any
      modules that are considered trustworthy but reside in a package that
      isn't trusted are not considered trusted. A more formal definition is
      given in the next section.
      </para>
    </sect3>

    <sect3>
      <title>Trust check (<option>-fpackage-trust</option> enabled)</title>
      <indexterm><primary>trust check</primary></indexterm>
      <indexterm><primary>-fpackage-trust</primary></indexterm>

      <para>
      When the <option>-fpackage-trust</option> flag is enabled, whether or not
      a module is trusted depends on a notion of trust for packages, which is
      determined by the client C invoking GHC (i.e. you). A package <emphasis>P
      is trusted</emphasis> when one of these hold:
      <itemizedlist>
        <listitem>C's package database records that P is trusted (and no
          command-line arguments override this)</listitem>
        <listitem>C's command-line flags say to trust P regardless of what is
          recorded in the package database.</listitem>
      </itemizedlist>
      </para>

      <para>
      In either case, C is the only authority on package trust. It is up to the
      client to decide which <link linkend="safe-package-trust">packages they
      trust</link>.
      </para>

      <para>
      When the <option>-fpackage-trust</option> flag is used a <emphasis>module M from
      package P is trusted by a client C</emphasis> if and only if:

      <itemizedlist>
        <listitem>Both of these hold:
          <itemizedlist>
            <listitem> The module was compiled with <option>-XSafe</option>
              </listitem>
            <listitem> All of M's direct imports are trusted by C</listitem>
          </itemizedlist>
        </listitem>
        <listitem><emphasis>OR</emphasis> all of these hold:
          <itemizedlist>
            <listitem>The module was compiled with
              <option>-XTrustworthy</option></listitem>
            <listitem>All of M's direct safe imports are trusted by C</listitem>
            <listitem>Package P is trusted by C</listitem>
          </itemizedlist>
        </listitem>
      </itemizedlist>
      </para>

      <para>
      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
      <literal>-XTrustworthy</literal> compiled modules.
      </para>

      <para>
      The reason there are two modes of checking trust is that the extra
      requirement enabled by <option>-fpackage-trust</option> 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 users machine. A maintainer of a package
      <literal>foo</literal> that uses Safe Haskell so that security conscious
      Haskellers can use <literal>foo</literal> now may have other users of
      <literal>foo</literal> who don't know or care about Safe Haskell
      complaining about compilation problems they are having with
      <literal>foo</literal>because a package <literal>bar</literal>that foo
      requires, isn't trusted on their machine. In this sense, the
      <option>-fpackage-trust</option> flag can be thought of as a flag to
      properly turn on Safe Haskell while without it, it's operating in a
      covert fashion.
      </para>

      <para>
      Having the <option>-fpackage-trust</option> flag also nicely unifies the
      semantics of how Safe Haskell works when used explicitly and how modules
      are <ulink linkend="safe-inference">inferred as safe</ulink>.
      </para>
    </sect3>

    <sect3 id="safe-trust-example">
      <title>Example</title>

      <programlisting>
        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
      </programlisting>

      <para>
      Suppose a client C decides to trust package P. Then does C trust module
      M? To decide, GHC must check M's imports &mdash; M imports
      System.IO.Unsafe. M was compiled with <option>-XTrustworthy</option>, so
      P's author takes responsibility for that import. C trusts P's author, so
      C trusts M to only use its unsafe imports in a safe and consistent
      manner with respect to the API M exposes. M also has a safe import of
      Buggle, so for this import P's author takes no responsibility for the
      safety, so GHC must check whether Buggle is trusted by C. Is it? Well,
      it is compiled with <option>-XSafe</option>, so the code in Buggle
      itself is machine-checked to be OK, but again under the assumption that
      all of Buggle's imports are trusted by C. Prelude comes from base, which
      C trusts, and is compiled with <option>-XTrustworthy</option> (While
      Prelude is typically imported implicitly, it still obeys the same rules
      outlined here). So Buggle is considered trusted.
      </para>

      <para>
      Notice that C didn't need to trust package Wuggle; the machine checking
      is enough. C only needs to trust packages that contain
      <option>-XTrustworthy</option> modules.
      </para>
    </sect3>

    <sect3 id="trustworthy-guarantees">
      <title>Trustworthy Requirements</title>
      <indexterm><primary>trustworthy</primary></indexterm>

      Module authors using the <option>-XTrustworthy</option> 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.
    </sect3>

    <sect3 id="safe-package-trust">
      <title>Package Trust</title>
      <indexterm><primary>package trust</primary></indexterm>

      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:

      <itemizedlist>
        <listitem><emphasis>-trust P</emphasis> &mdash; Exposes package P if it
          was hidden and considers it a trusted package regardless of the
          package database.</listitem>
        <listitem><emphasis>-distrust P</emphasis> &mdash; Exposes package P if
          it was hidden and considers it an untrusted package regardless of the
          package database.</listitem>
        <listitem><emphasis>-distrust-all-packages</emphasis> &mdash; Considers
          all packages distrusted unless they are explicitly set to be trusted
          by subsequent command-line options.</listitem>
      </itemizedlist>

      To set a package's trust property in the package database please refer to
      <xref linkend="packages"/>.
    </sect3>

  </sect2>

  <sect2 id="safe-inference">
    <title>Safe Haskell Inference</title>
    <indexterm><primary>safe inference</primary></indexterm>

    <para>
    In the case where a module is compiled without one of
    <option>-XSafe</option>, <option>-XTrustworthy</option> or
    <option>-XUnsafe</option> 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 <option>-XSafe</option> flag, then M is marked as safe. If M
    would fail to compile under the <option>-XSafe</option> flag, then it is
    marked as unsafe. 
    </para>

    <para>
    When should you use Safe Haskell inference and when should you use an
    explicit <option>-XSafe</option> flag? The later case should be used when
    you have a hard requirement that the module be safe. That is, the
    <ulink linkend="safe-use-cases">use cases</ulink> outlined and the purpose
    for which Safe Haskell is intended: compiling untrusted code. Safe
    inference is meant to be used by ordinary Haskell programmers. Users who
    probably don't care about Safe Haskell. 
    </para>

    <para>
    Say you are writing a Haskell library. Then you probably just want to use
    Safe inference. Assuming you avoid any unsafe features of the language then
    your modules will be marked safe. This is a benefit as now a user of your
    library who may want to use it as part of an API exposed to untrusted code
    can use the library without change. If there wasn't safety inference then
    either the writer of the library would have to explicitly use Safe Haskell,
    which is an unreasonable expectation of the whole Haskell community. Or the
    user of the library would have to wrap it in a shim that simply re-exported
    your API through a trustworthy module, an annoying practice.
    </para>
  </sect2>

  <sect2 id="safe-flag-summary">
    <title>Safe Haskell Flag Summary</title>
    <indexterm><primary>safe haskell flags</primary></indexterm>

    In summary, Safe Haskell consists of the following three language flags:

    <variablelist>
      <varlistentry>
        <term>-XSafe</term>
        <indexterm><primary>-XSafe</primary></indexterm>
        <listitem>To be trusted, 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,
          every import is required to be safe regardless.
          <itemizedlist>
            <listitem><emphasis>Module Trusted</emphasis> &mdash; Yes</listitem>
            <listitem><emphasis>Haskell Language</emphasis> &mdash; Restricted to Safe
              Language</listitem>
            <listitem><emphasis>Imported Modules</emphasis> &mdash; All forced to be
              safe imports, all must be trusted.</listitem>
          </itemizedlist>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>-XTrustworthy</term>
        <indexterm><primary>-XTrustworthy</primary></indexterm>
        <listitem>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.
          <option>-XTrustworthy</option> has no effect on the accepted range
          of Haskell programs or their semantics, except that they allow the
          safe import keyword.
          <itemizedlist>
            <listitem><emphasis>Module Trusted</emphasis> &mdash; Yes.</listitem>
            <listitem><emphasis>Module Trusted (<option>-fpackage-trust</option>
              enabled)</emphasis> &mdash; Yes but only if the package the module
              resides in is also trusted.</listitem>
            <listitem><emphasis>Haskell Language</emphasis> &mdash; Unrestricted
            </listitem>
            <listitem><emphasis>Imported Modules</emphasis> &mdash; Under control of
              module author which ones must be trusted.</listitem>
          </itemizedlist>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>-XUnsafe</term>
        <indexterm><primary>-XUnsafe</primary></indexterm>
        <listitem>Mark a module as unsafe so that it can't be imported by code
          compiled with <option>-XSafe</option>. Also enable the Safe Import
          extension so that a module can require a dependency to be trusted.
          <itemizedlist>
            <listitem><emphasis>Module Trusted</emphasis> &mdash; No</listitem>
            <listitem><emphasis>Haskell Language</emphasis> &mdash;
              Unrestricted</listitem>
            <listitem><emphasis>Imported Modules</emphasis> &mdash; Under control of
              module author which ones must be trusted.</listitem>
          </itemizedlist>
        </listitem>
      </varlistentry>

    </variablelist>

    And one general flag:

    <variablelist>
      <varlistentry>
        <term>-fpackage-trust</term>
        <indexterm><primary>-fpackage-trust</primary></indexterm>
        <listitem>When enabled turn on an extra check for a trustworthy module
          M, requiring that the package M resides in is considered trusted for
          the M to be considered trusted.
        </listitem>
      </varlistentry>
    </variablelist>

    And two warning flags:

    <variablelist>
      <varlistentry>
        <term>-fwarn-unsafe</term>
        <indexterm><primary>-fwarn-unsafe</primary></indexterm>
        <listitem>Issue a warning if the module being compiled is regarded
          to be unsafe. Should be used to check the safety status of modules
          when using safe inference.
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>-fwarn-safe</term>
        <indexterm><primary>-fwarn-safe</primary></indexterm>
        <listitem>Issue a warning if the module being compiled is regarded
          to be safe. Should be used to check the safety status of modules
          when using safe inference.
        </listitem>
      </varlistentry>
    </variablelist>
  </sect2>

  <sect2 id="safe-compilation">
    <title>Safe Compilation</title>
    <indexterm><primary>safe compilation</primary></indexterm>

    <para>
    GHC includes a variety of flags that allow arbitrary processes to be run at
    compilation time. One such example is the <link
      linkend="pre-processor">custom pre-processor</link> flag. Another is the
    ability of Template Haskell to execute Haskell code at compilation time,
    including IO actions. Safe Haskell <emphasis>does not address this
      danger</emphasis> (although, Template Haskell is a disallowed feature).
    </para>

    <para>
    Due to this, it is suggested that when compiling untrusted source code that
    has had no manual inspection done, the following precautions be taken:
    <itemizedlist>
      <listitem>Compile in a sandbox, such as a chroot or similar container
        technology. Or simply as a user with very reduced system
        access.</listitem>
      <listitem>Compile untrusted code with the <option>-XSafe</option> 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.</listitem>
      <listitem>Ensure that all untrusted code is imported as a
        <link linkend="safe-imports">safe import</link><emphasis> and</emphasis>
        that the <link linkend="safe-package-trust"><option>-fpackage-trust</option></link>
        flag is used with packages from untrusted sources being marked as
        untrusted.</listitem>
    </itemizedlist>
    </para>

    <para>
    There is a more detailed discussion of the issues involved in compilation
    safety and some potential solutions on the <ulink
      url="http://ghc.haskell.org/trac/ghc/wiki/SafeHaskell/SafeCompilation">GHC
      Wiki</ulink>.
    </para>

  </sect2>

</sect1>

<!-- Emacs stuff:
     ;;; Local Variables: ***
     ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter" "sect1") ***
     ;;; End: ***
 -->