在内核模块中调用sock_sendmsg会返回(-1)权限被拒绝

时间:2017-11-17 01:59:19

标签: c sockets linux-kernel

我正在研究驱动程序,我需要从内核发送UDP数据包。当我在VM中运行它时,一切都很好并且数据包被发送出去。但是,当我直接在硬件上运行时,sock_sendmsg()返回-1。

我在两个环境中使用内核版本4.13.0-kali1-amd64在Kali Linux上运行。它们是从Kali Linux 2017.2构建的,所有软件包都是最新的。

sockDenied.c:

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>


#include <linux/uaccess.h>        // for get_fs, get_ds, set_fs
#include <linux/inet.h>           // for in4_pton
#include <net/sock.h>             // for IPPROTO_IP, SOCK_DGRAM, AF_INET
#include <linux/net.h>            // for sock_create, sock_alloc_file


MODULE_AUTHOR("helpme");
MODULE_DESCRIPTION("sock_sendmsg recieving permission denied");
MODULE_LICENSE("GPL");



//////////////////////////////////////////////////////////////////////////////
//      Global Variables
//////////////////////////////////////////////////////////////////////////////

static mm_segment_t _oldfs;

int my_inet_pton(int af, const char *src, void *dst) {
    printk("In %s", __FUNCTION__);
    if (AF_INET == af) {
        return in4_pton(src, strlen(src), (u8*) dst, '\0', NULL);
    } else if (AF_INET6 == af) {
        return in6_pton(src, strlen(src), (u8*) dst, '\0', NULL);
    } else {
        printk("uknown af value = %d", af);
        return -1;
    }
}

//////////////////////////////////////////////////////////////////////////////
//
//      Static Functions : UDP
//
//////////////////////////////////////////////////////////////////////////////

static int __init sockdenied_init(void) {    
    int retval = 0;
    struct msghdr msg = {};
    struct iovec iov = {};
    char data[2] = {0x01, 0x02};
    static struct sockaddr_in txaddr = {};

    struct socket* sock = NULL;
    struct file* fp = NULL;
    u32 dstip;

    _oldfs = get_fs();
    set_fs(KERNEL_DS);

    retval = my_inet_pton(AF_INET, "1.1.1.1", &dstip);

    retval = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_IP, &sock);
    fp = sock_alloc_file(sock, 0, NULL);

    txaddr.sin_family = AF_INET;
    txaddr.sin_addr.s_addr = dstip;
    txaddr.sin_port = htons(50000);

    iov.iov_base = data;
    iov.iov_len = 2;

    iov_iter_init(&msg.msg_iter, READ, &iov, 1, 1);

    msg.msg_flags = 0;
    msg.msg_name = &(txaddr);
    msg.msg_namelen = sizeof (struct sockaddr_in);
    msg.msg_control = NULL;
    msg.msg_controllen = 0;

    retval = sock_sendmsg(sock, &msg);

    printk(KERN_INFO"sock_sendmsg returned: %d", retval);

    sock_release(sock);

    return 0;
}

static void __exit sockdenied_exit(void) {

    set_fs(_oldfs);

    return;
}

module_init(sockdenied_init);
module_exit(sockdenied_exit);

生成文件:

obj-m+=sockDenied.o
MY_CFLAGS+= -g -DDEBUG
ccflags-y+= ${MY_CFLAGS}
CC += ${MY_CFLAGS}

all:
    make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD)  modules
    EXTRA_CFLAGS="$(MY_CFLAGS)"
clean:
    make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean

我为什么要收到-EPERM?我的模块怎么没有permssion发送UDP数据包?为什么VM的行为方式不同。

0 个答案:

没有答案