Connecting to external unix domain socket from NDK JNI - android-ndk

I'm building a POC Android app that needs to communicate with an ELF binary over a Unix domain socket server that the binary binds to and listens on. The app is meant for rooted phones and executes the binary as a superuser upon launch. I need to connect with the binary from my client residing in native code, which I'm presently failing to do.
I'm using a self-ported, stripped down version of libsocket to implement the domain socket functionality for both the binary and the Android app (through JNI). The binary communicates perfectly with a command line client, however, it fails to connect with the client that I've implemented in JNI code. I've made sure that the binary is running from /data/data/<my_package_name>/files and that the server socket has public access (777).
While researching the above problem, I stumbled across the fact that NDK requires LocalSockets to be in the Linux abstract namespace. My server (arm binary) binds to an absolute path (/data/data/<my_package_name>/files/serversocket) as libsocket does not support the abstract namespace for unix domain sockets (due to the usage of strlen() and strncopy() which do not support strings beginning with \0).
The following is the code for create_socket from libsocket that's failing with a negative fd.
int create_socket(const char* path, int flags) {
if (path == NULL) {
return -1;
}
if (strlen(path) > sizeof(((struct sockaddr_un*) 0)->sun_path) - 1) {
return -1;
}
int fd = socket(AF_LOCAL, SOCK_STREAM | flags, 0);
if (fd < 0) {
return -1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_LOCAL;
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
// the connect call below fails, errno is set to 13 (EACCESS)
if (connect(fd, (struct sockaddr*) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path))) {
close(fd);
return -1;
}
return fd;
}
EDIT :
In the above code, the call to connect() fails, with errno being set to 13 (EACCESS). This seems to be an insufficient privileges problem.
I'm wondering if there's any way for me to connect my client to an absolute path from within NDK. It works just fine when I package the client in an ELF executable that runs as superuser, am I missing something obvious here?

To anyone who might be following this, it is necessary to set appropriate permissions on the socket pseudo file manually every time it is launched as root, else connect() fails with errno being set to EACCESS. I'm yet to find a better solution to this.

Related

When should I call res_init in linux?

Pouring over some old network utility code, I found a res_init() call before a getipnodebyname():
void getAddresses(string hostname, set<string> &addresses) {
int error = 0;
res_init();
struct hostent *host = getipnodebyname(hostname.c_str(), AF_INET, AI_DEFAULT, &error);
insertHostAddresses(host, addresses);
freehostent(host);
}
Never having run into this call before, I looked up the man page:
https://linux.die.net/man/3/res_init
However this has not exactly helped me to understand when this call would be necessary to make.
I understand this is for preloading a cache? A bit of an explanation would help me out.
I should note - the current call getaddrinfo does not seem to require this?
One must call res_init() if one intends to modify any of the internal resolver settings before using any of the other resolver(3) functions (directly or indirectly), e.g. to change the flags set in _res.options.

'ioctl' signature for device mapper

The question may seem naive, but I'm new to kernel/driver programming. I created a device mapper over a block device, which is working fine. It's constructor/destructor and map methods are called.
Now, I'm trying to write an ioctl for this mapper. When ioctl is written for a device, it has the following signature:
int ioctl(int d, /* other args */);
A file structure/descriptor is expected in ioctl. This can be easily used by application process as it has access to file.
But the ioctl for device mapper has the following signature ( in struct target_type):
typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd,
unsigned long arg);
How can user application get access to device mapper with ioctl without having knowledge of struct dm_target ?
-Ioctl which stand for Input Output control is a system call used in linux to implement system calls which are not be available in the
kernel by default.
-The major use of this is in case of handling some specific operations of a device for which the kernel does not have a system call by default. For eg: Ejecting the media from a "CD" drive. An ioctl command is implemented to give the eject system call to the cd drive.
-ioctl(fd, cmd , INPARAM or OUTPARAM);
|
3rd argument is INPARAM or OUTPARAM i.e we don't have to read a device, then how how to interact with device ? use ioctl.
-open ioctl.h and check you will get more information
#define "ioctl name" __IOX("magic number","command number","argument type")
static long char_dev_ioctl( struct file *filp, unsigned int cmd, unsigned long arg)
{
/* verify argument using access_ok() */
/* impliment support of ioctl commands */
}

POSIX compliant way to tell if system rebooted?

