I have made an executable binary built through android ndk. I put the binary in /data/local/tmp.
In the binary I try to bind a socket which I later on want to listen through my android app. I have got root permissions still the bind shows 30 as error which means read only file system. Can anyone tell me what else do I need to do bind a socket?
My code in brief:
int serv_sock = -1, len;
struct sockaddr_un serv_soc_addr;
if ((serv_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
printf( "socket error:%d\n", errno);
return -1; // Terminatie DR
}
bzero(&serv_soc_addr, sizeof(serv_soc_addr));
serv_soc_addr.sun_family = AF_UNIX;
strcpy(serv_soc_addr.sun_path, "iptable_socket");
unlink(serv_soc_addr.sun_path);
len = strlen(serv_soc_addr.sun_path) + sizeof(serv_soc_addr.sun_family);
if (0 != bind(serv_sock, (struct sockaddr*) &serv_soc_addr, len)) {
printf( "bind error:%d\n", errno);
close(serv_sock);
return -1; //Terminate DR
}
root#android:/ # /data/local/tmp/hello-jni
bind error:30
I was able to solve this one myself. Probably someone else looking for this might find helpful.
I changed the type of socket from Abstract type to FileSystem type.
I put the unlink statement at the end of the function after the accept system call breaks rather than just after strcpy as above.
Lastly I ran chmod on my binary.
Any other pointers would be helpful. Thanks.
Related
I need to send few strings on localhost via socket on android using native code (in C particularity) but I've faced weird problem - recv() function always returns -1 and eerno tells "Try again!"
Here is code responsible for initialization of socket and receiving response
void request() {
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
//need to send string to localhost
inet_aton("127.0.0.1", &(sa.sin_addr));
int sock;
char res[7];
sock = socket(AF_INET, SOCK_STREAM, 0);
sa.sin_port = htons(27042);
int connection = connect(sock, (struct sockaddr *) &sa, sizeof sa);
if (connection != -1) { //connection >= 0
memset(res, 0, 7);
send(sock, "\x00", 1, NULL);
send(sock, "AUTH\r\n", 6, NULL);
usleep(100); // Give it some time to answer
int rec = recv(sock, res, 7, MSG_DONTWAIT);
// rec is always -1 and errno says "Try again!"
}
close(sock);
}
There is an INTERNET permission in Manifest file.
I've tried to put recv(sock, res, 7, MSG_DONTWAIT) part in while loop to wait maybe it would return some data but no success. Maybe I need to call something like flush() after send()?
Does any one know where could be trouble?
UPD. This code runs in one android app (client) and tries to send string to other android app that runs on the same device (server).
Solution became pretty obvious - current "server" version can't process "AUTH" message that is why "client" app receive -1 response. I've tried older version and everything worked fine.
I am developing an app in C for Android. I want to add a new tun interface and use the file descriptor to access the device. The way I am doing it is the same as described here: https://backreference.org/2010/03/26/tuntap-interface-tutorial/
However, I am getting Operation not permitted on ioctl() call. My device is rooted, I granted superuser rights to my app, set SELinux policy to permissive. But still, Android does not allow me to access /dev/net/tun. I created it by creating symbolic link from /dev/tun. I also didn't forget to set chmod 666 on /dev/tun. Calling open("/dev/net/tun", O_RDWR | O_NONBLOCK) returns a valid file descriptor, and I set the ifreq struct correctly. It is exactly ioctl() call that returns an error that is Operation not permitted.
Furthermore, if I separate the code and cross-compile it, and then push it to device via adb and run it - everything works. But if I do it as a part of my application, the Operation is not permitted.
Any advise on how to allow this system call inside application? Any tips on why it fails would be also appreciated.
Code:
int create_virtual_nic(char *device) {
struct ifreq ifr;
int fd_tunnel = -1;
int err = -1;
fd_tunnel = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
if(fd_tunnel < 0) {
fprintf(stderr, "Could not open TUN device!\n");
return fd_tunnel;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if (*device) {
strncpy(ifr.ifr_name, device, IFNAMSIZ);
}
// ERROR IS HERE
err = ioctl(fd_tunnel, TUNSETIFF, (void*) &ifr);
if(err < 0 ) {
close(fd_tunnel);
perror("ioctl()");
fprintf(stderr, "Device '%s' taken or not running as root!\n", device);
exit(EXIT_FAILURE);
} else {
fprintf(stdout, "Succesfullt ioctl() on %d\n", err);
}
fprintf(stdout, "Created interface '%s'...\n", device);
return fd_tunnel;
}
OS: Android L
Server: an native level system server, service through abstract socket.
Client: jni in normal 3rd APK
Get a 'permission denied' while using APK to connect the socket.
I thought abstract socket has no permissions!
And, the same code works when running in a adb shell, rooted shell.
The question is: where is the permisson set?
the code:
char *target_socket_name = "#mobilelogd";
int sock_id = 0;
struct sockaddr_un sun;
int address_len;
sock_id = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_id < 0) {
LOG("in %s: Unable to create socket: %s\n", __func__, strerror(errno));
return -1;
} else {
LOG("socket created!\n");
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strncpy(sun.sun_path, target_socket_name, strlen(target_socket_name));
sun.sun_path[0] = 0;
address_len = offsetof(struct sockaddr_un, sun_path) + strlen(target_socket_name);
if (connect(sock_id, (struct sockaddr *)&sun, address_len) == -1)
{
LOG("in %s: Connect to socket failed: (%d),%s\n", __func__, errno, strerror(errno));
close(sock_id);
return -1;
}
--- EDIT 1 ---: add some initialise code,and change '0' to 0. Same result.
Okay, here is the scoop it changed on L by a bug introduced..the bug fix is the pipeline:
https://android.googlesource.com/device/moto/shamu/+/b2db40f
Until than do java pipes or native pipes instead
Since Android manipulated the Linux kernel and added Paranoid networking to it, So you should add the following permission to your manifest file.
<uses-permission android:name="android.permission.INTERNET" />
Android adds a "paranoid network" option to the Linux kernel, which restricts access to some networking features depending on the group of the calling process.
So, your app's uid (user id; each app is assigned an unique uid once it is installed) must be granted that permission in order to do networking tasks.
I don't know if this is in the way I'm handling Android, or a problem with my native code, or both.
I am setting up a udp socket in C++ (wrappers generated by swig):
udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (udpSocket < 0)
{
pthread_mutex_unlock(&csOpenCloseUdp);
throw IOException("Failed to open socket");
}
char bAllowMultiple = true;
setsockopt(udpSocket, SOL_SOCKET, SO_REUSEADDR, &bAllowMultiple, sizeof(bAllowMultiple));
setsockopt(udpSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&hopLimit, sizeof(hopLimit));
setsockopt(udpSocket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localAddr, sizeof(localAddr));
// Set to non-blocking mode
unsigned long bMode = 1;
ioctl( udpSocket, FIONBIO, &bMode );
// Create the local endpoint
sockaddr_in localEndPoint;
localEndPoint.sin_family = AF_INET;
localEndPoint.sin_addr.s_addr = localAddr.s_addr;
localEndPoint.sin_port = groupEndPoint.sin_port;
// Bind the socket to the port
int r = bind(udpSocket, (sockaddr*)&localEndPoint, sizeof(localEndPoint));
if (r == SOCKET_ERROR)
{
//LeaveCriticalSection(&csOpenCloseUdp);
pthread_mutex_unlock(&csOpenCloseUdp);
close();
throw IOException("Failed to bind port");
}
// Join the multicast group
struct ip_mreq imr;
imr.imr_multiaddr = groupEndPoint.sin_addr;
imr.imr_interface.s_addr = localAddr.s_addr;
setsockopt(udpSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&imr, sizeof(imr));
The socket is not throwing any exceptions, and after this it has some value not INVALID_SOCKET.
When I try to send a packet though,
int r = sendto(udpSocket, (char*)dataToSend, (size_t)length, 0, (sockaddr*)&groupEndPoint, (socklen_t)sizeof(groupEndPoint));
I get errno 101: Network is unreachable.
I'm quite new to socket programming, and I know sockets in Android is a bad way to start, but the fact is I have to get this done and have very little time. Does anyone here know of a likely reason to get Network Unreachable? Has anyone tried playing with UDP on Android and can shed some light?
Is there a requirement to use C++ sockets? If possible, in the interests of time, and pretty much
in the interests of everything, I'd recommend the Java API instead. Here is an example of how to use it: http://android-er.blogspot.com/2011/01/simple-communication-using.html . I like C, but I would recommend against using it here.
SOLVED:
I just had to monkey with the ethernet settings on the device to get it to talk to my laptop. for some reason it didn't like using the dedicated link, so I'm going through the local network router and it's working. now getting different issues, but this one's done
My app is partly written in native app using C/C++. The problem is that whenever C/C++ part crashes for some reason the app dies and then restarts automatically. This causes all kinds of messy problems
Now of course, it should not crash in the native part and I'm trying to weed out all reasons why it would happen. However, if it does happen I'd like to:
Quit gracefully
If it does die, at least not try to restart automatically.
I'm curious as to why this behaviour happens. After some search I tried putting the following line in the main activity element of the AndroidManifest.xml:
android:finishOnTaskLaunch="true"
but the automatic restore still happens.
Anyone knows why this is happening and how to change it?
UPDATE:
I think a more fundamental question is,
Is there something similar to a callback if there is a native crash?
One of the answers suggested 'handling crash signals'. I'd be grateful for any links on how it can be done at an application or module level.
As it stands currently, if there is a crash the app just disappears, there's nothing in logcat, so no debugging is possible.
Try to handle crash signals (SIGSEGV etc.) and send kill to yourself in signal handler. This trick helps me.
Example:
#include <signal.h>
#include <unistd.h>
static void signal_handler(int signal, siginfo_t *info, void *reserved)
{
kill(getpid(),SIGKILL);
}
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
struct sigaction handler;
memset(&handler, 0, sizeof(handler));
handler.sa_sigaction = signal_handler;
handler.sa_flags = SA_SIGINFO;
sigaction(SIGILL, &handler, NULL);
sigaction(SIGABRT, &handler, NULL);
sigaction(SIGBUS, &handler, NULL);
sigaction(SIGFPE, &handler, NULL);
sigaction(SIGSEGV, &handler, NULL);
sigaction(SIGSTKFLT, &handler, NULL);
return(JNI_VERSION_1_6);
}
UPDATE2
if you want to see crashlog in android logcat you should use this signal handler
static void signal_handler(int signal, siginfo_t *info, void *reserved)
{
struct sockaddr_un addr;
size_t namelen;
socklen_t alen;
int s, err;
char name[] = "android:debuggerd";
namelen = strlen(name);
// Test with length +1 for the *initial* '\0'.
if ((namelen + 1) > sizeof(addr.sun_path)) {
errno = EINVAL;
return;
}
/* This is used for abstract socket namespace, we need
* an initial '\0' at the start of the Unix socket path.
*
* Note: The path in this case is *not* supposed to be
* '\0'-terminated. ("man 7 unix" for the gory details.)
*/
memset (&addr, 0, sizeof addr);
addr.sun_family = AF_LOCAL;
addr.sun_path[0] = 0;
memcpy(addr.sun_path + 1, name, namelen);
alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
s = socket(AF_LOCAL, SOCK_STREAM, 0);
if(s < 0) return;
RETRY_ON_EINTR(err,connect(s, (struct sockaddr *) &addr, alen));
if (err < 0) {
close(s);
s = -1;
}
pid_t tid = gettid();
if(s>=0)
{
/* debugger knows our pid from the credentials on the
* local socket but we need to tell it our tid. It
* is paranoid and will verify that we are giving a tid
* that's actually in our process
*/
int ret;
RETRY_ON_EINTR(ret, write(s, &tid, sizeof(unsigned)));
if (ret == sizeof(unsigned)) {
/* if the write failed, there is no point to read on
* the file descriptor. */
RETRY_ON_EINTR(ret, read(s, &tid, 1));
//notify_gdb_of_libraries();
}
close(s);
}
wait(NULL);
kill(getpid(),SIGKILL);
}
I took it from android source (can't insert link because android.git.kernel.org is down), but I am not sure that it will work in future Android releases
By default your application should not be automatically restarting. Generally one would have to register for this kind of thing, e.g. via the AlarmManager/keep alives.
Do you have a service as part of your application?