!standard 13.7.1(7) 09-06-01 AC95-00174/01 !class Amendment 09-06-01 !status received no action 09-06-01 !status received 09-03-05 !subject Improper use of null access !summary !appendix !topic Improper use of null access !reference RM 13.7.1 !from Adam Beneschan 09-03-05 !discussion In a comp.lang.ada thread regarding null pointers, I noted that while dereferencing a null pointer in C was more likely to crash the program immediately than resulting in behavior that could make a program vulnerable to a virus, pointer arithmetic was more of a problem because adding some value to "null" may result in a value that can be dereferenced without being caught by the processor. I noticed that Ada provides a way to cause the same problem without using Unchecked_Conversion: convert a null access value to System.Address using System.Address_To_Access_Conversions (which results in System.Null_Address), add something to it with a System.Storage_Elements function, and convert it back to an access value using System.Address_To_Access_Conversions. We can't do much about Unchecked_Conversion abuses, but may I suggest that we could plug this hole by making it a requirement, or at least Implementation Advice, that the "+" and "-" functions in System.Storage_Elements raise Constraint_Error if one of the arguments is System.Null_Address? **************************************************************** From: Randy Brukardt Date: Thursday, March 5, 2009 1:22 PM That doesn't sound like a good idea to me. First of all, it is harmless to subtract Null_Address from another address. Second, it would mean that special code would be needed for these operators (Janus/Ada just maps them directly to the built-in integer operations), that would be a lot of work for something that is rarely used. Thirdly, it would provide a false sense of security -- these operators are very much like Unchecked_Conversion and using them is never going to be safe, nor is Address_to_Access_Conversions. **************************************************************** From: Micronian Date: Thursday, March 5, 2009 3:10 PM This sounds like a bad idea because it would add extra overhead for each use of address arithmetic. There have been past cases mentioned on comp.lang.ada where the author made the decision to use address arithmetic in order to gain noticeable improvement in performance. Now, I understand one might argue that more time critical code should be written in assembly, but it is very nice when you can use pure Ada with a good degree of confidence that it will perform well _and_ is portable. **************************************************************** From: Adam Beneschan Date: Thursday, March 5, 2009 3:49 PM I'm not sure this is all that good an argument---if a user wanted that kind of performance improvement, wouldn't they also be suppressing null checks? Randy has already given some different reasons why he thinks this is a bad idea, so chances are it won't be considered further. But if it is, then I'd presume that the check for Null_Address would be one that is suppressed if Suppress(Access_Check) is in effect. And I can't imagine that someone would want access values to be checked for null, and at the same time be upset about the performance hit caused by checking for Null_Address. That seems contradictory. **************************************************************** From: Micronian Date: Thursday, March 5, 2009 5:01 PM Good point. I did not think about the possibility of using pragma Suppress to remove the null address check. To be honest, I have never used that pragma (but that will change :) ). In addition, I don't normally see it used in other code, so I wonder how wide its use is. **************************************************************** From: Adam Beneschan Date: Thursday, March 5, 2009 5:37 PM Even if you don't see the Suppress pragma in other code, that doesn't mean it isn't used, in effect; I think most or all Ada compilers have a command-line switch that has the same effect as Suppress (or Suppress(All_Checks)). **************************************************************** From: Adam Beneschan Date: Thursday, March 5, 2009 4:12 PM > That doesn't sound like a good idea to me. First of all, it is > harmless to subtract Null_Address from another address. I don't think that's true. Although it doesn't directly produce a harmless access result that could become an invalid memory access, the value of a Storage_Offset is supposed to be the distance in storage units between two objects (presumably two objects that reside in some larger thing that takes up a contiguous area of memory); as such, it's a value that can sensibly be added to another System.Address. Suppose, for instance, the programmer subtracts the addresses of two objects which he thinks are in the same larger buffer B1, and then uses that difference to add to the address of some object in a different buffer B2. It seems like a reasonable thing to try to do. If one of the addresses in the first subtraction is Null_Address, the result of the subtraction will be garbage, and the later addition will result in a System.Address that, if converted to an access value, could end up being a bad memory reference. > Second, it would mean that > special code would be needed for these operators (Janus/Ada just maps > them directly to the built-in integer operations), that would be a lot > of work for something that is rarely used. I won't argue against that point. > Thirdly, it would provide a false sense of security -- these operators > are very much like Unchecked_Conversion and using them is never going > to be safe, nor is Address_to_Access_Conversions. No, using that package isn't going to be safe, but I still don't see why that means we can't at least try to prevent some disasters. If you think that the existence of *some* checks is going to lull programmers into thinking they can do anything they want without worrying, OK, but I don't see it. **************************************************************** From: Bob Duff Date: Thursday, March 5, 2009 6:33 PM > > Constraint_Error if one of the arguments is System.Null_Address? > > That doesn't sound like a good idea to me. I think we should restrict changes in the next version of Ada to things that are really important. So I don't really care whether Adam's idea is a good one or not -- it's not important, so we shouldn't do it. Besides, it's not upward compatible. I suspect the wording in chap 13 is vague enough that implementations are already allowed to do what Adam wants. ****************************************************************