What is the proper way of sending some data to a loaded and running kernel module, without using netlink and without using features that may not be in place (e.g. debugfs)?
I'd like to see a clean and safe way of doing this which should work on most kernels (or preferably all modern ones), or at best an approximation of that.
The user who wants to send data to the module is the root user, the amount of data is probably under 64 kiB and consists of a series of strings.
I've already looked into trying to read files from the module, which is not only highly frowned upon for various reasons but also hard to do.
I've looked at netlink, which socket() tells me on my kernel is not supported.
I've looked at debugfs, which is not supported either on my kernel.
Obviously I could use a different kernel but as I mentioned I'd like a proper way of doing this. If someone could show me a simple example of a module that will just do a printk() of a string sent from user space that would be great.
... a simple example of a module that will just do a printk() of a string sent from user space, printkm.c:
#include <linux/module.h>
#include <linux/proc_fs.h>
MODULE_DESCRIPTION("printk example module");
MODULE_AUTHOR("Dietmar.Schindler#manroland-web.com");
MODULE_LICENSE("GPL");
static
ssize_t write(struct file *file, const char *buf, size_t count, loff_t *pos)
{
printk("%.*s", count, buf);
return count;
}
static struct file_operations file_ops;
int init_module(void)
{
printk("init printk example module\n");
struct proc_dir_entry *entry = proc_create("printk", 0, NULL, &file_ops);
if (!entry) return -ENOENT;
file_ops.owner = THIS_MODULE,
file_ops.write = write;
return 0;
}
void cleanup_module(void)
{
remove_proc_entry("printk", NULL);
printk("exit printk example module\n");
}
Example use:
root#kw:~# insmod printkm.ko
root#kw:~# echo a string >/proc/printk
root#kw:~# dmesg|tail -1
[193634.164459] a string
I think you can use a char device. Take a look at Linux Device Driver 3th Chapter 3. With the function *copy_to_user* and *copy_from_user* you can copy data safely to and from userspace.
Related
I wrote a character device driver. Now I want to use python to read from it when there is data.
However, I found that the modules "io" as well as "os" do not block upon reading. The latter even when I set os.set_blocking(fd,true).
Is there a way to access the device in blocking mode?
Or do I miss something in the device driver (tail works fine)?
f=io.open("/dev/tstty0","r")
while (1)
data=str(f.read(32))
print("mark") # <--- endless list of marks
#do somthing
The read function of the device driver:
static ssize_t tstty_read(
struct file *filp,
char *buffer,
size_t length,
loff_t *offset)
{
unsigned char b;
unsigned long ofs=0;
devConfig* dev=filp->private_data;
if (dev)
{
while (fifoGet(&dev->tcp2dev,&b) && (ofs<length))
{
if (put_user(b,buffer+ofs))
{
printk(KERN_ERR "Could not copy user data");
return -EINVAL;
}
ofs++;
}
//printk(KERN_INFO "Reading device");
return ofs;
}
printk(KERN_ERR "Unknown device: %s",filp->f_path.dentry->d_iname);
return -EINVAL;
};
The read function reads any bytes available from a fifo. I none is available 0 is returned.
Kudos to Ian Abbott. A character device has to implement the ability to block a read request. The read file operation has to evaluate filp->f_flags & O_NONBLOCK to check if a client has requested blocking I/O.
This link helped me with an example:
simple linux driver code for blocking and non-blocking read
This example works but one has to consider two more things not covered in the example: a) What to do when you want to unload the driver while in read operation (just dont do it or wake up and abort)?
b) How to abort a client caught in blocking I/O?
I'm trying to drop network packets that contain a string: i.e. if a webpage says "free download" on it i need my kernel module to drop the packets that contain that string. I'm trying to scan through sk_buff in the netfilter hook, but not sure if this is the right place to look for the string. here is the code:
unsigned int hook_func_outgoing(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state) {
int pos;
struct ts_config *conf;
struct ts_state statetext;
const char *pattern = "free download";
conf = textsearch_prepare("kmp", pattern, strlen(pattern),
GFP_KERNEL, TS_AUTOLOAD);
pos = textsearch_find_continuous(conf, &statetext, skb->data, skb->len);
printk(KERN_INFO "pos: %d", pos);
printk(KERN_INFO "data: %s ", skb->data);
if (pos != UINT_MAX){
return NF_DROP;
printk(KERN_INFO "found spam\n");
}
textsearch_destroy(conf);
return NF_ACCEPT;
}
This is not as easy as it sounds.
I'm not fully aware of writing kernel modules for network filtering, so I cannot comment on your code. But I think the major problem here is that you have only access to the "raw" packet.
The internet nowadays is mostly encrypted using TLS (https) and thus you cannot read the content of the transfer on that level (which is good). This means that your module can only work on unencrypted HTTP-Connections. Another issue might be HTTP compression like GZIP which can scramble your data too.
I'm writing a Linux kernel module to read out a GPS device (a u-blox NEO-7) via USB by using the book Linux Device Drivers.
I already can probe and read out data from the device successfully. But, there is a problem when reading the device with multiple applications simultaneously (I used "cat /dev/ublox" to read indefinitely). When the active/reading applications is cancelled via "Ctrl + C", the next reading attempt from the other application fails (exactly method call usb_submit_urb(...) returns -EINVAL).
I use following ideas for my implementation:
The kernel module methods should be re-entrant. Therefore, I use a mutex to protect critical sections. E.g. allowing only one reader simultaneously.
To safe ressources, I reuse the struct urb for different reading requests (see an explanation)
Device-specific data like USB endpoint address and so on is held in a device-specific struct called ublox_device.
After submitting the USB read request, the calling process is sent to sleep until the asynchronous complete handler is called.
I verified that the ideas are implemented correctly: I have run two instances of "cat /dev/ublox" simultaneously and I got the correct output (only one instance accessed the critical read section at a time). And also reusing the "struct urb" is working. Both instances read out data alternatively.
The problem only occurs if the currently active instance is cancelled via "Ctrl + C". I can solve the problem by not reusing the "struct urb" but I would like to avoid that. I.e. by allocating a new "struct urb" for each read request via usb_alloc_urb(...) (usually it is allocated once when probing the USB device).
My code follows the USB skeleton driver from Greg Kroah-Hartman who also reuse the "struct urb" for different reading requests.
Maybe someone has a clue what's going wrong here.
The complete code can be found on pastebin. Here is a small excerpt of the read method and the USB request complete handler.
static ssize_t ublox_read(struct file *file, char *buffer, size_t count, loff_t *pos)
{
struct ublox_device *ublox_device = file->private_data;
...
return_value = mutex_lock_interruptible(&ublox_device->bulk_in_mutex);
if (return_value < 0)
return -EINTR;
...
retry:
usb_fill_bulk_urb(...);
ublox_device->read_in_progress = 1;
/* Next call fails if active application is cancelled via "Ctrl + C" */
return_value = usb_submit_urb(ublox_device->bulk_in_urb, GFP_KERNEL);
if (return_value) {
printk(KERN_ERR "usb_submit_urb(...) failed!\n");
ublox_device->read_in_progress = 0;
goto exit;
}
/* Go to sleep until read operation has finished */
return_value = wait_event_interruptible(ublox_device->bulk_in_wait_queue, (!ublox_device->read_in_progress));
if (return_value < 0)
goto exit;
...
exit:
mutex_unlock(&ublox_device->bulk_in_mutex);
return return_value;
}
static void ublox_read_bulk_callback(struct urb *urb)
{
struct ublox_device *ublox_device = urb->context;
int status = urb->status;
/* Evaluate status... */
...
ublox_device->transferred_bytes = urb->actual_length;
ublox_device->read_in_progress = 0;
wake_up_interruptible(&ublox_device->bulk_in_wait_queue);
}
Now, I allocate a new struct urb for each read request. This avoids the problem with the messed up struct urb after an active read request is cancelled by the calling application. The allocated struct is freed in the complete handler.
I will come back to LKML when I optimize my code. For now, it is okay to allocate a new struct urb for each single read request. The complete code of the kernel module is on pastebin.
static ssize_t ublox_read(struct file *file, char *buffer, size_t count, loff_t *pos)
{
struct ublox_device *ublox_device = file->private_data;
...
retry:
ublox_device->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
...
usb_fill_bulk_urb(...);
...
return_value = usb_submit_urb(ublox_device->bulk_in_urb, GFP_KERNEL);
...
}
static void ublox_read_bulk_callback(struct urb *urb)
{
struct ublox_device *ublox_device = urb->context;
...
usb_free_urb(ublox_device->bulk_in_urb);
...
}
So, I am a total newbie when it comes to kernel drivers and have a question regarding ioremap function.
I am writing a driver for accessing some registers defined in a custom VHDL-module on a SoC with a ARM Cortex-M3 and FPGA fabric.
Looking at examples I figured I should use ioremap, but since the Cortex-M3 does not have a MMU, I don't really see the point, as per the following example:
/* Physical addresses */
static u32* rcu_trig_recv_physaddr = ((u32 *) 0x50040000);
static int rcu_trig_recv_size = 0x10; // size of 16 for testing
/* Virtual addresses */
static u32* rcu_trig_recv_virtbase = NULL;
/*removed code not relevant for the question*/
static int __init rcumodule_init(void)
{
int iResult = 0; // holding result of operations
u32 buffer;
// Register the driver
iResult = register_chrdev(rcuc_majorID, "rcuc", &rcuc_fops);
if (iResult < 0) {
printk(KERN_INFO "module init: can't register driver\n");
}
else{
printk(KERN_INFO "module init: success!\n");
}
// Map physical address to virtual address
if(rcu_trig_recv_size){
rcu_trig_recv_virtbase = (u32*) ioremap_nocache( (u32 *)rcu_trig_recv_physaddr, rcu_trig_recv_size );
printk("Remapped TRGRECV from 0x%p to 0x%p\n", rcu_trig_recv_physaddr, rcu_trig_recv_virtbase);
}
// try to read some stuff, expecting 0x17240f09
buffer = readl(rcu_trig_recv_virtbase);
printk("read %lx, at 0x%p\n", buffer, rcu_trig_recv_virtbase);
return iResult;
}
This then return, when I insmod the driver:
# insmod trigger.ko
module init: success!
Remapped TRGRECV from 0x50040000 to 0x50040000
read 17240f09, at 0x50040000
According to this, I would just be better off reading the physical address instead. Or is that a bad idea and I should be messing with my registers in a better way?
It's possible that you can get away with this if you know your code will never need to be used on another device, but you're much safer sticking with using ioremap(). Basing your code around obtaining and using the pointers provided by memory-mapped IO will make your code more portable and maintainable than utilizing hard-coded physical addresses.
Even if you don't plan on taking this code to a different device, using physical addresses could potentially break your code when simply upgrading to a newer chip in the same line.
a user submitted a bug-report, where my application segfaults in "__fortify_fail()".
i understand that this is related to building my application with Debian's "hardening" flags -D_FORTIFY_SOURCE=2 -fstack-protector.
unfortunately the backtrace of the user does not tell me much yet, and the user is not super responsive (right now).
in order to understand better what is going on, i would like to know, what __fortify_fail actually does.
This function is normally just an error reporter. Sample code from glibc is:
extern char **__libc_argv attribute_hidden;
void
__attribute__ ((noreturn))
__fortify_fail (msg)
const char *msg;
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (2, "*** %s ***: %s terminated\n",
msg, __libc_argv[0] ?: "<unknown>");
}
libc_hidden_def (__fortify_fail)
It may be called here and there where sources is preferred to be fortified. "Fortification" itself is just a couple of run-time checks. Sample usage in openat function from io/openat.c is:
int
__openat_2 (fd, file, oflag)
int fd;
const char *file;
int oflag;
{
if (oflag & O_CREAT)
__fortify_fail ("invalid openat call: O_CREAT without mode");
return __openat (fd, file, oflag);
}
Without fortification, O_CREAT is acceptable without mode (still this case is highly suspicious, it is legal).
Think about __fortify_fail like about printf+abort.
Turning telepathy on about your question, I may suggest that user have some problems with using libc in user code. /lib/x86_64-linux-gnu/libc.so.6(+0xebdf0)[0x7f75d3576df0] is a place inside libc where some runtime-check fails, so pd[0x49b5c0] is a place where libc incorrectly called from.