Hi Steve,
My comments inline.
The "instance of OS" is a good idea however,
I'd probably rename the OS class to OSCall or something like that and name the
instance OS so that less code would change. Methods that are static
final native are highly optimized by some JIT's, so we'd be a bit
slower.
The OSCall-being-the-class and
OS-being-the-instance idea will generate tons of warnings from ECJ for the
static final ints you have in OS (like, "you are using a constant through
nonstatic instance").
In order to get rid of
Control.handle(), we'd instead add a method something like
Widget.getHandleData() (*** insert better name here ***). This would be
a class that was platform specific. On Windows, it could include a field
that was the HWND and on platforms with multiple handles or wierd clipping
(such as the Mac), it would return more internal widget "handle" information.
However, it would make things somewhat slower.
That sounds like a good plan. Within
org.eclipse.swt.widgets.* the handles can be accessed directly so no performance
hit.
In org.eclipse.swt.graphics you have GCData
anyway, so no performance hit there as well. As for org.eclipse.swt.dnd, I
doubt there will be a huge performance hit either.
Some other "unsafe" things:
Drawable.internal_new_GC(GCData
data)/internal_dispose_GC(int handle, GCData data)
I've rewritten these as
Drawable.internal_new_GC(OS os, GCData
data)/internal_dispose_GC(OS os, int handle, GCData data)
.. where the caller is supposed to provide
non-null os object. The "OS os" thing here is a proof that the caller has enough
permissions to call internal stuff: if he can "new" the OS class, then,
presumably, he can call the internal methods outside OS. This technique can be
re-applied to other cases too, like Font.internal_new(OS os, Device device, long
handle) etc.
Although it is technically feasible, the number of code
changes to catch every possible place and the overhead in doing this would be
prohibitive.
I'm not sure whether you are referring here the
"OS os" thing or the resource management.
For the first, I agree that it would break binary
compatibility, but I doubt it will have performance overhead or it will be too
much work.
For example, disposing a font that is in use would
require us to keep a list of every place the font is used (both widgets and
graphics) and set a default system font. However, setting a font in a
widget can cause a redraw, redraws cause paint events and behavior is
changed.
I agree. I've thought a bit for
strategies alternative to selecting the default system font,
like:
- GC throws exception immediately when a font
being selected in it is disposed; BUT this will break code in Eclipse; In my
resource tracker I receive tons of warnings coming from Eclipse for cases where
the font is disposed first and afterwards the GC where the font is
selected is disposed as well.
- GC throws exception when text-related operation
is called. BUT this may become even more complex than the selection of default
font, as you need to know what part of GC can be safely called as it will
not need valid font.
What I cannot agree with, is that having OS
type-safe and no resource tracking at all is a good solution. It may be a good
start, but in the end, code based security is all-or-nothing. It is one
thing to miss code protection here and there, and then fix these as-you-go, and
another when you have a whole concept, like resource selection, which is not
type-safe at all.
There is the further problem of Custom Controls that can
have their own concept of default font.
For all-Java custom controls I don't see the
problem at all. Do you?
For native custom controls, user should do the
resource tracking thing as well.
Doing any of this work would
break binary compatibility, something that SWT has not done since version
1.0.
"Ivan Markov"
<ivan.markov@xxxxxxxxxx> Sent by: platform-swt-dev-bounces@xxxxxxxxxxx
09/19/2005 05:03 AM
Please respond
to "Eclipse Platform SWT component developers
list." |
|
To
| <platform-swt-dev@xxxxxxxxxxx>
|
cc
|
|
Subject
| [platform-swt-dev]
Sandboxed SWT. Is this possible? |
|
Hello everybody, Inspired by some
constructive criticism on a well known Java forum, I'm recently thinking of
how much effort it would be to achieve code based security in SWT. I will use
my SWT/Fox port as a playground. Your thoughts on the
following questions are very welcome: Would it be useful?
Perhaps, yes. SWT is probably the single Java API that currently cannot be
sandboxed due to the exposure of various "crash-friendly" things like OS.java,
Control.handle, etcetera.
Would this be easy to achieve, without
sacrificing the simplicity of the code and without the need for total rework
of the SWT internals? Perhaps, yes. Please, read on. My plan is as
follows: There are several main sources
of crashes in SWT:
1. The native layer (OS.java and friends) is
exposed for everyone to use. This is something I'm able to tolerate as
otherwise probably we need tons of abstractions or something related to C++'s
"friend" construct in order to cross package-level boundaries and still
preserve private visibility. Note that there is already a JSR which is
supposed to bring a similar facility to Java. The main problem with the
exposed native layer is that everyone is able to call a static function in
OS.java with bogus parameters provided, thus crashing the JVM process. If this
is remedied somehow, the exposure of "support" structures like LOGFONT,
LOGPEN, BITMAP etc. should not be a problem: the important thing to grok here
is that user may create and change these as he wills, but as long as he is not
allowed to directly call functions of OS.java, he can't crash the JVM, as
OS.java represents the "code" of the operating system, whiule everything else
is the "data". One way OS.java can be protected is by a) marking all
natives as package protected or private and b) creating non-static public
wrapper functions for all the natives. Note that in some X11 ports this is
already done (module non-static) due to the need to lock the calls going into
into XLIB. What are these non-static wrappers going to buy us? Well,
if the primary interface of OS.java becomes non-static, then the
constructor of OS.java can be protected by doing a permission check
with AccessController and friends and throwing exception if the caller's stack
does not have enough permissions. The usage pattern of OS.java from within
SWT would be like this:
In the base class of every SWT, package needing
native access, i.e. in Widget.java, Resource.java, Printer.java, etc:
<snip> static OS os;
static {
AccessController.doPrivileged(new PrivilegedAction() { public Object
run() { os = new OS(); return null; } });
} </snip>
and then all calls to functions in OS in all
classes should be prefixed not with "OS." but with "os." Note that
protecting only the constructor is a) sufficient and b) give significant
performance advantage, as security checks should not be done on every OS API
call; not to mention that having to do the doPrivileged() thing all the time
is inconvenient, at best.
2. public int Control.handle This is also
dangerous, as user is free to change the handle of the control to bogus value,
at will. This can be remedied by instead providing: public int Control.handle() 3. Resource
tracking. This is nasty. Here's a sample of the problem:
<snip> GC gc = ...;
Font font = ...; gc.setFont(font); font.dispose(); gc.drawString("test"); // <-- Crash on platforms based on Toolkits
like Fox or probably even GTK+, or weird output on Win32 </snip> The problem here is that
after the disposal of the Font instance, there is no valid Font object
selected in the GC. In SWT ports wrapping toolkits where Font is represented
by a C++ object, this means that the C++ GC class will try to access the C++
Font class, which is already free-d, which leads to memory corruption and
possible GPF. The best thing for solving this I've come so far is some
sort of resource tracking utility class. The "selection" of every SWT object
in another SWT object is tracked there. When the selected object is disposed,
the "selector" object is signalled so that it has can switch to using another
font handle, usually the default system one which cannot be freed
anyway. That's it. I
know I've missed a tons of stuff. For one thing I haven't covered how in this
framework a costom "native" control is supposed to receive native callbacks
(WM_* on win32). Regards, Ivan
_______________________________________________ platform-swt-dev
mailing
list platform-swt-dev@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/platform-swt-dev
_______________________________________________ platform-swt-dev
mailing
list platform-swt-dev@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/platform-swt-dev
|