From: James Kanze on 20 Dec 2006 12:07 Niklas Matthies wrote: > On 2006-12-19 18:01, James Kanze wrote: > > Niklas Matthies wrote: [...] > > And it's not relevant to > > just security. In C++, a string literal has the value that > > appears in the code. Period. With many compilers, it's in > > write protected memory, so it is physically impossible to change > > it. IMHO, this is essential not only for security reasons, but > > in order to be able to understand the code. In C++, if I need a > > string whose value cannot change after I receive it, I can use > > pass by value; from that point on, I operate on a copy of the > > original string, and the providing code cannot even see the > > string I'm using. This is essential to security, and can also > > have an effect on readability. Java's doesn't have pass by > > value, and counts on immutability to achieve the same effect. > Agreed. This is, IMHO, the important issue. > >> So, whether the value of string literals and private data can change > >> in Java is a matter of configuration. > > You can't configure Java so that it is single threaded, nor that > > it use deep copy. Which means that there is no way to prevent > > the modification of the String data using the method shown, in > > another thread, after the SecurityManager has authorized the > > operation, but before the operation has taken place. > What kind of "operation" are you talking about? > The operation *I* am talking about is setting the "accessible" flag > of the respective private field (private data member) of the String > class, so that instances of it can be modified through reflection. OK. It's already been established that my Java knowledge isn't completely up-to-date:-). I was unaware of this flag, and since it is apparently set by default (since I could modify private fields), at least with Sun's standard JDK, I'd never encountered it. > For private fields, this flag is false by default, Only if you use some specific SecurityManager. The default SecurityManager manager in Sun's JDK allows modifying private fields without complaining. (Of course, if security is an issue, you're not doing anything automatically by default, without finding out first what the default means, and what you're options are.) [...] > >> If you want it secure, you > >> configure it one way; if you want to enable access by a debugger, > >> you configure it a different way. The language supports both. > > Using the C++ model, you can have both at the same time. > In Java you can also have both at the same time by only allowing > access for the classes of the debugging implementation. Another > example (and motivation) is allowing access for a generic > serialization implementation. > As for C++, there's two possible views: Either the debugger is > considered part of the C++ program, then yes you can have both, but > only with the debugger invoking UB. Or the debugger is not considered > part of of the C++ program (the usual view), but of the implementation, > then when using it to mutate non-volatile private (or const) data in a > way detectable by the program, the implementation obviously stops to > be conforming. Certainly. A 100% conforming implementation of c++, with no extensions, isn't very useful anyway. No GUI, no sockets, no threads, no processes... In general, connecting a debugger to a process changes a lot, and a C++ program under a debugger, and interacting with the debugger, isn't a conforming implementation according to the standard. In addition to changing various variables in ways which the standard really doesn't condone, you can terminate the program when it shouldn't terminate, and doubtlessly break what the standard guarantees in a number of other ways (like setting a breakpoint, to begin with). > In Java, one could actually distinguish between Java-the-language > and the JVM. The JVM allows more than Java-the-language allows. Certainly. Since it is written in C or C++, it allows anything that C or C++ does:-). Seriously, I've never used a debugger with Java---I rarely use one with C++ either. But I would expect that it would be simple a different VM, which allowed user intervention. In many ways, this corresponds to the model used for C++ debuggers, at least under Unix. The Unix system interface used for debugging allows one process to modify memory, etc. of another process, and to catch its signals. It certainly breaks the memory model defined in the standard. > Strings are really immutable in Java-the-language. But there's an API > that provides (restricted) access to certain features of the JVM which > allows you to perform operations you wouldn't otherwise be able to > perform from within Java-the-language. > There's a certain similarity with how UB in C++ allows the possibility > of doing things that aren't possible in C++ proper. Only that for Java > the JVM defines the one-and-only behavior. Of course! Obviously, Java allows undefined behavior. Just declare the function "native", and you can put all the undefined behavior you want into it:-). (With regards to "one-and-only" behavior: there are definitly cases where the behavior is not specified---where several different behaviors are allowed. Threads are an obvious example, but I think floating point has been relaxed as well, so that you can get different results on two different conforming implementations.) -- James Kanze (GABI Software) email:james.kanze(a)gmail.com Conseils en informatique orient�e objet/ Beratung in objektorientierter Datenverarbeitung 9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Raoul Gough on 21 Dec 2006 09:42 AJ wrote: > Hi there, > > Seungbeom Kim wrote: > <snip> > > But considering only the core language features would be a serious > > mistake; it would be an unfair disadvantage to a language which has > > preferred library solutions to core language solutions. For example, > > under that criterion, you would say "C99 can handle variable-length > > arrays but C++ can't; C99 can handle complex numbers but C++ can't." > > It would also be unfair to consider library support as good as core > language support for (at least) two reasons: > > 1) Syntax. > 2) Convenience. However, library solutions win in terms of flexibility, because you can choose between different libraries without switching languages. > > Here's one example: Multi-threading and thread safety. > > For 1: In D, this is achieved in a super-clean and succinct manner: > Adding a synchronized keyword. > > In C++, one must add error-prone boilerplate for critical sections (or > mutexes, or locks) and in general the syntax is verbose and a hassle. > > For 2: In D, synchronized is built-in. No need to download or install > anything else. No need to check additional documentation on library usage. > > In C++, one must install and add a dependency to boost (non-trivial) or > pthreads (still non-trivial), or sacrifice platform-independence and go > Win32. Threads and mutexes are just one way of doing concurrency - they happen to be popular at the moment, but better ways may be developed. With a library solution the programmer would be able to choose between whatever libraries are available. In keeping with the general purpose nature of the C++, the language designers should attempt to define fundamental requirements without requiring a particular implementation. Obviously a difficult challenge when it comes to concurrent programming. -- Raoul Gough. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Joe on 21 Dec 2006 14:22 Raoul Gough wrote: > > However, library solutions win in terms of flexibility, because you can > choose between different libraries without switching languages. > I think this is true only until a library solution becomes standardized. I know that with Microsoft and probably others, there are parts of the standard library that are in precompiled libraries and dlls. If you wanted to replace a piece, it is likely you would have to replace a lot of pieces. Sometimes you can do that, sometimes not. I have read in other discussion along these lines (for example when Walter mentions having builtin complex types) that the C++ compiler is allowed to treat std library things specially. Specifically, any includes of std headers can just magically fill the symbol tables with new stuff without ever having to read an actual file. The compiler can recognize std::complex<> and generate optimal code for it etc. The combination of these two things mean that you can not portably replace the std library anymore than you can portably redefine a keyword. > > Threads and mutexes are just one way of doing concurrency - they happen > to be popular at the moment, but better ways may be developed. With a > library solution the programmer would be able to choose between > whatever libraries are available. Not if they become standardized. If they become standardized, they will be drug around forever because no one will want to break existing code. Again this is very much the same as if they added support for the core. I don't really know D, but it does allow libraries as well, so if something new came about, poof new library and some folks would stop using the builtins, others would probably continue using them. The only real benefit of libraries is the development of new features. You can try things out until you like the results. Once you standardize them though, they become just as burdensome as core keywords. joe -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Raoul Gough on 24 Dec 2006 14:19 "Joe" <jgreer(a)nsisoftware.com> writes: > Raoul Gough wrote: >> >> However, library solutions win in terms of flexibility, because you can >> choose between different libraries without switching languages. > > I think this is true only until a library solution becomes > standardized. [snip] Well you can still choose to use an entirely different library. It might provide a compatible interface (e.g. STLport) or it might not. I guess the problem I was thinking of with built-in constructs is where they are necessitated by underlying weaknesses in the language. Built-in I/O in BASIC springs to mind as a particularly bad example of this. It would also be hard to implement something like boost::scoped_lock in Java because of the language semantics (instead we have the synchronized keyword and try/finally blocks). >> >> Threads and mutexes are just one way of doing concurrency - they happen >> to be popular at the moment, but better ways may be developed. With a >> library solution the programmer would be able to choose between >> whatever libraries are available. > > Not if they become standardized. If they become standardized, they > will be drug around forever because no one will want to break existing > code. Again this is very much the same as if they added support for > the core. I don't really know D, but it does allow libraries as well, > so if something new came about, poof new library and some folks would > stop using the builtins, others would probably continue using them. > > The only real benefit of libraries is the development of new features. > You can try things out until you like the results. Once you > standardize them though, they become just as burdensome as core > keywords. Another benefit of library-based solutions is that (in C++ anyway) the libraries are modular and optional - you don't have to #include <string> if you don't want to, and it doesn't pollute your namespace in the same way that keywords do. I guess when you invent a new language you get to define all the keywords you want, but you only have that luxury at the start. After that any new keywords will probably break somebody's code. -- Raoul Gough. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Greg Herlihy on 27 Dec 2006 04:51
James Kanze wrote: > Niklas Matthies wrote: > > I'm not sure who's missing the point here. The value won't be able to > > change unless the SecurityManager allows the application to change the > > value. The SecurityManager, or, more generally, the security policy is > > global for the JVM, and can be set when starting up the JVM, such that > > the application has no way whatsoever to bypass it. > > You're missing the point entirely. And it's not relevant to > just security. In C++, a string literal has the value that > appears in the code. Period. Unless, of course, the string literal happens to have a different value because the C++ program has changed it. There is, after all, nothing in C++ that guarantees that the value of a string literal is immutable. The Standard states only that attempting to modify a const value is "undefined' - which includes the possibility that such modification is allowed. So a C++ implementation that allows modification of string literal values is just as conforming to the C++ Standard as an implementation that does not allow such changes - so any C++ program that counts on one behavior instead of the other is necessarily relying on non-portable, implementation-dependent behavior to guarantee its secure operation. A C++ program has no choice but to look elsewhere than the C++ Standard for anything related to its secure operation, because "security" as a concept is one entirely absent from the C++ Standard. Greg -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |