Quantcast
Channel: Active questions tagged linux-kernel - Stack Overflow
Viewing all 12204 articles
Browse latest View live

How can I create my own defined MTD device through kernel command line on ARM system?

$
0
0

At first, I didn't add any kernel parameter and then got MTD device

/proc/mtd:
dev:    size   erasesize  name
mtd0: 01000000 00010000 "spi1.0"

then, I added setenv mtdids "mtdids=spi1.0", and setenv mtdparts "mtdparts=spi1.0:2m(U-Boot)ro,-(RootFS)ro" to kernel command line, at the meantime, I turned on

"Command line partition table parsing",
"ARM Firmware Suite partition parsing"

of Device Drivers ---> Memory Technology Device (MTD) support through Kconfig. Finally, I got,

 dev:    size   erasesize  name
 mtd0: 00100000 00010000 "u-boot"
 mtd1: 00400000 00010000 "kernel"
 mtd2: 00a00000 00010000 "rootfs"

But this is still not what I want. Do I have something missing? Thanks for help,


EBPF: pointer arithmetic on PTR_TO_PACKET_END prohibited

$
0
0

I am trying to write a kernel module for filtering using the following example. On Ubuntu 18.04 with kernel 5.3.0 it's compiled and works perfectly fine.

However, when the same example is compiled on Debian 10 with kernel 4.19.0 compilation emits another byte-code, which is rejected when trying to load it to kernel by the kernel's verifier with error:

Prog section 'action' rejected: Permission denied (13)!
 - Type:         4
 - Instructions: 108 (0 over limit)
 - License:      GPL

Verifier analysis:

0: (bf) r6 = r1
1: (61) r2 = *(u32 *)(r6 +84)
2: (67) r2 <<= 32
3: (61) r1 = *(u32 *)(r6 +80)
4: (4f) r2 |= r1
R2 pointer arithmetic on PTR_TO_PACKET_END prohibited

Error fetching program/map!
bad action parsing
parse_action: bad value (6:bpf)!
Illegal "action"

What can be the issue? Is there a bug somewhere in kernel, compiler, verifier or the example? Versions of clang and llc match on both systems: 6.0.0 for both.

Save old sk_data_ready

$
0
0

After creating a socket, I set a custom listen_data_ready(struct sock *sk) callback. However, for accepted socket I want to reset the callback to sock_def_readable.

sk->sk_user_data = sk->sk_data_ready;
sk->sk_data_ready = listen_data_ready;

And then, for new accepted socket, I want to use sk->sk_data_ready = sk_user_data;

But that didn't work. I guess sk_user_data is just a pointer, so it points to the new sk_data_ready function. Any idea how to do this?

How to write a network device driver to edit (encrypt) Network packet between sender and receiver

$
0
0

I try to use this sample to get the network packet and I need encrypt data before reach to destinations.
like server send a message like: hello-world I need to encrypt it before reaching to server.

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/ip.h>
#include <linux/inet.h>

#define DIP "1.2.3.4"

static struct nf_hook_ops nfho;     // net filter hook option struct
struct sk_buff *sock_buff;          // socket buffer used in linux kernel
struct udphdr *udp_header;          // udp header struct (not used)
struct iphdr *ip_header;            // ip header struct
struct ethhdr *mac_header;          // mac header struct


MODULE_DESCRIPTION("Redirect_Packet");
MODULE_AUTHOR("Andy Lee <a1106052000 AT gmail.com>");
MODULE_LICENSE("GPL");

unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
        sock_buff = skb;
        ip_header = (struct iphdr *)skb_network_header(sock_buff); //grab network header using accessor
        mac_header = (struct ethhdr *)skb_mac_header(sock_buff);

        if(!sock_buff) { return NF_DROP;}

        //TODO:: Need to edit network packet.

        if (ip_header->protocol==IPPROTO_ICMP) { //icmp=1 udp=17 tcp=6
                printk(KERN_INFO "Got ICMP Reply packet and dropped it. \n");     //log we’ve got udp packet to /var/log/messages
        printk(KERN_INFO "src_ip: %pI4 \n", &ip_header->saddr);
            printk(KERN_INFO "dst_ip: %pI4\n", &ip_header->daddr);
        ip_header->daddr = in_aton(DIP);
        printk(KERN_INFO "modified_dst_ip: %pI4\n", &ip_header->daddr);
        }
        return NF_ACCEPT;
}

int init_module()
{
        nfho.hook = hook_func;
        nfho.hooknum = 4; //NF_IP_PRE_ROUTING=0(capture ICMP Request.)  NF_IP_POST_ROUTING=4(capture ICMP reply.)
        nfho.pf = PF_INET;//IPV4 packets
        nfho.priority = NF_IP_PRI_FIRST;//set to highest priority over all other hook functions
        nf_register_hook(&nfho); //register hook

        printk(KERN_INFO "---------------------------------------\n");
        printk(KERN_INFO "Loading dropicmp kernel module...\n");
        return 0;
}

void cleanup_module()
{
    printk(KERN_INFO "Cleaning up dropicmp module.\n");
        nf_unregister_hook(&nfho);
}

I need to edit the packet before reach to the destination.

possibly bug: modprobe ip_tables doesn't work

$
0
0

I want to test some Linux conntrack behavior. So I should turn on iptables before connection tracking system.
I tried modprobe ip_tables as root but it fails with:

modprobe: ERROR: ../libkmod/libkmod-module.c:960 command_do() Error running install command for ip_tables
modprobe: ERROR: could not insert 'ip_tables': Operation not permitted

I can't inspect command_do(), can't find this function source code. But it seems there is some bug in Linux kernel or in module loading system.
P.S. I have 4.4.161 kernel, but there are some other kernels installed on my machine.

Getting kernel config from defconfig

$
0
0

The title says it all: I need the .config file that was used for compiling a kernel, but all I have is the defconfig file. I've seen instructions on how to produce the latter from the former, but not the other way around. Is it possible?

Disadvantage of using mutex in interrupt context

$
0
0

What is Disadvantage of using mutex in interrupt context.Why spin lock is preferred here.

Path lookup in linux kernel 4.15

$
0
0

I'm trying to write a simple kernel module, just for didactic purpose. In particular, what is giving me headaches is the path lookup. I'd like to have a sysfs entry and in the store operation I want to receive a buffer and I want to save it only if it's a valid path. So I tried to use the vfs_path_lookup Exported Symbols from here namei.c. But even inserting a valid path, it prints me the ENOENT error.

This is my code:

Into the header:

extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *path);

Into the module store function:

ssize_t path_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count){

            int err = vfs_path_lookup(current->fs->root.dentry, current->fs->root.mnt, buf, LOOKUP_DIRECTORY, base_path);
            printk(KERN_DEBUG "%s\n", __FUNCTION__);
            printk(KERN_DEBUG "Received: %s err is %d\n", buf, err);        

            strncpy(base_addr, buf, MAX_FILENAME_SIZE);
            printk(KERN_DEBUG "Base Addr: %s\n", base_addr);
            return strlen(base_addr);
        }

What I tried to write into the file is the string "/home/osboxes/Documents" that is an existing directory. I suspect that I didn't get the real usage of the function, maybe something with flags. Thank you in advance for your help.

Edit: This is the example requested into the comments (Thanks again)

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kobject.h> 
#include <linux/sysfs.h>



#define MAX_FILENAME_SIZE 256

struct path *base_path ;
struct kobject *conf_kobj;
char base_addr[MAX_FILENAME_SIZE] = "/home/osboxes/Documenti";

struct kobj_attribute *get_attribute(char *name, umode_t mode, ssize_t (*show)(struct kobject *, struct kobj_attribute *, char *), ssize_t (*store)(struct kobject *, struct kobj_attribute *,
             const char *, size_t));

ssize_t path_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf){
                printk(KERN_DEBUG "%s\n", __FUNCTION__);

                return sprintf(buf, "%s", base_addr);
            }
ssize_t path_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count){

                int err = kern_path(buf, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, base_path);
                printk(KERN_DEBUG "%s\n", __FUNCTION__);
                printk(KERN_DEBUG "Received: %s err is %d\n", buf, err);        

                strncpy(base_addr, buf, MAX_FILENAME_SIZE);
                printk(KERN_DEBUG "Base Addr: %s\n", base_addr);
                return strlen(base_addr);
            }



