Jesse Phillips wrote:
> On Tue, 03 Nov 2009 23:13:14 -0600, Andrei Alexandrescu wrote:
>
>>> I think the only real option is to have the importer decide if it is
>>> trusted.
>> That can't work. I can't say that stdc.stdlib is trusted no matter how
>> hard I try. I mean free is there!
>
> I would like to disagree here.
>
> void free(void *ptr);
>
> free() takes a pointer. There is no way for the coder to get a pointer in
> SafeD, compiler won't let them, so the function is unusable by a "safe"
> module even if the function is imported.

Pointers should be available to SafeD, just not certain operations with
them.

Andrei

Andrei Alexandrescu, el  3 de noviembre a las 17:54 me escribiste:
> Leandro Lucarella wrote:
> >Andrei Alexandrescu, el  3 de noviembre a las 16:33 me escribiste:
> >>SafeD is, unfortunately, not finished at the moment. I want to leave
> >>in place a stub that won't lock our options. Here's what we
> >>currently have:
> >>
> >>module(system) calvin;
> >>
> >>This means calvin can do unsafe things.
> >>
> >>module(safe) susie;
> >>
> >>This means susie commits to extra checks and therefore only a subset of D.
> >>
> >>module hobbes;
> >>
> >>This means hobbes abides to whatever the default safety setting is.
> >>
> >>The default safety setting is up to the compiler. In dmd by default
> >>it is "system", and can be overridden with "-safe".
> >
> >What's the rationale for letting the compiler decide? I can't see nothing
> >system, I think the default should be defined (I'm not sure what the
> >default should be though).
>
> The parenthesis pretty much destroys your point :o).

I guess this is a joke, but I have to ask: why? I'm not sure about plenty
of stuff, that doesn't mean they are pointless.

> I don't think letting the implementation decide is a faulty model.
> If you know what you want, you say it. Otherwise it means you don't
> care.

I can't understand how you can't care. Maybe I'm misunderstanding the
proposal, since nobody else seems to see a problem here.

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
CAMPAÑA POR LA PAZ: APLASTARON JUGUETES BÉLICOS
-- Crónica TV

Walter Bright, el  3 de noviembre a las 16:21 me escribiste:
> Andrei Alexandrescu wrote:
> >Sketch of the safe rules:
> >
> >\begin{itemize*}
> >\item No @cast@ from a pointer type to an integral type and vice versa
>
> replace integral type with non-pointer type.
>
> >\item No @cast@ between unrelated pointer types
> >\item Bounds checks on all array accesses
> >\item  No  unions  that  include  a reference  type  (array,  @class@,
> >  pointer, or @struct@ including such a type)
>
> pointers are not a reference type. Replace "reference type" with
> "pointers or reference types".

Strictly speaking, arrays are not reference types either, right?

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Nos retiramos hasta la semana que viene reflexionando sobre nuestras
vidas: "Qué vida de mier'... Qué vida de mier'!"
-- Sidharta Kiwi

Michel Fortin Wrote:

> How is this supposed to work correctly with and without the "-safe"
> compiler flag? The way you define things "-safe" would make module
> memory safe for use while it is not.

"-safe" would cause the compiler to check if the code was safe and error out if it wasn't. Not sure how it would work out for the precompiled libraries.

Leandro Lucarella wrote:
> Andrei Alexandrescu, el  3 de noviembre a las 17:54 me escribiste:
>> Leandro Lucarella wrote:
>>> Andrei Alexandrescu, el  3 de noviembre a las 16:33 me escribiste:
>>>> SafeD is, unfortunately, not finished at the moment. I want to leave
>>>> in place a stub that won't lock our options. Here's what we
>>>> currently have:
>>>>
>>>> module(system) calvin;
>>>>
>>>> This means calvin can do unsafe things.
>>>>
>>>> module(safe) susie;
>>>>
>>>> This means susie commits to extra checks and therefore only a subset of D.
>>>>
>>>> module hobbes;
>>>>
>>>> This means hobbes abides to whatever the default safety setting is.
>>>>
>>>> The default safety setting is up to the compiler. In dmd by default
>>>> it is "system", and can be overridden with "-safe".
>>> What's the rationale for letting the compiler decide? I can't see nothing
>>> system, I think the default should be defined (I'm not sure what the
>>> default should be though).
>> The parenthesis pretty much destroys your point :o).
>
> I guess this is a joke, but I have to ask: why? I'm not sure about plenty
> of stuff, that doesn't mean they are pointless.