I'm writing some highly portable security code. I'm trying to avoid security flaw in a utility program such as this one found in some versions of sudo:
... it is possible to become the super user by running sudo -k and then resetting the system clock to 01-01-1970.
This happens because sudo relies on absolute (aka calendar) time to determine whether or not access has timed out.
My idea is to use CLOCK_MONOTONIC defined in time.h.
From the POSIX standard,
[CLOCK_MONOTONIC is] defined as a clock whose value cannot be set via clock_settime() and which cannot have backward clock jumps. The maximum possible clock jump shall be implementation-defined.
Problem is, on many (most?) systems, CLOCK_MONOTONIC resets on reboot. Is there any guaranteed POSIX-compliant way to determine whether or not the system has rebooted since a program last ran?
One (bad) way is to check whether or not the stored clock value is greater than the current clock value, however this just shifts the problem. On systems where CLOCK_MONOTONIC resets on reboot, there could be a short window of length TIMEOUT where access would be permitted.
What am I missing that would avoid this problem?
It seems to me this is straightforward to do using a POSIX shared memory object:
POSIX shared memory objects have kernel persistence: a shared memory
object will exist until the system is shut down, or until all
processes have unmapped the object and it has been deleted with
shm_unlink
Whenever your program launches it can shm_open a new object with some consistent name and set the owner to root. The object needn't contain any particular value. POSIX requires that all shared memory objects persist until reboot unless manually destroyed (which only its owner or creator can do...which in this case is the root user).
Whenever your program launches it first checks if such a shared memory object already exists having root as the owner. Since only root could create such an object, and only root or a reboot could destroy it, you can thus know for certain whether your program has been launched since the last reboot, save the only possible circumvention being the root user invoking shm_unlink on the object manually.
I wrote a test-and-set function below that should do exactly what you need. And it works except for the ownership setting/detection: for some unknown reason both calls to shmctl are failing on my system, saying "invalid argument". The man page for shmctl says the EINVAL error indicates either an invalid memory object identifier or an invalid command. But the IPC_SET and IPC_STAT commands are certainly valid, and you can watch the program's output to see the valid object identifier that is being created and/or opened each time.
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
int rebooted_test_and_set() {
int err;
int rebooted;
struct shmid_ds shmst;
// create object if nonexistent, returning failure if already exists
int shmid = shm_open("/bootcheck", O_CREAT | O_EXCL);
if (shmid != -1) {
fprintf(stderr, "bootcheck object did not exist, so created: %d\n", shmid);
// object did not exist, so system has been rebooted
rebooted = 1;
// set owner to root, and no permissions for anyone
shmst.shm_perm.uid = 0;
shmst.shm_perm.gid = 0;
shmst.shm_perm.mode = 0;
if ((err = shmctl(shmid, IPC_SET, &shmst)) == -1) {
perror("shmctl: shmctl failed to set owner and permissions for bootcheck object");
exit(1);
}
} else {
// object already exists, so reopen with read access and verify that the owner is root
shmid = shm_open("/bootcheck", O_RDONLY);
if (shmid == -1) {
perror("shm_open: failed, perhaps due to insufficient privileges");
exit(1);
}
fprintf(stderr, "bootcheck object (%d) exists, so checking ownership\n", shmid);
if ((err = shmctl(shmid, IPC_STAT, &shmst)) == -1) {
perror("shmctl: shmctl failed");
exit(1);
}
if (shmst.shm_perm.uid == 0) {
// yes, the bootcheck owner is root,
// so we are confident the system has NOT been rebooted since last launch
rebooted = 0;
} else {
// uh oh, looks like someone created the object illegitimately.
// since that is only possible if the root-owned object did not exist,
// therefore we know that it never did exist since the last reboot
rebooted = 1;
}
}
return rebooted;
}
// for debugging purposes ONLY, so I don't have to keep rebooting to clear the object:
void rebooted_clear() {
if (shm_unlink("/bootcheck") == -1) {
perror("shm_unlink: failed, probably due to insufficient privileges or object nonexistent");
exit(1);
}
}
int main() {
int rebooted = rebooted_test_and_set();
printf("rebooted since last launch: %d\n", rebooted);
return 0;
}
If anyone has any clues, I'm stumped. Some information and examples for POSIX shared memory here.
In this python library they look for the last BOOT_TIME entry in utmp. Technically as what is in POSIX is utmpx (the file format) and the libc functions for accessing it. I think this is as good as you can get staying within POSIX.