static int __init init_mymodule(void)
{   
    struct kobj_attribute *path_attr;

    printk(KERN_DEBUG "Module inserted\n");

    path_attr = get_attribute(base_addr, 0666, path_show, path_store);
    base_path = kmalloc(sizeof(struct path), GFP_KERNEL);

    conf_kobj = kobject_create_and_add("conf", kernel_kobj);


    sysfs_create_file(conf_kobj, &path_attr->attr);

    return 0;

}



struct kobj_attribute *get_attribute(char *name, umode_t mode, ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf), ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
             const char *buf, size_t count))
{
    struct kobj_attribute *attribute = kmalloc(sizeof(struct kobj_attribute), GFP_KERNEL);

    attribute->attr.name = name;
    attribute->attr.mode = mode;
    if(show)
        attribute->show = show;
    if(store)
        attribute->store = store;
    return attribute;

}

static void __exit exit_mymodule(void)
{

    kobject_put(conf_kobj);
    kfree(base_addr);
    printk(KERN_INFO "Module removed\n");
}



module_init(init_mymodule);
module_exit(exit_mymodule);

MODULE_LICENSE("GPL");

I also replaced vfs_path_lookup with kern_path as @Tsyvarev suggested. The error comes when I write into the terminal

echo "/home/osboxes/Documenti"> /sys/kernel/conf/path

When I use the address into the "buf" variable, in this case it's hardcoded, but doesn't work.


How to fix dependency on devm_kmalloc for the phy driver?

$
0
0

I am trying to build a custom phyDriver in my Ubuntu Machine - 18.04. However, I get errors on insmod like -

The dmesg tells me -

57810.400155] phyDriver: module license 'unspecified' taints kernel.
[57810.400156] Disabling lock debugging due to kernel taint
[57810.400196] phyDriver: Unknown symbol devm_kmalloc (err -2)
[57810.400234] phyDriver: Unknown symbol platform_driver_unregister (err -2)
[57810.400555] phyDriver: Unknown symbol __platform_driver_register (err -2)

I am unsure why I am getting devm_kmalloc() unknown symbol. I am using devm_kzalloc() and I believe this is complaining about devm_kzalloc(). My question is how do I solve this problem. Do I need to build kernel to add those debug symbols or is there any other easy way? If I have to build kernel then what I need to enable in the kernel so that my driver can access these symbols like - devm_kzalloc()platform_driver_register()

Here is the snippet of my code:

static int phy_platform_probe(struct platform_device *pdev) { 

  struct custom_port_phy_platform_local *lp;
    int ret;

    lp  = devm_kzalloc(&pdev->dev,sizeof(struct custom_port_phy_platform_local),GFP_KERNEL);
    if (!lp) {
      dev_err(&(pdev->dev),"Failed to allocatate platform_local\n");
        return -ENOMEM;
    }
    platform_set_drvdata(pdev, lp);

    lp->dev = &pdev->dev;
    ret = custom_port_phy_mdio_setup(lp, pdev->dev.of_node);
    if (ret < 0) {
      dev_err(&(pdev->dev),"Failed to setup MDIO bus\n");
      return ret;
    }

    return 0;
}


static int __init phy_init(void)
{
   int ret = 0;
   ret = phy_driver_register(&custom_phy_driver, THIS_MODULE);
   if(ret < 0) {
       printk(KERN_ALERT "custom phy driver registration failed\r\n");
       return ret;
   }

   ret = platform_driver_register(&custom_phy_platform_driver);
   if(ret < 0) {
       phy_driver_unregister(&custom_phy_driver);
       printk("%s: Failed to register as Platform Driver\r\n", __func__);
       return ret;
   }

   return ret;
}

Booting Linux on Qemu

n_gsm Line discipline problem with Telit LE910B1 Modem and CMUX

$
0
0

We are using a Telit LE910B1 modem on an embedded device running a Linux 5.1.0 kernel. We only have a single UART available for the modem so we are using n_gsm line discipline with CMUX on the modem. Once everything is setup, our app creates two virtual ttys, uses one to get modem information and the other is passed to pppd to start a PPP session. We can then start data RX/TX over TCP/IP. This all works fine for a short time, with small data transfers, but when we try to transfer large amounts of data, the PPP connection locks up and the only way to get things running again is to kill pppd, power cycle the modem, and restart the application.