Oh, I see what you mean. The problem is that many are as unsure as you
are about what the default should be. If too many are unsure, maybe the
decision should be left as a choice.

>> I don't think letting the implementation decide is a faulty model.
>> If you know what you want, you say it. Otherwise it means you don't
>> care.
>
> I can't understand how you can't care. Maybe I'm misunderstanding the
> proposal, since nobody else seems to see a problem here.

It's not a proposal as much as a discussion opener, but my suggestion is
that if you just say module without any qualification, you leave it to
the person compiling to choose the safety level.

Andrei

Leandro Lucarella wrote:
> Walter Bright, el  3 de noviembre a las 16:21 me escribiste:
>> Andrei Alexandrescu wrote:
>>> Sketch of the safe rules:
>>>
>>> \begin{itemize*}
>>> \item No @cast@ from a pointer type to an integral type and vice versa
>> replace integral type with non-pointer type.
>>
>>> \item No @cast@ between unrelated pointer types
>>> \item Bounds checks on all array accesses
>>> \item  No  unions  that  include  a reference  type  (array,  @class@,
>>>  pointer, or @struct@ including such a type)
>> pointers are not a reference type. Replace "reference type" with
>> "pointers or reference types".
>
> Strictly speaking, arrays are not reference types either, right?
>
>

Ok, in order to not create confusion, I changed that. Here's the new

\begin{itemize*}
\item No @cast@ from a pointer type to a non-pointer type (e.g.~@int@)
and vice versa
\item No @cast@ between unrelated pointer types
\item Bounds checks on all array accesses
\item No  unions that include pointer  type, a @class@  type, an array
type, or a @struct@ embedding such a type
\item No pointer arithmetic
\item Taking the  address of a local is forbidden  (in fact the needed
restriction is to  not allow such an address to  escape, but that is
more difficult to track)
\item Cross-module function calls must only go to other @safe@ modules
\item No inline assembler
\item No casting away of @const@, @immutable@, or @shared@
\item No calls to unsafe functions
\end{itemize*}

Andrei

Andrei Alexandrescu wrote:
> How can we address that? Again, I'm looking for a simple, robust,
> extensible design that doesn't lock our options.
>
>
> Thanks,
>
> Andrei
You may want to have a look at the CoreCLR security model (that's used
by silverlight / moonlight). It's quite similar to what you've proposed.
http://www.mono-project.com/Moonlight2CoreCLR#Security_levels

Btw, is there a reason why safety should be specified at the module
level? As we have attributes now that would be a perfect usecase for
them: example:

@Safety(Safe)
void doSomething()...

or:
@Safety.Critical
void doSomething()...

where that attribute could be applied to functions, classes, modules, ...

Another related question: Will there be a way to provide different
implementations for different safety levels?

version(Safety.Critical)
{
//Some unsafe yet highly optimized asm stuff here
}
else
{
//Same thing in safe
}