SerialPort in mono in linux not responding to DataReceived event

I am writing an app that uses the serial port exposed by the SerialPort class in mono. What I have written so far works perfect in windows, however in linux the DataReceived event handler is never entered, so I cannot receive any data form my device. I have declared the event handler as follows:
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
Basically I am exploring good cross-platform options and this is a deal-breaker. Any advise on how to fix this or what is going on?
Edit-
I should also point out that I have tested the serial port and device on linux with other applications and all appears to be working.
Maybe it has changed lastly, but as far as I know, events are not currently implemented in Mono's serial port. You have to make another thread in any flavour to read data from serial port, which happens in blocking manner. Try it and tell if it worked.
On Antanas Veiverys blog you can find two possible ways to solve it.
(2012) By adjusting the mono source code.
http://antanas.veiverys.com/enabling-serialport-datareceived-event-in-mono/
(2013) By not touching the mono source but solving the issue in a derived class.
http://antanas.veiverys.com/mono-serialport-datareceived-event-workaround-using-a-derived-class/
(2014)
However, I encourage you to read Ben Voigts blog post where he ignores using the DataReceivedEvent and instead used the BaseStream async BeginRead/EndRead functions to read data from the serial port.
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport#comment-840
Implementing and using the given code sample works on both Windows/Unix, so I have tested. And it is more elegant than using the blocking Read() function in a threaded fashion.
mono does not support Event for serialport.
It is shown on mono's website
I have the same problem with SerialPort.DataReceived. Konrad's advice.
using System.IO.Ports;
using System.Threading;
namespace Serial2
{
class MainClass
{
public static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
Thread readThread = new Thread(new ThreadStart(ReadThread));
readThread.Start();
Thread.Sleep(200); // TODO: Ugly.
writeThread.Start();
Console.ReadLine();
}
private static void WriteThread()
{ // get port names with dmesg | grep -i tty
SerialPort sp2 = new SerialPort("/dev/ttyS5", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
if(sp2.IsOpen)
Console.WriteLine("WriteThread(), sp2 is open.");
else
Console.WriteLine("WriteThread(), sp2 is open.");
sp2.Write(" This string has been sent over an serial 0-modem cable.\n"); // \n Needed (buffering?).
sp2.Close();
}
private static void ReadThread()
{
SerialPort sp = new SerialPort("/dev/ttyS4", 115200, Parity.None, 8, StopBits.One);
sp.Open();
if(sp.IsOpen)
Console.WriteLine("ReadThread(), sp Opened.");
else
Console.WriteLine("ReadThread(), sp is not open.");
while(true)
{
Thread.Sleep(200);
if(sp.BytesToRead > 0)
{
Console.WriteLine(sp.ReadLine());
}
}
}
}
}

Can I use a socket as stdin/stdout in lxc (linux containers)?

I am interested in starting a daemon inside an lxc container with its stdin/stdout as a socket passed from the host, inetd style. Is this possible?
Be advised, if using an LXC "snapshot" clone, with a directory backing store (which thus uses overlayfs), then Unix FIFO pipes are currently broken. See:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1214500
I don't think LXC has native support, but you could always just run your lxc command under xinetd to get what you want. Or write your own server that talks sockets on one side and talks LXC (via popen() or something) on the other side.
inetd is a daemon that starts (non-daemonic) programs that use stdin/stdout to listen/talk to you
The LXC utilities lxc-start and lxc-execute insist on closing all open file descriptors (including stdin/stdout) making them useless with inetd. They eventually call clone(2), however, and so can you, writing your own C wrapper like this:
#define STACKSIZE 409600
/* choose your favourite brand of isolationism below */
#define SPLENDID_ISOLATION (CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWNET)
int exec_command(void* arg) {
/* don't close stdin/stdout here! */
execl("command", "command", arg, NULL);
return 1;
}
void main(int argc, char **argv) {
void *stack = malloc(STACKSIZE) + STACKSIZE - 1; /* grows downwards */
clone(&exec_command, stack, SIGCHLD|CLONE_VFORK|SPLENDID_ISOLATION, argv[1]);
wait(NULL);
}
This wrapper can then be run under inetd.

Resources