Telit was able to reproduce the problem with two different versions of Ubuntu (18.04 and , and was able to obtain tracing information from the modem, which they pass to Intel for further diagnosis. Intel's response was that they think the "host application side" may not be making correct CMUX frames or is not respecting max frame size. Here are some extracts given to us by Telit from the analysis of the modem trace:

<-- Packet discarded because of flag("0xF9") missing in CMUX frame.
<-- Packet discarded because of dlc is not valid in frame.
<-- Packet discarded because of length size more then RD_BUF_SIZE = 1510
<-- Packet dropped because of in PPP frame FCS is not valid

In my case, the "host application side" is the n_gsm driver in Linux and the only things I can set are the mru and mtu sizes, which I've set to what Telit says is the modem's default (i.e. 121).

The code I use to configure the modem is pretty straight forward (error checking is omitted for brevity):

struct termios tio;
int serial_fd;

serial_fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(serial_fd, &tio);
tio.c_iflag = 0;
tio.c_oflag = 0;
tio.c_cflag = CS8 | CREAD | CLOCAL;
tio.c_cflag |= CRTSCTS;
tio.c_lflag = 0;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;

cfsetospeed(&tio, B115200);
cfsetispeed(&tio, B115200);
tcsetattr(serial_fd, TCSANOW, &tio);

To configure the modem I use the following:

send_at_command(serial_fd, "ATE0V1&K3&D2\r");
send_at_command(serial_fd, "AT#CMUXMODE=5\r");
send_at_command(serial_fd, "AT+CMUX=0,0\r");

Once that's done, I enable n_gsm discipline

struct gsm_config gsm;

int ldisc = N_GSM0710;
ioctl(serial_fd, TIOCSETD, &ldisc);
ioctl(serial_fd, GSMIOC_GETCONF, &gsm) ;

gsm.initiator = 1;
gsm.encapsulation = 0;
gsm.mru = 121;
gsm.mtu = 121;

ioctl(serial_fd, GSMIOC_SETCONF, &gsm);
/* Create /dev/ttyGSM1 and /dev/ttyGSM2. Do not close /dev/ttyS1 */

Has anyone else used an LE910* modem with CMUX and n_gsm line discipline on a Linux 5.1.0 or later kernel? Have you had any problems? Are there any problem with the code I've shown or can you suggest something I could try?

EDIT

I looked at the n_gsm.c driver code and discovered that there are 3 trace level you can enable. I started by enabling level 4 and 2:

echo "6"> /sys/module/n_gsm/parameters/debug

and this would log packets as they are built and sent to the tty. What I found was that what Intel said was correct. The driver is sending garbage to the modem. The log shows normal packets going out but then this:

Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000000: f9 0b ef f3 21 45 10 05 74 aa 6a 40 00 40 06 d1  ....!E..t.j@.@..
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000010: a5 46 19 8e 6f cc 65 18 76 00 16 0b 58 5b e6 da  .F..o.e.v...X[..
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000020: 55 bd 3e 38 ad 80 18 1f 4a 4d dc 00 00 01 01 08  U.>8....JM......
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000030: 0a 65 3c e5 73 7b 9d 4c 86 f8 53 e4 9f ff a4 9e  .e<.s{.L..S.....
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsmld_output: 00000060: 27 3c ee ab 28 29 51 e7 4e 04 f4 70 ce d4 e3 f2  '<..()Q.N..p....
Jan 19 18:09:51 ZFG0000805 kern.debug kernel: gsmld_output: 00000070: 93 ed 71 30 c7 1e 93 d8 b3 4a 90 88 e7 f9        ..q0.....J....

Normally you see a kick followed by an output where the packet is exactly the same, but not here. CMUX packets should start and end with a 0xf9 byte but the "output" packet appears corrupt. After this, all kick logging shows complete packets but the following output trace starts one byte off from the start-of-frame character.

Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000000: f9 0b ef f3 87 8d e0 d0 db 2a 22 96 92 80 b6 a4  .........*".....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000010: 31 33 43 f0 13 e9 f3 79 13 d9 b4 13 8a 85 10 15  13C....y........
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000020: 26 0d ab c2 89 f2 ad a2 6f cd 5d a9 15 f2 fe e8  &.......o.].....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000030: 6a 90 06 ef f3 d2 4c c1 65 4e 3c 22 f5 db f8 66  j.....L.eN<"...f
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000040: d5 d7 70 fa f5 47 03 09 52 d3 1f 30 91 55 20 ce  ..p..G..R..0.U .
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000050: bc 71 51 b5 f7 ac f4 2a 7d 5d 1d 47 8d 30 73 22  .qQ....*}].G.0s"
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000060: 38 fa 39 f4 64 9f f6 7d 5d 7d 5d 2a ab b6 a6 cf  8.9.d..}]}]*....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsm_data_kick: 00000070: 76 dd 8f 0a fd 27 8f 09 b2 78 99 da f8 e7 f9     v....'...x.....
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000000: 0b ef f3 87 8d e0 d0 db 2a 22 96 92 80 b6 a4 31  ........*".....1
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000010: 33 43 f0 13 e9 f3 79 13 d9 b4 13 8a 85 10 15 26  3C....y........&
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000020: 0d ab c2 89 f2 ad a2 6f cd 5d a9 15 f2 fe e8 6a  .......o.].....j
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000030: 90 06 ef f3 d2 4c c1 65 4e 3c 22 f5 db f8 66 d5  .....L.eN<"...f.
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000040: d7 70 fa f5 47 03 09 52 d3 1f 30 91 55 20 ce bc  .p..G..R..0.U ..
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000050: 71 51 b5 f7 ac f4 2a 7d 5d 1d 47 8d 30 73 22 38  qQ....*}].G.0s"8
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000060: fa 39 f4 64 9f f6 7d 5d 7d 5d 2a ab b6 a6 cf 76  .9.d..}]}]*....v
Jan 19 18:09:52 ZFG0000805 kern.debug kernel: gsmld_output: 00000070: dd 8f 0a fd 27 8f 09 b2 78 99 da f8 e7 f9        ....'...x.....

