TLDR: An interface I'm trying to use contains a few "optional_policy" macros. Using it (or any form of "optional") inside a tunable_policy macro results in a syntax error. What is the correct way to accomplish this? See update below.
Long Version: I'm new to SELinux and currently working on a module to constrain a user application on Debian. One of the things I'd like to do is add a boolean to toggle network access. I created a basic policy module using the something similar to the following:
sepolicy generate --application -n mymodule /usr/share/foo/foo
I added a new tunable to the generated module.
gen_tunable(mymodule_use_network,false)
tunable_policy(`mymodule_use_network',`
sysnet_dns_name_resolve(mymodule_t)
')
The interface call shown above was generated by sepolicy and I just moved it into the tunable_policy macro. Once I get the DNS working I'll move the rest of the network permissions in.
I have experimented using both the optional_policy macro and the plain optional statement directly. When using the generated script to build and load my module I get the following output in all cases:
Building and Loading Policy
+ make -f /usr/share/selinux/devel/Makefile mymodule.pp
Compiling default mymodule module
mymodule.te:65:ERROR 'syntax error' at token 'optional' on line 4858:
optional {
#line 65
/usr/bin/checkmodule: error(s) encountered while parsing configuration
make: *** [/usr/share/selinux/devel/include/Makefile:166: tmp/mymodule.mod] Error 1
+ exit
I have noticed that the file that defines these macros has a helper function regarding commented lines and m4, but I have no idea what it's doing. Is something like that my issue here? As a workaround I can copy the contents of the interface into my macro but that defeats the purpose. What am I missing here? Is it really the case that this is expected and no other tunable in the reference policy contains a nested optional statement?
Update:I've boiled it down to the following if/optional statement combination. According to the SELinux Notebook optional statements are valid within if statements in policy modules so I'm really at a loss.
if(`mymodule_use_network'){
optional {
require {
type fonts_t;
}
allow mymodule_t fonts_t:dir getattr;
}
}
Actually, it only now starts to sink in here that according to documentation "optional" statement is not allowed in conditionals.
A workaround is to wrap the "tunable_policy","if" or "booleanif" construct with an "optional" instead.
native module policy, something like:
module myfoo 1.0;
bool foo true;
type bar;
require { class process signal; }
if (foo) {
allow bar self:process signal;
} else {
dontaudit bar self:process signal;
}
optional {
if (foo) {
require { type baz; class file read; }
allow bar baz:file read;
}
}
or refpolicy, something along the lines of:
policy_module(myfoo, 1.0)
gen_tunable(foo, true)
type bar;
tunable_policy(`foo',`
allow bar self:process signal;
',`
dontaudit bar self:process signal;
')
optional_policy(`
tunable_policy(`foo',`
gen_require(` type baz; ')
allow bar baz:file read;
')
')
or native common intermediate language:
(boolean foo true)
(type bar)
(booleanif foo
(true
(allow bar self (process (signal))))
(false
(dontaudit bar self (process (signal)))))
(optional foo_optional
(booleanif foo
(true
(allow bar baz (file (read))))))
Syntax error maybe? Your stuff does not look like what is documented
What is the compiler telling you?
Do note though that not all statements are allowed in conditionals. You are for example not allowed to declare/associate type attributes in conditionals. Ensure that any interfaces you call in conditionals do not declare/associate type attributes (or any other things that aren't allowed)
The only statements and rules allowed within the if / else construct are:
allow, auditallow, auditdeny, dontaudit, type_member, type_transition (except file_name_transition), type_change and require.
By the way: sysnet_dns_name_resolve() is not realistically optional.
It is kind of confusing because you are essentially using two policy languages (the reference policy abstraction and the native module policy) The `' is specific to reference policy (refpolicies' use of M4 to be precise) That is not something that native module policy uses.
Consider the following code:
public class TestClass
{
public int? NullableInt { get; set; }
private bool DoPreChecks()
{
if(NullableInt == null)
return false;
return true;
}
public bool DoTest()
{
if(!DoPreChecks())
return false;
//Here R# tells me that "nullableInt" may be null
if (NullableInt.Value > 10)
{
// Do something
}
return true;
}
}
R# would be correct to worry that "NullableInt.Value" may be null when I reference it in "DoTest", except that if it was, then "DoPreChecks" would have returned false and that means I would never have gotten to this line. I was looking at R#'s code annotations and I see I can tell it what output to expect under limited conditions and it seems like that may be something I could leverage here, but I don't see any way to tell it that when the output is true/false/null/notnull, then a class variable (which has nothing to do with the input or output) will have a certain value type (true/false/null/notnull). Can something like this be done?
The use case here is this -- I have a dozen methods that all rely on the same preconditions, including several class variables being initialized. Rather than putting all those checks in each method, I want to have them all run the "DoPreChecks" method and if it returns true, we're good to go. The problem is that R# can't follow that and thinks I have lots of possible null reference exceptions. I could:
Ignore the errors completely and just tolerate wiggly lines everywhere
Disable and restore the warning at the beginning and ending of these methods
Disable the warning 1 line at a time
Do null checks or assertions before each use
The problem with each is...
Violates company policy to just ignore warnings
Disabling this check over large swaths of code would be worse than ignoring individual warnings because other valid issues may be there, but get disabled
This would require a LOT of R# comments, thus negating the helpfulness of DoPreChecks method
Same as #3
Right now I'm leaning toward getting an exception on the policy and just ignoring the warnings, but if there is a way to tell R# what is going on, that would be a much better solution. Can it be done without adding parameters or complicating the return type?
There is no contract annotation in ReSharper that sets up a relation between return value of a method and nullness of a field/property
Is there an attribute like #[warn(redundant_result_as_return_type)] to show a warning that Result is redundant as a return type?
#[derive(Debug)]
struct SomeError();
fn process_some() -> Result<(), SomeError> {
Ok(())
}
fn main() {
process_some().unwrap();
}
(playground)
This code produces no warnings despite the fact that Result is not needed as the return type at all.
I've been deciding how to properly implement error handling of a function from the crate used in my project. After digging into the function implementation, it turned out that no errors are generated.
Since then, I want to prevent such cases in my own code. Ideally it would be great to get such warnings from inside of imported crates too, when utilizing methods with redundant Results, but as far as I understand such checking is impossible for used crates without adjusting their code.
The question is in some way the opposite of Possible to declare functions that will warn on unused results in Rust?.
No, there is no such warning, either in the compiler or in Clippy. You could submit an issue to Clippy suggesting they add it, of course.
I challenge that this is a common occurrence or even one that is actually a problem. Even if it was, I'd believe such a warning will have many disadvantages:
I use this pattern to scaffold out functions that I'm pretty sure will return an error once I've implemented them.
A method that is part of a trait cannot change the return type.
You might be passing the function as a function pointer or closure argument and the return type cannot be changed.
Changing the return type breaks API backwards compatibility, so you have to wait until a major version bump.
To illustrate the following example I created a litte spock test (but it's about groovy itself, not spock):
void "some spock test"() {
given: String value = null
expect: someMethod(value) == 3
}
int someMethod(String s) {
return 3
}
int someMethod(Map s) {
return 5
}
There are two methods who's signatures only differ by the type of the given parameter. I thought that when I give it a null value that is explicitly typed as a string, the string-method will be called.
But that doesn't happen; the test fails, because the map-method is called! Why?
I guess groovy ignores the type and treats all nulls the same. There seems to be some kind of priority of types: When I use Object instead of Map as the parameter type of the wrong-method, its all the same, but when I for instance use Integer, the test succeeds.
But than again: If groovy really ignores the type of nulls, why can the following fix the original test:
expect: someMethod((String) value) == 3
If you read my answer to the question Tim already mentioned you will see that I talk there about runtime types. The static type plays normally no role in this. I also described there how the distance calculation is used and that for null the distance to Object is used to determine the best fitting method. What I did not mention is that you can force method selection by using a cast. Internally Groovy will use a wrapper for the object, that also transports the type. Then the transported type is used instead. But you surely understand, that this means a one additional object creation per method class, which is very inefficient. Thus it is not the standard. In the future Groovy maybe change to include that static type information, but this requires a change to the MOP as well. And that is difficult
I've often wondered why languages with a null representing "no value" don't differentiate between the passive "I don't know what the value is" and the more assertive "There is no value.".
There have been several cases where I'd have liked to differentiate between the two (especially when working with user-input and databases).
I imagine the following, where we name the two states unknown and null:
var apple;
while (apple is unknown)
{
askForApple();
}
if (apple is null)
{
sulk();
}
else
{
eatApple(apple);
}
Obviously, we can get away without it by manually storing the state somwhere else, but we can do that for nulls too.
So, if we can have one null, why can't we have two?
Isn't is bad enough that we have one null?
In my programming, I recently adopted the practice of differentiating "language null" and "domain null".
The "language null" is the special value that is provided by the programming language to express that a variable has "no value". It is needed as dummy value in data structures, parameter lists, and return values.
The "domain null" is any number of objects that implement the NullObject design pattern. Actually, you have one distinct domain null for each domain context.
It is fairly common for programmers to use the language null as a catch-all domain null, but I have found that it tends to make code more procedural (less object oriented) and the intent harder to discern.
Every time to want a null, ask yourself: is that a language null, or a domain null?
In most programming languages null means "empty" or "undefined". "Unknown" on the other hand is something different. In essence "unknown" describes the state of the object. This state must have come from somewhere in your program.
Have a look at the Null Object pattern. It may help you with what you are trying to achieve.
javascript actually has both null and undefined (http://www.w3schools.com/jsref/jsref_undefined.asp), but many other languages don't.
It would be easy enough to create a static constant indicating unknown, for the rare cases when you'd need such a thing.
var apple = Apple.Unknown;
while (apple == Apple.Unknown) {} // etc
Existence of value:
Python: vars().has_key('variableName')
PHP: isset(variable)
JavaScript: typeof(variable) != 'undefined'
Perl: (variable != undef) or if you wish: (defined variable)
Of course, when variable is undefined, it's not NULL
Why stop at two?
When I took databases in college, we were told that somebody (sorry, don't remember the name of the researcher or paper) had looked at a bunch of db schemas and found that null had something like 17 different meanings: "don't know yet", "can't be known", "doesn't apply", "none", "empty", "action not taken", "field not used", and so on.
In haskell you can define something like this:
data MaybeEither a b = Object a
| Unknown b
| Null
deriving Eq
main = let x = Object 5 in
if x == (Unknown [2]) then putStrLn ":-("
else putStrLn ":-)"
The idea being that Unknown values hold some data of type b that can transform them into known values (how you'd do that depends on the concrete types a and b).
The observant reader will note that I'm just combining Maybe and Either into one data type :)
The Null type is a subtype of all reference types - you can use null instead of a reference to any type of object - which severely weakens the type system. It is considered one of the a historically bad idea by its creator, and only exists as checking whether an address is zero is easy to implement.
As to why we don't have two nulls, is it down to the fact that, historically in C, NULL was a simple #define and not a distinct part of the language at all?
Within PHP Strict you need to do an isset() check for set variables (or else it throws a warning)
if(!isset($apple))
{
askForApple();
}
if(isset($apple) && empty($apple))
{
sulk();
}
else
{
eatApple();
}
In .net langages, you can use nullable types, which address this problem for value types.
The problem remains, however, for reference types. Since there's no such thing as pointers in .net (at least in 'safe' blocks), "object? o" won't compile.
Note null is an acceptable, yet known condition. An unknown state is a different thing IMO. My conversation with Dan in the comments' section of the top post will clarify my position. Thanks Dan!.
What you probably want to query is whether the object was initialized or not.
Actionscript has such a thing (null and undefined). With some restrictions however.
See documentation:
void data type
The void data type contains only one value, undefined. In previous versions of ActionScript, undefined was the default value for instances of the Object class. In ActionScript 3.0, the default value for Object instances is null. If you attempt to assign the value undefined to an instance of the Object class, Flash Player or Adobe AIR will convert the value to null. You can only assign a value of undefined to variables that are untyped. Untyped variables are variables that either lack any type annotation, or use the asterisk (*) symbol for type annotation. You can use void only as a return type annotation.
Some people will argue that we should be rid of null altogether, which seems fairly valid. After all, why stop at two nulls? Why not three or four and so on, each representing a "no value" state?
Imagine this, with refused, null, invalid:
var apple;
while (apple is refused)
{
askForApple();
}
if (apple is null)
{
sulk();
}
else if(apple is invalid)
{
discard();
}
else
{
eatApple(apple);
}
It's been tried: Visual Basic 6 had Nothing, Null, and Empty. And it led to such poor code, it featured at #12 in the legendary Thirteen Ways to Loathe VB article in Dr Dobbs.
Use the Null Object pattern instead, as others have suggested.
The problem is that in a strongly typed language these extra nulls are expected to hold specific information about the type.
Basically your extra null is meta-information of a sort, meta-information that can depend on type.
Some value types have this extra information, for instance many numeric types have a NaN constant.
In a dynamically typed language you have to account for the difference between a reference without a value (null) and a variable where the type could be anything (unknown or undefined)
So, for instance, in statically typed C# a variable of type String can be null, because it is a reference type. A variable of type Int32 cannot, because it is a value type it cannot be null. We always know the type.
In dynamically typed Javascript a variable's type can be left undefined, in which case the distinction between a null reference and an undefined value is needed.
Some people are one step ahead of you already. ;)
boolean getAnswer() throws Mu
Given how long it took Western philosophy to figure out how it was possible to talk about the concept of "nothing"... Yeah, I'm not too surprised the distinction got overlooked for a while.
I think having one NULL is a lower-common denominator to deal with the basic pattern
if thing is not NULL
work with it
else
do something else
In the "do something else" part, there are a wide range of possibilities from "okay, forget it" to trying to get "thing" somewhere else. If you don't simply ignore something that's NULL, you probably need to know why "thing" was NULL. Having multiple types of NULL, would help you answering that question, but the possible answers are numerous as hinted in the other answers here. The missing thing could be simply a bug, it could be an error when trying to get it, it may not be available right now, and so on. To decide which cases apply to your code -- which means you have to handle them -- it domain specific. So it's better to use an application defined mechanism to encode these reasons instead of finding a language feature that tries to deal with all of them.
It's because Null is an artifact of the language you're using, not a programmer convenience. It describes a naturally occurring state of the object in the context in which it is being used.
If you are using .NET 3.0+ and need something else, you might try the Maybe Monad. You could create whatever "Maybe" types you need and, using LINQ syntax, process accordingly.
AppleInformation appleInfo;
while (appleInfo is null)
{
askForAppleInfo();
}
Apple apple = appleInfo.apple;
if (apple is null)
{
sulk();
}
else
{
eatApple(apple);
}
First you check if you have the apple info, later you check if there is an apple or not. You don't need different native language support for that, just use the right classes.
For me null represents lack of value, and I try to use it only to represent that. Of course you can give null as many meanings as you like, just like you can use 0 or -1 to represent errors instead of their numerical values. Giving various meanings to one representation could be ambiguous though, so I wouldn't recommend it.
Your examples can be coded like apple.isRefused() or !apple.isValid() with little work; you should define beforehand what is an invalid apple anyway, so I don't see the gain of having more keywords.
You can always create an object and assign it to same static field to get a 2nd null.
For example, this is used in collections that allow elements to be null. Internally they use a private static final Object UNSET = new Object which is used as unset value and thus allows you to store nulls in the collection. (As I recall, Java's collection framework calls this object TOMBSTONE instead of UNSET. Or was this Smalltalk's collection framework?)
VB6
Nothing => "There is no value."
Null = > "I don't know what the value is" - Same as DBNull.Value in .NET
Two nulls would be the wrongest answer around. If one null is not enough, you need infinity nulls.
Null Could mean:
'Uninitialized'
'User didn't specify'
'Not Applicable here, The color of a car before it has been painted'
'Unity: This domain has zero bits of information.'
'Empty: this correctly holds no data in this case, for example the last time the tires were rotated on a new car'
'Multiple, Cascading nulls: for instance, the extension of a quantity price when no quantity may be specified times a quantity which wasn't specified by the user anyway'
And your particular domain may need many other kinds of 'out of band' values. Really, these values are in the domain, and need to have a well defined meaning in each case. (ergo, infinity really is zero)