digitalmars.D - User defined safety?
- Lutger Blijdestijn (22/22) Aug 26 2011 I wonder if anybody has brought up the idea of using or expanding the Sa...
- Adam Ruppe (23/23) Aug 26 2011 My pet feature request could do this too. User defined attributes
- Timon Gehr (22/45) Aug 26 2011 I think it could be possible to provide decent error messages, by
- jdrewsen (21/38) Aug 30 2011 Couldn't this be used for marking classes as serializable. Something
- Andrei Alexandrescu (3/22) Aug 30 2011 I think a convention based on the name of the field shouldn't be half ba...
- bearophile (6/7) Aug 28 2011 If you want to design this idea well, then I suggest you to read some pa...
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
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
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
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
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
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