Andrei Alexandrescu wrote:
> Don wrote:
>> Andrei Alexandrescu wrote:
>>> Don wrote:
>>>> Andrei Alexandrescu wrote:
>>
>>> module(safe) is not a comment. We need three types of modules because
>>> of the interaction between what the module declares and what the
>>> command line wants.
>>>
>>> Let's assume the default, no-flag build allows unsafe code, like
>>> right now. Then, module(safe) means that the module volunteers itself
>>> for tighter checking, and module(system) is same as module unadorned.
>>>
>>> But then if the user compiles with -safe, module(safe) is the same as
>>> module unadorned, and module(system) allows for unchecked operations
>>> in that particular module. I was uncomfortable with this, but Walter
>>> convinced me that D's charter is not to allow sandbox compilation and
>>> execution of malicious code. If you have the sources, you may as well
>>> take a look at their module declarations if you have some worry.
>>>
>>> Regardless on the result of the debate regarding the default
>>> compilation mode, if the change of that default mode is allowed in
>>> the command line, then we need both module(safe) and module(system).
>>
>> When would it be MANDATORY for a module to be compiled in safe mode?
>
> module(safe) entails safe mode, come hell or high water.
>
>> If module(safe) implies bound-checking *cannot* be turned off for that
>> module, would any standard library modules be module(safe)?
>
> I think most or all of the standard library is trusted. But don't forget
> that std is a bad example of a typical library or program because std
> interfaces programs with the OS.

I think it's not so atypical. Database, graphics, anything which calls a
C library will be the same.
For an app, I'd imagine you'd have a policy of either always compiling
with -safe, or ignoring it.
If you've got a general-purpose library, you have to assume some of your
users will be compiling with -safe. So you have to make all your library
modules safe, regardless of how they are marked. (Similarly, -w is NOT
optional for library developers).

That doesn't leave very much.
I'm not seeing the use case for module(safe).

Andrei Alexandrescu Wrote:

> Jesse Phillips wrote:
> > On Tue, 03 Nov 2009 23:13:14 -0600, Andrei Alexandrescu wrote:
> >
> >>> I think the only real option is to have the importer decide if it is
> >>> trusted.
> >> That can't work. I can't say that stdc.stdlib is trusted no matter how
> >> hard I try. I mean free is there!
> >
> > I would like to disagree here.
> >
> > void free(void *ptr);
> >
> > free() takes a pointer. There is no way for the coder to get a pointer in
> > SafeD, compiler won't let them, so the function is unusable by a "safe"
> > module even if the function is imported.
>
> Pointers should be available to SafeD, just not certain operations with
> them.
>
> Andrei

I must have been confused by the statement:

"As long as these pointers are not exposed to the client, such an implementation might be certified to be SafeD compatible1 ."

Found on the article for SafeD. I realize things may change, just sounded like pointers were not ever an option.

jpf wrote:
> Andrei Alexandrescu wrote:
>> How can we address that? Again, I'm looking for a simple, robust,
>> extensible design that doesn't lock our options.
>>
>>
>> Thanks,
>>
>> Andrei
> You may want to have a look at the CoreCLR security model (that's used
> by silverlight / moonlight). It's quite similar to what you've proposed.
> http://www.mono-project.com/Moonlight2CoreCLR#Security_levels

I don't have much time right now, but here's what a cursory look reveals:

====================
Security levels

The CoreCLR security model divide all code into three distinct levels:
transparent, safe-critical and critical. This model is much simpler to
understand (and implement) than CAS (e.g. no stack-walk). Only a few
rules can describe much of it.
====================

The keywords "security" and "stack-walk" give it away that this is a
matter of software security, not language safety. These are quite different.

> Btw, is there a reason why safety should be specified at the module
> level? As we have attributes now that would be a perfect usecase for
> them: example:
>
> @Safety(Safe)
> void doSomething()...
>
> or:
> @Safety.Critical
> void doSomething()...
>
> where that attribute could be applied to functions, classes, modules, ...
>
> Another related question: Will there be a way to provide different
> implementations for different safety levels?
>
> version(Safety.Critical)
> {
>    //Some unsafe yet highly optimized asm stuff here
> }
> else
> {
>    //Same thing in safe
> }

I think it muddies things too much to allow people to make safety
decisions at any point (e.g., I'm not a fan of C#'s unsafe).

Andrei

1 2 3 4 5