Python3 read fron character device in blocking mode - python-3.x

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?

Related

dropping packets that contain string linux kernel module

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.

Linux kernel module to read out GPS device via USB

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);
...
}

Linux (Ubuntu) ioctl KDGETLED/KDGKBLED always 0

Code snippet below; basically, I am grabbing the active vt and issuing an ioctl KDGETLED against that terminal for the current state of the capslock/numlock/scrolllock keys and I always get result=0, regardless of the state of the lock keys.
I've tried this on multiple Linux boxes, all running variants of Ubuntu (e.g. Mint). I've tried other fds for the KDGETLED command such as "/dev/tty", "/dev/console", 0, etc. I'm running into the same problem with KDGKBLED. Are others experiencing the same issue, am I doing something silly, am I running into poorly written drivers, or something else?
int fd;
vt_stat stat;
fd = open("/dev/tty0", O_RDONLY);
if (ioctl(fd, VT_GETSTATE, &stat) == -1) {
fprintf(stderr, "Error on VT_GETSTATE\n");
exit(1);
}
close(fd);
char tty[128];
sprintf(tty, "/dev/tty%d", stat.v_active);
printf("Query tty: %s\n", tty);
char result;
fd = open(tty, O_RDWR | O_NDELAY, 0);
if (ioctl(fd, KDGETLED, &result) == -1) {
fprintf(stderr, "Error on KDGETLED\n");
exit(1);
}
close(fd);
printf("LED flag state: %d\n", result);
Thanks, in advance, to all who review my question.
Checkout the driver code, especially the struct file_operations instance for that driver, and check the function assigned to the .ioctl member - if that is poorly coded (I've seen a lot of shitty stuff happening in ioctls) then that is definitely your issue.
In this case I am pretty sure it is the drivers fault. As long the ioctl command shows no compile error, everything - especially error handling and input checking - is the task of the driver.

Develop simple net_device in the linux kernel

I am trying to implement a netdevice (net_device) in linux kernel. This is simple net_device which pass the command/data from user space to kernel space and vice versa this is the goal of this simple net_device. I am using socket for passing command/data from user space to kernel space . After googling i successed in registering net_device and able to see my device in /sys/class/net/abc0 (device name)
when coming to file operation there is no clear idea of the flow
struct net_device_ops
{
.ndo_open =open,
.ndo_close = close,
.ndo_start_xmit = start_xmit
}
if i issue write in socket will it call start_xmit in data link layer.
If i want to call open method, how to call it using socket
How to call start_xmit using socket
How will i find , there is data packet in the receive buffer and pass it to user space.
There is no clear flow/information about simple net_device (except ethernet) can any suggest a link/pdf.
I tried writing simple socket program to test open,close,start_xmit. where socket read/write is not calling open,close,star_xmit .
Is there any way to test the developed net_device ?
Thank you
I found how to test the open,close function .
type : ifconfig abc0(Device name) up will call open method
type : ifconfig abc0(Device name) down will call close method
Can some one help me how to test these methods with sockets.
SIOCSIFFLAGS, -> IFF_UP you can actually set or unset it while doing an ioctl to the netdevice abc0.
first off you have to create a dgram socket,
then use ifreq structure defined in net/if.h
and fill interface and iff_flags
iff_flags can be set with IFF_UP or can be negated with the same IFF_UP to make interface down
and then close the socket.
#include <net/if.h>
....
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
goto fail;
}
struct ifreq ifreq;
strcpy(ifreq.ifr_name, "abcd0");
ifreq.iff_flags |= IFF_UP;
if (ioctl(sock, &ifreq, sizeof(ifreq) < 0) {
perror("ioctl setting interface up");
}
ifreq.iff_flags ~= IFF_UP;
if (ioctl(sock, &ifreq, sizeof(ifreq) < 0) {
perror("ioctl setting interface down");
}
close(sock);
offtopic:
will you please share your code? we can understand too about your network device :)

Kernel module get data from user space

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.

Resources