From: Francis Glassborow on
In article <g_2dnfT928QnaRzYnZ2dnUVZ_vmqnZ2d(a)comcast.com>, Al
<two(a)haik.us> writes
>Well, there are two issues, which are distinct:
>
>A) (String) Literals being unique (single instance).
>B) (String) Literals being constant (immutable).


Yes but there is also motivation which you have completely ignored.
Neither C++ nor Java targets only big systems with oodles of resources.
Enabling optimisation of storage of string literals is important in
small (usually embedded) systems. For example

char const* greet_world = "Hello World";
char const* world = "World";

should (and in both C and C++ can) share memory.

Now that motivates making string literals immutable. However there is
another important motivation for making string literals immutable, doing
so allows them to be held in ROM. In many embedded systems, RAM is a
precious resource and putting string literals in ROM is important.

Note that in both C and C++ attempts to modify a string literal is
undefined behaviour. Historical reasons and preservation of legacy code
prevented C++ from forbidding storing the address of a string literal in
a plain char* but nonetheless doing so and then modifying the storage
pointed to is undefined behaviour.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
{ I'm approving this because it's part of an ongoing discussion, but
please don't start a thread about Java security in clc++m. -mod/aps }

Niklas Matthies wrote:
> On 2006-12-15 13:23, James Kanze wrote:
> :
> > In the case of Java, the problem concerning literals may be the
> > most shocking, externally, but the fact that you can modify a
> > String after having passed it to another subsystem is far more
> > serious, since it undermines many of Java's security measures.

> No, it doesn't, because a security-conscious application will
> run under a SecurityManager that will prevent such accesses
> (the setAccessible() call will fail).

You seem to have missed the point. The SecurityManager sees a
valid URL (filename, or whatever). It's only after the
SecurityManager has approved the operation that the value
changes. For better or for worse, the Java security model
depends on the immutability of String; violate that, and the
security model doesn't work.

--
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: Niklas Matthies on
{ please move on to discussing C++ or choose a different venue.
thank you. -mod }

On 2006-12-16 18:06, James Kanze wrote:
> { I'm approving this because it's part of an ongoing discussion, but
> please don't start a thread about Java security in clc++m. -mod/aps }

Right.

> Niklas Matthies wrote:
>> On 2006-12-15 13:23, James Kanze wrote:
>> :
>> > In the case of Java, the problem concerning literals may be the
>> > most shocking, externally, but the fact that you can modify a
>> > String after having passed it to another subsystem is far more
>> > serious, since it undermines many of Java's security measures.
>
>> No, it doesn't, because a security-conscious application will
>> run under a SecurityManager that will prevent such accesses
>> (the setAccessible() call will fail).
>
> You seem to have missed the point. The SecurityManager sees a
> valid URL (filename, or whatever). It's only after the
> SecurityManager has approved the operation that the value
> changes.

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.

So, whether the value of string literals and private data can change
in Java is a matter of configuration. 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.

-- Niklas Matthies

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Niklas Matthies wrote:
> { please move on to discussing C++ or choose a different venue.
> thank you. -mod }

I'll try. I do think that comparing the memory and object
models of different languages is acceptable (provided one of the
languages is C++, of course).

> On 2006-12-16 18:06, James Kanze wrote:
> > { I'm approving this because it's part of an ongoing discussion, but
> > please don't start a thread about Java security in clc++m. -mod/aps }

> Right.

> > Niklas Matthies wrote:
> >> On 2006-12-15 13:23, James Kanze wrote:
> >> :
> >> > In the case of Java, the problem concerning literals may be the
> >> > most shocking, externally, but the fact that you can modify a
> >> > String after having passed it to another subsystem is far more
> >> > serious, since it undermines many of Java's security measures.

> >> No, it doesn't, because a security-conscious application will
> >> run under a SecurityManager that will prevent such accesses
> >> (the setAccessible() call will fail).

> > You seem to have missed the point. The SecurityManager sees a
> > valid URL (filename, or whatever). It's only after the
> > SecurityManager has approved the operation that the value
> > changes.

> 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. 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.

> 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. (In C++,
of course, a random pointer can wreck havoc; a really clever
program could probably manage to find where the memory for the
deep copy was allocated, and modify it. It's considerably more
difficult than in Java, but it's certainly not impossible.)

> 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. (I'm
pretty sure it would also be possible using the Java model---a
debugger integrated into the JVM would not need reflection.)

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orientie objet/
Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, 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: Niklas Matthies on
On 2006-12-19 18:01, James Kanze wrote:
> Niklas Matthies wrote:
>> { please move on to discussing C++ or choose a different venue.
>> thank you. -mod }
>
> I'll try. I do think that comparing the memory and object
> models of different languages is acceptable (provided one of the
> languages is C++, of course).

More C++ content below this time.

:
> You're missing the point entirely.

I don't think so, read below.

> 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.

>> 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.
For private fields, this flag is false by default, so to perform a
read or write access to such a field the flag first needs to be set to
true; otherwise the access will fail with an IllegalAccessException.
Now, the crucial point is that calls to setAccessible() only succeed
if the JVM's SecurityManager authorizes it.

That is, you can't actually modify a String object unless the
SecurityManager allows accesses to the private members of the
java.lang.String class. For example, if you run the Java program I
previously posted in this thread with "java -Djava.security.manager
Test", you'll get a "java.security.AccessControlException: access
denied". Here it's actually already the getDeclaredField() call that
fails, in other words the program isn't even allowed to obtain the
java.lang.reflect.Field object corresponding to the private field.

So there's no way a Java program can mutate a String object when the
JVM is run with an appropriate SecurityManager.

:
>> 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.

In Java, one could actually distinguish between Java-the-language
and the JVM. The JVM allows more than Java-the-language allows.
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.

-- Niklas Matthies

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]