[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A (Low-Level) Opaque Object Proposal for R5RS

> ---------------------------------------------------------------------------
> [1].     (MAKE-OPAQUE-TYPE                              . <passkey>)
> [2].     (     OPAQUE-UP   <opaque-type>       <object> . <passkey>)
> [3].     (     OPAQUE-DOWN              <opaque-object> . <passkey>)
> [4].     (     OPAQUE-TYPE                     <object>            )
> ---------------------------------------------------------------------------
> Both MAKE-OPAQUE-TYPE and OPAQUE-UP must be reserved identifiers so that
> users cannot re-define them to subvert the abstraction barriers they are
> designed to enforce.  By contrast, however, OPAQUE-DOWN and OPAQUE-TYPE
> need be reserved keywords only so they can be recognized syntactically by
> clever compilers to permit potentially more efficient code.  If they are
> re-bound by a user, no security breach could ensue.)

This is not true.  Suppose T is an allegedly opaque type (or instance
of a type) with secret passkey P, and I am a malign agent who wishes
to learn the secret passkey.  To keep this example simple, suppose
further that T is the only opaque type used by the program I wish to
subvert.  (I leave the generalization of this example as an exercise
for the reader.)  If OPAQUE-DOWN is not reserved, then all I have to
do is

  (define secret-passkey)
  (define secret-passkey-is-known-to-a-malign-agent #f)

  (define original-opaque-down opaque-down)

  (set! opaque-down
        (lambda (obj . rest)
          (if (not (null? rest))
              (begin (set! secret-passkey (car rest))
                     (set! secret-passkey-is-known-to-a-malign-agent #t)))
          (apply original-opaque-down obj rest)))

and wait a while.  If I'm impatient, and I have access both to an
object of type T and to an allegedly abstract operation on T whose
implementation calls OPAQUE-DOWN, then I won't even have to wait.