From: James Kanze on
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
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

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
"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
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! ]