Now the really weird part. When I enable packet logging,

echo "7"> /sys/module/n_gsm/parameters/debug

Packets are logged just before being queued for sending. This slows down the whole system but no matter what I tried, I could not get the network session to hang. Everything seemed to work fine, although it was gawd awful slow.

Changing default permissions on IOctl cdev

$
0
0

I am adding an IOctl call from the native OpenGL framework on an Android device such that I can log frame information in the kernel via a tracing kernel module. In my kernel module I am creating the cdev for the IOctl calls but am having the problem that my dev's default permissions are 6000 and since the user-land IOctl calls are coming from a non-root process the open call is unable to open the file decriptor required for the ioctl call.

My cdev approach is very much standard and as follows (note devnode is an attempt to fix permissions, see this).

static dev_t dev;
static struct cdev c_dev;
static struct class *cl;

static char *device_node(struct device *dev, umode_t *mode) 
{ 
    if(!mode)
        return NULL;
    *mode=0666;
    return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
}

static int IOctlInit(void)
{
    int ret;
    struct device *dev_ret;

    if((ret = alloc_chrdev_region(&dev, FIRST_MINOR, MINOR_CNT, EGL_SYSLOGGER_NAME)))
        return ret;

    cdev_init(&c_dev, &syslog_EGL_fops);

    if((ret = cdev_add(&c_dev, dev, MINOR_CNT)) < 0)
        return ret;

    if(IS_ERR( cl = class_create(THIS_MODULE, EGL_SYSLOGGER_NAME "char")))
    {
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(cl);
    }

    cl->devnode = device_node;

    if(IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, EGL_SYSLOGGER_NAME)))
    {
        class_destroy(cl);
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(cl);
    }

    return 0;
}

And similarly using a misc dev with .mode=0666 I have the same problem

static struct miscdevice misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = EGL_SYSLOGGER_NAME,
    .fops = &syslog_EGL_fops,
    /** .mode = S_IRWXUGO, */
    .mode = 0666,
};

static `enter code here`int IOctlInit(void)
{
    int ret;

    ret = misc_register(&misc_dev);
    if(ret)
        printk("Unable to register EGL IOctl misc dev\n");
    printk("Misc dev registered\n");

    return 0;
}

Both approaches work once running chmod 666 /dev/$EGL_SYSLOGGER_NAME but I am hoping to find a solution that does not need this intervention. According to this post the misc dev approach should solve my problem but I have not had any success.

I am not sure what I have missed and would greatly appreciate some tips.

