www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - User defined safety?

reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
I wonder if anybody has brought up the idea of using or expanding the SafeD 
features to cover a user-defined kind of safety? Right now,  safe means 
memory safe and it is defined by the language. However, there are many kinds 
of safety that benefit from being layered in a manner similar to how 
safe/trusted/system works.

A web application for example might want to restrict raw sql access in one 
layer, where care is taken to avoid injection attacks. The rest of the 
application trusts only this layer and is forbidden from accessing the sql 
drivers directly.

A security audit script can grep for such forbidden use of sql, thus 
enforcing a 'provable' safe use of sql (with the liberal use of the word 
provable). In D it could be possible to enforce this layered design by the 
compiler. It is possible right now by an application programmer through the 
(ab)use of safe/trusted/system, by lumping memory and sql-injection safety 
together, though this has some serious drawbacks. What do you think of this, 
is it a good or bad use of these features?

Going further, SafeD could be expanded by allowing user defined security 
labels as parameters of safe/trusted/system. For example, the user could 
define  system(SQL) and  trusted(SQL) as well as  system(SMTP) and 
 trusted(SMTP).  safe code can use the  trusted sql and smtp components, but 
not  system. In this model,  trusted(SMTP) is only allowed to call 
 system(SMTP) and not  system(SQL).
Aug 26 2011
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
My pet feature request could do this too. User defined attributes
combined with a list of functions called by a function.

===

 custom("mysafe") void foo() {}
void bar() {}

 custom("mysafe") void main() {
   foo();
   bar();
}

CheckCustomSafety!("mysafe", main);

template CheckCustomSafety(string attribute, alias func) {
    static if(!__traits(hasCustomAttribute(func, attribute))
           pragma(error, func.stringof ~ " is not " ~ attribute);

      foreach(f; __traits(getCalledFunctions, func))
            CheckCustomSafety!(attribute, f);
}

====

And throw in an or for trusted.



The reason I want this is to check for things more like custom
purity, but I think it'd work for your custom safety too.

(and user defined attributes are just useful for other things too!)


The biggest problem I see with using my idea is the error
message will probably suck.
Aug 26 2011
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/26/2011 02:38 PM, Adam Ruppe wrote:
 My pet feature request could do this too. User defined attributes
 combined with a list of functions called by a function.

 ===

  custom("mysafe") void foo() {}
 void bar() {}

  custom("mysafe") void main() {
     foo();
     bar();
 }

 CheckCustomSafety!("mysafe", main);

 template CheckCustomSafety(string attribute, alias func) {
      static if(!__traits(hasCustomAttribute(func, attribute))
             pragma(error, func.stringof ~ " is not " ~ attribute);

        foreach(f; __traits(getCalledFunctions, func))
              CheckCustomSafety!(attribute, f);
 }

 ====

 And throw in an or for trusted.



 The reason I want this is to check for things more like custom
 purity, but I think it'd work for your custom safety too.

 (and user defined attributes are just useful for other things too!)


 The biggest problem I see with using my idea is the error
 message will probably suck.

I think it could be possible to provide decent error messages, by providing some means (via traits) to get line and file numbers of the calls. The biggest problem I see with this design is, that only functions reachable from main will be checked. I'd rather see something in the lines of mysafe.d __traits(declareCustomAttribute, "mysafe"); // can detect name clash __traits(declareCustomAttribute, "mytrusted"); __traits(declareCustomAttribute, "mysystem"); __traits(attribSetMutuallyExclusiveWithDefault, ["mysafe", "mytrusted","mysystem"],"mysystem"); __traits(registerStaticChecker, "mysafe", CheckMysafe); (the traits could be replaced by better syntax, of course) and then we could use int main() mysafe {} which would automatically be checked. There should also be some way to parameterize custom attributes, and to perform code transformations (probably that would require AST-macros and AST-pattern matching to be nice) __traits(declareCustomAttribute, "memoized(int=int.max)"); // maximum size of hash table. int foo(int x) memoized(100){ ... } // memoize at most 100 values
Aug 26 2011
prev sibling parent reply jdrewsen <jdrewsen nospam.com> writes:
Den 26-08-2011 14:38, Adam Ruppe skrev:
 My pet feature request could do this too. User defined attributes
 combined with a list of functions called by a function.

 ===

  custom("mysafe") void foo() {}
 void bar() {}

  custom("mysafe") void main() {
     foo();
     bar();
 }

 CheckCustomSafety!("mysafe", main);

 template CheckCustomSafety(string attribute, alias func) {
      static if(!__traits(hasCustomAttribute(func, attribute))
             pragma(error, func.stringof ~ " is not " ~ attribute);

        foreach(f; __traits(getCalledFunctions, func))
              CheckCustomSafety!(attribute, f);
 }

 ====

Couldn't this be used for marking classes as serializable. Something like this: class Foo { custom("serialize") Cake theCake; Bar cache; } SerializeCustom!("serialize", Foo); template SerializeCustom(string attribute, alias cls) { foreach (m; __traits(listMembers, cls)) { static if ( __traits(hasCustomAttribute(attribute, m) ) { Serializer.register(cls, m); } } } ---------- Though I would prefer if you could just write: custom("serialize") class Foo { ... } instead of: SerializeCustom!("serialize", Foo); /Jonas
Aug 30 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/30/11 12:41 PM, jdrewsen wrote:
 Couldn't this be used for marking classes as serializable. Something
 like this:

 class Foo {

  custom("serialize") Cake theCake;
 Bar cache;
 }

 SerializeCustom!("serialize", Foo);

 template SerializeCustom(string attribute, alias cls) {
 foreach (m; __traits(listMembers, cls)) {
 static if ( __traits(hasCustomAttribute(attribute, m) ) {
 Serializer.register(cls, m);
 }

 }
 }

 ----------

 Though I would prefer if you could just write:
  custom("serialize") class Foo { ... }

 instead of:
 SerializeCustom!("serialize", Foo);

I think a convention based on the name of the field shouldn't be half bad. Andrei
Aug 30 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Lutger Blijdestijn:

I wonder if anybody has brought up the idea of using or expanding the SafeD
features to cover a user-defined kind of safety?<

If you want to design this idea well, then I suggest you to read some papers a bout Securty Types. You are able to find a brief overview from page 58 of this good slides pack, that is a review (from 2003) of trends in type research: "Types and Programming Languages The Next Generation" by Benjamin C. Pierce: http://www.cis.upenn.edu/~bcpierce/papers/tng-lics2003-slides.pdf Bye, bearophile
Aug 28 2011