Passing Java Socket FD to C Hack

A

Amir Michail

Hi,

I tried this hack for passing a Java socket fd to C but could not get
it to work:

http://www.geocities.com/SiliconValley/Vista/2013/JavaOOB.html

Here's the code I have:

JNIEXPORT void JNICALL
Java_UnixProcess_closeSockets__Ljava_net_Socket_2
(JNIEnv *env, jclass cls, jobject obj) {

struct Hjava_io_FileDescriptor *fd; /* Java-struct-excavation aids */
struct Hjava_net_SocketImpl *impl;
struct Hjava_net_Socket *socket;
int sockfd;

/* dig deep into "this" to get the UNIX file descriptor */
//socket = unhand(this)->socket;

socket = obj;
impl = unhand(socket)->impl;
fd = unhand(impl)->fd;
sockfd = (int)(unhand(fd)->fd - 1);
/* "The FileDescriptor object integer class variable fd represents
the actual file descriptor plus 1." - Mark Yarvis */

closeSockets(sockfd);

}

I get this error:

UnixProcessImp.c: In function
`Java_UnixProcess_closeSockets__Ljava_net_Socket_2':
UnixProcessImp.c:97: error: invalid type argument of `->'
UnixProcessImp.c:98: error: invalid type argument of `->'
UnixProcessImp.c:99: error: invalid type argument of `->'

which corrrespond to these lines:

impl = unhand(socket)->impl;
fd = unhand(impl)->fd;
sockfd = (int)(unhand(fd)->fd - 1);



Here are the header files generated by javah:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class java_net_Socket */

#ifndef _Included_java_net_Socket
#define _Included_java_net_Socket
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: factory */
#ifdef __cplusplus
}
#endif
#endif


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class java_net_SocketImpl */

#ifndef _Included_java_net_SocketImpl
#define _Included_java_net_SocketImpl
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class java_io_FileDescriptor */

#ifndef _Included_java_io_FileDescriptor
#define _Included_java_io_FileDescriptor
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: in */
/* Inaccessible static: out */
/* Inaccessible static: err */
/*
* Class: java_io_FileDescriptor
* Method: sync
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_io_FileDescriptor_sync
(JNIEnv *, jobject);

/*
* Class: java_io_FileDescriptor
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_io_FileDescriptor_initIDs
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif



Amir
 
G

Gordon Beaton

I tried this hack for passing a Java socket fd to C but could not
get it to work:

http://www.geocities.com/SiliconValley/Vista/2013/JavaOOB.html
[...]

I get this error:

UnixProcessImp.c: In function
`Java_UnixProcess_closeSockets__Ljava_net_Socket_2':
UnixProcessImp.c:97: error: invalid type argument of `->'
UnixProcessImp.c:98: error: invalid type argument of `->'
UnixProcessImp.c:99: error: invalid type argument of `->'

I believe that unhand() comes from JNI 1.0 and is now obsolete. At any
rate I've never encountered it in the 6 or so years since I wrote my
first native method.

I've previously used this mechanism to do what you're trying:

static int getFd(JNIEnv *env, jobject sock)
{
JNIEnv e = *env;
jclass clazz;
jfieldID fid;
jobject impl;
jobject fdesc;

/* get the SocketImpl from the Socket */
if (!(clazz = e->GetObjectClass(env,sock)) ||
!(fid = e->GetFieldID(env,clazz,"impl","Ljava/net/SocketImpl;")) ||
!(impl = e->GetObjectField(env,sock,fid))) return -1;

/* get the FileDescriptor from the SocketImpl */
if (!(clazz = e->GetObjectClass(env,impl)) ||
!(fid = e->GetFieldID(env,clazz,"fd","Ljava/io/FileDescriptor;")) ||
!(fdesc = e->GetObjectField(env,impl,fid))) return -1;

/* get the fd from the FileDescriptor */
if (!(clazz = e->GetObjectClass(env,fdesc)) ||
!(fid = e->GetFieldID(env,clazz,"fd","I"))) return -1;

/* return the descriptor */
return e->GetIntField(env,fdesc,fid);
}

Note that since the code traverses private class members, there is no
guarantee that it will work correctly in all versions of the class
libraries or with libraries from other vendors than Sun. I haven't
used this code in several years, so you may wish to use "javap -s" to
confirm the class structure assumed by the code.

With *some* (but not all) JVMs, you will need to subtract 1 from the
returned value to get the true descriptor. I believe that was only
true of early JVM's (prior to 1.2 or so), but YMMV.

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,052
Members
48,769
Latest member
Clifft

Latest Threads

Top