Hi Jean-Frederic and Rémy,

I do not have a real answer, but a workaround. It is possible to get the same result without any printf style functions or atoi, just by doing arithmetics. But: maybe then the crash simply moves to another position.

In src/ssl.c you can use:

static int ssl_rand_choosenum(int l, int h)
{
    double dbl;
    int i;

    dbl = 1.0 * (rand() % RAND_MAX) * (h - l);
    i = (dbl / RAND_MAX + 0.5) + 1;
    if (i < l) i = l;
    if (i > h) i = h;
    return i;
}

This will also be much faster.

I tested the formula against the original one for each value of l and h Note, that currently the function is always called with l==0 and h==127! So you could also drop the h and l params and use fixed values, but of course would loose future flexibility.

between 0 and 499 (and h>=l) and for each seed between 0 and 499 on twi different architectures (Linux 64 Bit on x64 and Solaris Sparc 32 Bit). You can run the following test program to convince yourself about the formula correctness on your platform:

#include <stdlib.h>
#include <stdio.h>

#define MAX_SEED 500
#define MAX_BOUNDARY 500
#define FEEDBACK 100000

int main ()
{
    int seed;
    int l;
    int h;
    int i1;
    int i2;
    int rand_orig;
    int rand_reduced;
    double rand_normalized;
    double rand_prod;
    char buf[50];
    long count = 0;

    fprintf(stdout, "RAND_MAX is %d\n", RAND_MAX);
fprintf(stdout, "Number of tests to run: %ld\n", 1L*MAX_BOUNDARY*MAX_BOUNDARY/2*MAX_SEED);
    fprintf(stdout, "Feedback dot every %d tests\n", FEEDBACK);
fprintf(stdout, "Expect %d feedback dots\n", 1L*MAX_BOUNDARY*MAX_BOUNDARY/2*MAX_SEED / FEEDBACK);

fprintf(stdout, "l\th\tseed\trand\tred\tnorm\torig\tnew\tprod\tround\n");
    fflush(stdout);

    for (seed = 0; seed < MAX_SEED; seed++) {
        srand(seed);
        for (l = 0; l < MAX_BOUNDARY; l++) {
            for (h = l; h < MAX_BOUNDARY; h++) {
                rand_orig = rand();
                rand_reduced = rand_orig % RAND_MAX;

rand_normalized = ((double)rand_reduced / RAND_MAX) * (h - l);
                /* %.0f does rounding */
                sprintf(buf, "%.0f", rand_normalized);
                i1 = atoi(buf) + 1;
                if (i1 < l) i1 = l;
                if (i1 > h) i1 = h;

                rand_prod = 1.0 * rand_reduced * (h - l);
                i2 = (rand_prod / RAND_MAX + 0.5) + 1;
                if (i2 < l) i2 = l;
                if (i2 > h) i2 = h;

                if (i1 != i2) {
                    fprintf(stdout, "%d\t%d\t%d\t%d\t%d\t%f\t%d\t%d\t%f\n",
l, h, seed, rand_orig, rand_reduced, rand_normalized,
                            i1, i2, rand_prod);
                }
                count++;
                if (count % FEEDBACK == 0) {
                    fprintf(stderr, ".");
                    fflush(stderr);
                }
            }
        }
    }
}

Regards,

Rainer

Am 18.07.2019 um 08:57 schrieb jean-frederic clere:
On 12/07/2019 11:21, Rémy Maucherat wrote:
On Thu, Jul 11, 2019 at 11:01 PM Rainer Jung <rainer.j...@kippdata.de
<mailto:rainer.j...@kippdata.de>> wrote:

     Am 11.07.2019 um 22:10 schrieb Rémy Maucherat:
     > On Thu, Jul 11, 2019 at 8:42 PM Rainer Jung
     <rainer.j...@kippdata.de <mailto:rainer.j...@kippdata.de>
     > <mailto:rainer.j...@kippdata.de <mailto:rainer.j...@kippdata.de>>>
     wrote:
     >
     >     Hi Rémy,
     >
     >     When one looks up the macros in native/include/tcn.h, this boils
     >     down to
     >     the following returning null:
     >
     >     (*env)->FindClass(env, "org/apache/tomcat/jni/FileInfo")
     >
     >     So our own FileInfo class can not be found. FindClass docs
     indicate its
     >     searched in the CLASSPATH although I'm not sure whether its
     really the
     >     classpath or some search paths of a class loader hierarchy.
     >
     >     You might want to add the JVM commandline flag
     "-verbose:class" for any
     >     easy way to track class loading.
     >
     >     I didn't really grok what you meant with "define in JNI
     configuration".
     >     For normal JVMs the code just works, so what might be special
     for Graal
     >     that org.apache.tomcat.jni.FileInfo can't be found?
     >
     >
     > A Graal native image is indeed not a normal JVM and does not
     support any
     > kind of dynamic class loading, it has to be declared first in these
     > configuration files.

     Ah OK.

     > So I am adding this to the jni one:
     > { "name":"org.apache.tomcat.jni.FileInfo" },
     > { "name":"org.apache.tomcat.jni.Sockaddr" },
     > { "name":"org.apache.tomcat.jni.FileInfo" },

     Again FileInfo? I think instead "org.apache.tomcat.jni.Error" should be
     the third one.

     > { "name":"java.lang.String", "methods" :
     >
     
[{"name":"<init>","parameterTypes":["byte[]"]},{"name":"getBytes","parameterTypes":[]}]

     > }
     > And loading now works.
     > Jul 11, 2019 9:39:28 PM org.apache.catalina.core.AprLifecycleListener
     > lifecycleEvent
     > INFO: Loaded APR based Apache Tomcat Native library [1.2.23] using
     APR
     > version [1.6.5].
     > Jul 11, 2019 9:39:28 PM org.apache.catalina.core.AprLifecycleListener
     > lifecycleEvent
     > INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters
     > [false], random [true].
     > Jul 11, 2019 9:39:28 PM org.apache.catalina.core.AprLifecycleListener
     > lifecycleEvent
     > INFO: APR/OpenSSL configuration: useAprConnector [false],
     useOpenSSL [true]
     > Jul 11, 2019 9:39:28 PM org.apache.catalina.core.AprLifecycleListener
     > initializeSSL
     > INFO: OpenSSL successfully initialized [OpenSSL 1.1.1c FIPS  28
     May 2019]
     >
     > However when trying to actually connect I got:
     > Segmentation fault (core dumped)
     >
     > Oops.

     If the above duplicate class was just a copy and paste typo, but you
     had
     it right in your actual work, the next one could try, would be
     activating writing core dumps in the underlying OS. The resulting core
     should be inspectable depending on OS via gdb or similar tools. The
     simplest gdb invocation would be

     gdb /path/to/my/bin/java /path/to/my/corefile

     and then at the gdb prompt the command

        bt

     or

        bt full

     or

        thread apply all bt

     or

        thread apply all bt full

     That way we should at least see, in which function the crash happens.
     Depending on symbols etc. you might even get line numbers.


In the native code, it crashes on:
https://github.com/apache/tomcat-native/blob/master/native/src/ssl.c#L635

I modified the code to:
     double d = (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l));
     apr_snprintf(buf, sizeof(buf), "%.0f", d);

And it cores on the apr_snprintf. I don't see how it is unsafe though.

Rémy


I also have the same core using the AprConnector I can't really see what
is wrong there.

gdb doesn't really help :-( I have replaced the apr_snprintf by snprintf
and I also have a core:
+++
Thread 19 "apr-8443-exec-1" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffaffff700 (LWP 24724)]
0x00007ffff792e41a in __GI___printf_fp_l (fp=<optimized out>,
loc=<optimized out>, info=<optimized out>, args=<optimized out>) at
../include/ctype.h:53
53        return __libc_tsd_address (const int32_t *, CTYPE_TOLOWER);
Missing separate debuginfos, use: dnf debuginfo-install
sssd-client-2.2.0-3.fc30.x86_64 zlib-1.2.11-15.fc30.x86_64
(gdb) bt
#0  0x00007ffff792e41a in __GI___printf_fp_l (fp=<optimized out>,
loc=<optimized out>, info=<optimized out>, args=<optimized out>) at
../include/ctype.h:53
#1  0x00007ffff7946f71 in __vfprintf_internal (s=0x7fffafffe660,
format=0x7ffff7ff05f7 "%.0f", ap=0x7fffafffe7e0, mode_flags=<optimized
out>) at vfprintf-internal.c:1644
#2  0x00007ffff7959f8a in __vsnprintf_internal (string=0x7ffff7ffa2a0
<buf> "", maxlen=<optimized out>, format=0x7ffff7ff05f7 "%.0f",
args=0x7fffafffe7e0, mode_flags=0) at vsnprintf.c:114
#3  0x00007ffff7933386 in __GI___snprintf (s=<optimized out>,
maxlen=<optimized out>, format=<optimized out>) at snprintf.c:31
#4  0x00007ffff7fe6ea4 in ssl_rand_choosenum (l=0, h=127) at src/ssl.c:720
+++
Suggestions?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to