Cheers

Convert string with time data to rtc_time structure in Linux kernel

$
0
0

I can easily convert kernel data type struct rtc_time to string with help sprintf(), but I can't do reverse operation:

 string "Thu Aug 23 14:55:02 2001" to rtc_time structure

Should I write my own realisation if strptime() function into my kernel module?

Could anyone prompt me?

Driver binding using device tree without compatible string in the driver

$
0
0

I saw one scenario where "struct of_device_id" is not defined in the driver, but in the device tree(dts) file compatible string added for the same device entry.

Following is the sample device tree entry for the chip.

&i2c1 {

    ...

    adv7ex: adv7ex@4a {
            compatible = "adv7ex";
            reg = <0x4a>;
    };

    ...

 };

Following is sample code snippet for the driver of the chip which is registering as a I2C driver.

static struct i2c_device_id adv7ex_id[] = {
    { "adv7ex", ADV7EX },
    { }
};
MODULE_DEVICE_TABLE(i2c, adv7ex_id);

static struct i2c_driver adv7ex_driver = {
    .driver = {
        .owner = THIS_MODULE,
        .name = "adv7ex",
    },
    .probe = adv7ex_probe,
    .remove = adv7ex_remove,
    .id_table = adv7ex_id,
};

module_i2c_driver(adv7ex_driver);

Could you please help me to understand how device to driver binding is happened in this case as there no "of_device_id" structure definition in the driver.

mmap, msync and linux process termination

$
0
0

I want to use mmap to implement persistence of certain portions of program state in a C program running under Linux by associating a fixed-size struct with a well known file name using mmap() with the MAP_SHARED flag set. For performance reasons, I would prefer not to call msync() at all, and no other programs will be accessing this file. When my program terminates and is restarted, it will map the same file again and do some processing on it to recover the state that it was in before the termination. My question is this: if I never call msync() on the file descriptor, will the kernel guarantee that all updates to the memory will get written to disk and be subsequently recoverable even if my process is terminated with SIGKILL? Also, will there be general system overhead from the kernel periodically writing the pages to disk even if my program never calls msync()?

EDIT: I've settled the problem of whether the data is written, but I'm still not sure about whether this will cause some unexpected system loading over trying to handle this problem with open()/write()/fsync() and taking the risk that some data might be lost if the process gets hit by KILL/SEGV/ABRT/etc. Added a 'linux-kernel' tag in hopes that some knowledgeable person might chime in.


How to remove conntrack entry from within Linux kernel?

$
0
0

I need to delete a conntrack entry in the kernel. There are numerous functions like nf_ct_delete and nf_ct_put. At the moment I use both on a skb->nfct (block on every tracked skb). It seems to work fine at first, but after some seconds the kernel just crashes.

My current code is as follows:

struct nf_conntrack *con = skb->nfct;
nf_conntrack_get(sub_conntrack);
//... do some stuff 
nf_ct_delete((struct nf_conn *) con, 0, 0);
nf_ct_put((struct nf_conn *) con);

Directly after execution of the delete and put statement, I check the entries with conntrack -L conntrack and they are gone (as expected). But after one minute or so, the system freezes. I guess conntrack starts some timers that crash when fired.

So my question is: How can I immediately delete everything for a specific connection? Including stopping any timers and cleaning up all state.

How Linux arm64 switch between AArch32 and AArch64

$
0
0

Linux supports running 32-bit application, as long as

  1. kernel enables CONFIG_COMPAT
  2. the hardware supports the AArch32

I assume that 32-bit application must run in arm AArch32 execution state and if the environment has 32-bit application and 64-bit application.

32-bit application process -> arm state is AArch32

64-bit application process and kernel -> arm state is AArch64

Is it correct?

If so,
how does the Linux handle the AArch32 and AArch64 switch?
Does the kernel know the running process is 32-bit or 64-bit?

Is Alpine Linux an implementation of a Unikernel?

$
0
0

I've been reading a lot about Docker containers and Unikernels and how to run lightweight environment with my own applications.

I understand that Linux containers and Unikernels are different things, as the first are implementations of kernel features (such as namespaces, cgroups, etc) sharing resources with the host's OS, and the later are independent specialised library operating systems built around applications.

