| Thread overview | ||||||||
|---|---|---|---|---|---|---|---|---|
|
August 26, 2011 User defined safety? | ||||
|---|---|---|---|---|
| ||||
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). | ||||
August 26, 2011 Re: User defined safety? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Lutger Blijdestijn | 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.
| |||
August 26, 2011 Re: User defined safety? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam Ruppe | 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 | |||
August 28, 2011 Re: User defined safety? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Lutger Blijdestijn | 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 | |||
August 30, 2011 Re: User defined safety? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam Ruppe | 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 | |||
August 30, 2011 Re: User defined safety? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to jdrewsen | 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
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply