Explicit Serialization API and Security

Peter Firmstone peter.firmstone at zeus.net.au
Mon Jan 5 12:01:51 UTC 2015


My mistake, thank you.

Peter.

On 5/01/2015 9:57 PM, David Holmes wrote:
> Hi Peter,
>
> Did you send this to the list? I haven't seen it turn up yet.
>
> David
>
> On 5/01/2015 6:51 PM, Peter Firmstone wrote:
>> Thanks Dave,
>>
>> That's another way of checking invariants, you could expose A's check
>> method but you'd also need a couple of additional static methods to
>> obtain integers upper and lower from ReadSerial, so that B can ensure
>> its invariant.
>>
>> ReadSerial is caller sensitive so B can't obtain A's stream values via
>> ReadSerial and must do so via A's API.  This prevents the publication of
>> A's implementation, you don't wan't B depending on A's serial form.
>> Instead A can reorder and rename it's fields and change their values,
>> have multiple serial forms and be able to remain compatible with all
>> forms relatively easily.
>>
>> There are some benefits to using a temporary object instance of A; it
>> reduces the amount of code required, eg it would be a beneficial for RMI
>> to minimise code downloads, the JVM is free to inline access to these
>> fields and the temporary instance of A never leaves the cpu cache, so
>> it's not likely to become a performance issue.  Well it might on real
>> time java :)
>>
>> If circular relationships are mutable, or effectively mutable after
>> publication, then we could eventually deprecate the requirement to
>> support special treatment of final fields for Serializable.
>>
>> Cheers,
>>
>> Peter.
>>
>> On 5/01/2015 10:38 AM, David Holmes wrote:
>>>
>>>>>       - I don't see how this invariant-checking mechanism can enforce
>>>>> invariants between superclass fields and subclass fields.   For
>>>>> example:
>>>>>
>>>>> class A {
>>>>>             int lower, upper;   // invariant: lower <= upper
>>>>> }
>>>>>
>>>>> class B extends A {
>>>>>             int cur;   // invariant: lower <= cur <= upper
>>>>> }
>>>>>
>>>>
>>>> The serialization framework should only construct an objects fields
>>>> and make these available from ReadSerial, each class then calls a
>>>> static method before calling a superclass constructor that's
>>>> responsible for an objects creation, to prevent construction of the
>>>> object, if necessary.
>>>>
>>>> Eg, some complexity, but bullet proof:
>>>>
>>>> public class A (
>>>>
>>>>      public final int lower, upper;
>>>>
>>>>       private static boolean check(ReadSerial rs){
>>>>          if (rs.getInt("lower") > rs.getInt("upper"))
>>>>               throw new IllegalArgumentException(
>>>>                  "lower bound must be less than or equal to upper");
>>>>         return true;
>>>>      }
>>>>
>>>>      public A(ReadSerial rs){
>>>>          this(check(rs), rs);
>>>>      }
>>>>
>>>>      private A(boolean checked, ReadSerial rs){
>>>>          super();
>>>>          lower = rs.getInt("lower");
>>>>          upper = rs.getInt("upper");
>>>>      }
>>>>
>>>> // other constructors omitted must also check invarients
>>>> }
>>>>
>>>> class B extends A {
>>>>
>>>>      public final int cur;
>>>>
>>>>      private static ReadSerial check(ReadSerial rs) {
>>>>          A a = new A(rs);
>>>
>>>
>>> It doesn't seem practical in general to have to create an instance of
>>> your supertype to validate the passed in serialized form. Why not
>>> expose the check method?
>>>
>>> David
>>> -----
>>>
>>>>          int cur = rs.getInt("cur");
>>>>          if ( a.lower > cur || cur > a.upper )
>>>>               throw new IllegalArgumentException(
>>>>                   "cur outside lower and upper bounds");
>>>>          return rs;
>>>>      }
>>>>
>>>>      public B(ReadSerial rs) {
>>>>          super(check(rs));
>>>>          cur = rs.getInt("cur");
>>>>      }
>>>> }
>>>>
>>>>
>>




More information about the core-libs-dev mailing list