But then I've stumbled upon Alpine linux derived images in Dockerhub. They are very lightweight and very specialized. But do they run around the same LXC/runc features?

Is it possible to run a unikernel under a hypervisor implementation using Docker?

What is the diference between Alpine images and the others?

Get NFS client IP address in a kernel module

$
0
0

I'm working on a kernel module to track the operations performed by NFS clients on my server. I can intercept the file operations using a hacky way (hijacking the vfs layer) but I can't retrieve the IP address of the client.

Is there any information that might be stored in the current task that I can use to obtain the IP address of the NFS client performing an operation?

I know from digging into the source code that nfsd stores a struct nfsd_net in the struct super_block's s_fs_info field, but I can only retrieve it as a struct net pointer. And in nfsd's implementation net_generic method is being used to get the struct nfsd_net pointer (using nfsd_net_id which is the pernet_operations's id).

Can I obtain this id somehow? and if yes, can I use the struct nfsd_net in my kernel module? Is it defined somewhere other than the fs/nfsd/netns.h?

Edit

I'm using this approach to hijack the open function. I'm writing this for kernel version 4.15.0. Here's the code of the kernel module:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/proc_fs.h>
#include <linux/cred.h>
#include <linux/sched.h>
#include <linux/preempt.h>
#include <linux/uaccess.h>
#include <linux/xattr.h>

MODULE_LICENSE("GPL");

#if defined(__i386__)
    #define POFF 1
    #define CSIZE 6
    // push address, addr, ret
    char *jmp_code="\x68\x00\x00\x00\x00\xc3";
    typedef unsigned int PSIZE;
#else
    #define POFF 2
    #define CSIZE 12
    // mov address to register rax, jmp rax. for normal x64 convention
    char *jmp_code="\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe0";
    typedef unsigned long PSIZE;
#endif

DEFINE_SPINLOCK(root_open_lock);

int (*orig_root_open) (struct inode *, struct file *);
void *orig_root_open_code;

void hook(void *src_func,void *dst_addr){
  barrier();
  write_cr0(read_cr0() & (~0x10000));
  memcpy(src_func,jmp_code,CSIZE);
  *(PSIZE *)&(((unsigned char*)src_func)[POFF])=(PSIZE)dst_addr;
  write_cr0(read_cr0() | 0x10000);
  barrier();
}

void save_and_hook(void **p_reserve,void *src_func,void *dst_addr){
  barrier();
  write_cr0(read_cr0() & (~0x10000));
  *p_reserve=kmalloc(CSIZE,GFP_KERNEL);
  // save origin code
  memcpy(*p_reserve,src_func,CSIZE);
  hook(src_func,dst_addr);
  write_cr0(read_cr0() | 0x10000);
  barrier();
}

void fix(void **p_reserve,void *src_func){
  barrier();
  write_cr0(read_cr0() & (~0x10000));
  memcpy(src_func,*p_reserve,CSIZE);
  write_cr0(read_cr0() | 0x10000);
  barrier();
}

int fake_root_open(struct inode *x, struct file *fp)
{
  int ret;

  printk("vfshijack: hijacked open\n"); // I need to find the client ip here.

  barrier();
  spin_lock(&root_open_lock);
  fix(&orig_root_open_code, orig_root_open);
  ret = orig_root_open(x, fp);
  hook(orig_root_open, fake_root_open);
  spin_unlock(&root_open_lock);
  barrier();
  return ret;
}

int vfs_init(void)
{
  struct file *fp = filp_open("/", O_DIRECTORY|O_RDONLY, 0);
  if (IS_ERR(fp))
    return -1;

  orig_root_open = fp->f_op->open;
  if(orig_root_open)
  {
    save_and_hook(&orig_root_open_code, orig_root_open, fake_root_open);
  }

  filp_close(fp, NULL);

  printk("vfshijack: vfshijack loaded\n");
  return 0;
}

void vfs_exit(void)
{
  if(orig_root_open)
  {
    fix(&orig_root_open_code, orig_root_open);
  }
  printk("vfshijack: vfshijack unloaded\n");
}

module_init(vfs_init);
module_exit(vfs_exit);

Why Linux distro Debian is the best linux distro for programmers? [closed]

$
0
0

I searched in several forums for user feedback about Linux distributions, why most of the forum people say Debian is best for programming?

Viewing all 12204 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>