Getting address family can be done with getsockopt() with option SO_DOMAIN (see socket options) on linux.
(read Get address family from socket. Linux)
How do I do the same thing on OS X ?
When using the code that worked on linux on OS X I get
error: use of undeclared identifier 'SO_DOMAIN'
int err = getsockopt(sock, SOL_SOCKET, SO_DOMAIN, &addr_family, &len);
^
so not SO_DOMAIN ?
You can find this out by calling proc_pidfdinfo() on your own PID, and requesting PROC_PIDFDSOCKETINFO:
#include <libproc.h>
#include <stdbool.h>
#include <unistd.h>
bool socketDomainGet(int socket, int *domain) {
struct socket_fdinfo info;
int rc = proc_pidfdinfo(getpid(), socket, PROC_PIDFDSOCKETINFO, &info, sizeof info);
if (rc <= 0) return false;
*domain = info.psi.soi_family;
return true;
}
Unlike getsockname(), this works even if the socket hasn't been bound yet. Note as well as the domain (psi.soi_family), it also can tell you the type (psi.soi_type) and the protocol (psi.soi_protocol).
Keep in mind though this warning Apple gives in the libproc.h header:
/*
* This header file contains private interfaces to obtain process information.
* These interfaces are subject to change in future releases.
*/
They probably aren't going to break this, but the risk is higher than for more official APIs.
use SO_TYPE instead of SO_DOMAIN
in OS X man GETSOCKOPT(2) says
SO_TYPE get the type of the socket (get only)
I'm trying to use dlmopen() in order to launch the same .so file with few instances.
Because I the shared object includes few static methods, I have to use dlmopen() in order to create due instances of it.
For each instance (all in the same thread,if it matters), in the constructor I use:
handle_ = dlmopen(LM_ID_NEWLM, "path_to_so", RTLD_LAZY | RTLD_DEEPBIND);
and I get no errors, I'm even able to use dlsym() to invoke functions from the so file:
int (*function_name)(int, const char *);
function_name = (int (*)(int, const char *))(unsigned long)dlsym(handle_, "function_name");
The thing that happens is when I try to use any kind of "zmq send" method (the receive works well) I get:
terminate called after throwing an instance of 'zmq::error_t'
what(): Interrupted system call
even after I terminate the object of the dlmopen() and the object that created them.
Has anyone encountered this kind of problem? I tried to change the flags of the dlmopen() with no luck.
This is the code for zmq_send():
inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
{
int nbytes = zmq_send (ptr, buf_, len_, flags_);
if (nbytes >= 0)
return (size_t) nbytes;
if (zmq_errno () == EAGAIN)
return 0;
throw error_t ();
}
Why I get a '__packed__' attribute ignored [-Wattributes] warning in an android NDK Project?
Here is the code
mem_ = malloc(size_);
uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;
//uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
__packed uint32_t* ui32_ptr = (__packed uint32_t*)(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags;
I am using the packed attribute because I think I have alignment problem when casting from uint8_t to uint32_t (See [1]).
[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html
GCC doesn't seem to support the packed attribute for all variables. It is only supported for struct, union, and enum types. So you could try something like this instead:
mem_ = malloc(size_);
uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;
struct unaligned32_t
{
uint32_t data __attribute__((packed, aligned(1)));
};
//unaligned32_t* ui32_ptr = reinterpret_cast<unaligned32_t*>(ui8_ptr);
unaligned32_t* ui32_ptr = (unaligned32_t*)(ui8_ptr);
(ui32_ptr++)->data = size_;
(ui32_ptr++)->data = flags;
This won't produce the warning unless you use it on a char type, which is already byte aligned anyway.
I'm still investigating if this produces the code I'm aiming for on my ARM micro-controller but it is the only legal way I can think of using the packed attribute.
Here be dragons! Don't take the address of unaligned32_t.data. You should only access the data member of the struct using the . or -> directly, and not via a pointer. See this answer for why.
Link you referenced is for RVDS compiler (probably armcc) and GCC doesn't support packed attribute on pointers for such usage.
Good day. Im trying to get fullpath from struct file
char *buf = (char*)__get_free_page(GFP_USER);
char *buf2 = (char*)__get_free_page(GFP_USER);
char *name = dentry_path(file->f_dentry, buf, PAGE_SIZE);
char *root = dentry_path(file->f_vfsmnt->mnt_mountpoint, buf2, PAGE_SIZE);
***some operations***
free_page((unsigned long)buf);
free_page((unsigned long)buf2);
kfree(*root);
kfree(*name);
But i get an error
fs/read_write.c:707: error: request for member 'mnt_mountpoint' in something not a structure or union
How can i get vsfmount struct from file?
Kernel version linux-2.6.37.6
In kernel 2.6, your code should work.
In kernel 3.0, struct vfsmount contains member mnt_root, of type struct dentry.
I think this would give you the mount point path.
Which are you using?
Judging by the error, is it possible that f_vfsmnt is allocated in the file-struct?
I that case the mnt_mountpoint field should be accessible via file->f_vfsmnt.mnt_mountpoint.
I have been looking for some time but have not found anywhere near sufficient documentation / examples on how to use the CryptoAPI that comes with linux in the creation of syscalls / in kernel land.
If anyone knows of a good source please let me know, I would like to know how to do SHA1 / MD5 and Blowfish / AES within the kernel space only.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
#define SHA1_LENGTH 20
static int __init sha1_init(void)
{
struct scatterlist sg;
struct crypto_hash *tfm;
struct hash_desc desc;
unsigned char output[SHA1_LENGTH];
unsigned char buf[10];
int i;
printk(KERN_INFO "sha1: %s\n", __FUNCTION__);
memset(buf, 'A', 10);
memset(output, 0x00, SHA1_LENGTH);
tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
desc.tfm = tfm;
desc.flags = 0;
sg_init_one(&sg, buf, 10);
crypto_hash_init(&desc);
crypto_hash_update(&desc, &sg, 10);
crypto_hash_final(&desc, output);
for (i = 0; i < 20; i++) {
printk(KERN_ERR "%d-%d\n", output[i], i);
}
crypto_free_hash(tfm);
return 0;
}
static void __exit sha1_exit(void)
{
printk(KERN_INFO "sha1: %s\n", __FUNCTION__);
}
module_init(sha1_init);
module_exit(sha1_exit);
MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("Me");
There are a couple of places in the kernel which use the crypto module: the eCryptfs file system (linux/fs/ecryptfs/) and the 802.11 wireless stack (linux/drivers/staging/rtl8187se/ieee80211/). Both of these use AES, but you may be able to extrapolate what you find there to MD5.
Another good example is from the 2.6.18 kernel source in security/seclvl.c
Note: You can change CRYPTO_TFM_REQ_MAY_SLEEP if needed
static int
plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
{
struct crypto_tfm *tfm;
struct scatterlist sg;
if (len > PAGE_SIZE) {
seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
"characters). Largest possible is %lu "
"bytes.\n", len, PAGE_SIZE);
return -EINVAL;
}
tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP);
if (tfm == NULL) {
seclvl_printk(0, KERN_ERR,
"Failed to load transform for SHA1\n");
return -EINVAL;
}
sg_init_one(&sg, (u8 *)plaintext, len);
crypto_digest_init(tfm);
crypto_digest_update(tfm, &sg, 1);
crypto_digest_final(tfm, hash);
crypto_free_tfm(tfm);
return 0;
}
Cryptodev-linux
https://github.com/cryptodev-linux/cryptodev-linux
It is a kernel module that exposes the kernel crypto API to userspace through /dev/crypto .
SHA calculation example: https://github.com/cryptodev-linux/cryptodev-linux/blob/da730106c2558c8e0c8e1b1b1812d32ef9574ab7/examples/sha.c
As others have mentioned, the kernel does not seem to expose the crypto API to userspace itself, which is a shame since the kernel can already use native hardware accelerated crypto functions internally.
Crypto operations cryptodev supports: https://github.com/nmav/cryptodev-linux/blob/383922cabeea7dca354415e8c590f8e932f4d7a8/crypto/cryptodev.h
Crypto operations Linux x86 supports: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/crypto?id=refs/tags/v4.0
The best place to start is Documentation/crytpo in the kernel sources. dm-crypt is one of the many components that probably uses the kernel crypto API and you can refer to it to get an idea about usage.
how to do SHA1 / MD5 and Blowfish / AES within the kernel space only.
Example of hashing data using a two-element scatterlist:
struct crypto_hash *tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
if (tfm == NULL)
fail;
char *output_buf = kmalloc(crypto_hash_digestsize(tfm), GFP_KERNEL);
if (output_buf == NULL)
fail;
struct scatterlist sg[2];
struct hash_desc desc = {.tfm = tfm};
ret = crypto_hash_init(&desc);
if (ret != 0)
fail;
sg_init_table(sg, ARRAY_SIZE(sg));
sg_set_buf(&sg[0], "Hello", 5);
sg_set_buf(&sg[1], " World", 6);
ret = crypto_hash_digest(&desc, sg, 11, output_buf);
if (ret != 0)
fail;
One critical note:
Never compare the return value of crypto_alloc_hash function to NULL for detecting the failure.
Steps:
Always use IS_ERR function for this purpose. Comparing to NULL does not capture the error, hence you get segmentation faults later on.
If IS_ERR returns fail, you possibly have a missing crypto algorithm compiled into your kernel image (or as a module). Make sure you have selected the appropriate crypto algo. form make menuconfig.