Reputation: 65
In Ubuntu 16.04 kernel version 4.4, the loadable kernel module has the following behavior:
(Use string literal)
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/fs.h>
static int __init myinit(void)
{
char *path_name = "~/microsoft.gpg";
struct path path;
printk("Module Init\n");
if (kern_path(path_name, LOOKUP_FOLLOW, &path) < 0)
{
printk("kern_path fail\n");
return 0;
}
printk("kern_path success\n");
return 0;
}
static void __exit myexit(void)
{
printk("Module Exit\n");
return;
}
module_init(myinit);
module_exit(myexit);
MODULE_LICENSE("GPL");
The result of dmesg is
Module Init
kern_path success
(Use string variable)
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#define MAX_PATH_LEN 256
static char path_name[MAX_PATH_LEN];
static struct proc_dir_entry *proc_file;
static int myopen(struct inode *inode, struct file *file)
{
printk("Module Open\n");
return 0;
}
static ssize_t mywrite(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos)
{
struct path path;
ssize_t bytes = count < (MAX_PATH_LEN - (*ppos)) ? count : (MAX_PATH_LEN - (*ppos));
if (copy_from_user(path_name, user_buffer, bytes))
return -EFAULT;
path_name[bytes] = '\0';
printk("Module Write\n");
if (kern_path(path_name, LOOKUP_FOLLOW, &path) < 0)
{
printk("kern_path fail\n");
(*ppos) += bytes;
return bytes;
}
printk("kern_path success\n");
(*ppos) += bytes;
return bytes;
}
static const struct file_operations fops =
{
.owner = THIS_MODULE,
.open = myopen,
.write = mywrite,
};
static int __init myinit(void)
{
printk("Module Init\n");
proc_file = proc_create("mymodule", 0644, NULL, &fops);
return 0;
}
static void __exit myexit(void)
{
printk("Module Exit\n");
remove_proc_entry("mymodule", NULL);
return;
}
module_init(myinit);
module_exit(myexit);
MODULE_LICENSE("GPL");
Commands entered in the shell are
echo ~/microsoft.gpg > /proc/mymodule
The result of dmesg is
Module Init
Module Open
Module Write
kern_path fail
I did not have a similar problem when writing user application code, but I am really embarrassed because there is a problem with the kernel module.
Why did the problem appear in the second code? How do I fix it?
Answer completed
Upvotes: 1
Views: 511
Reputation: 65898
Mainly used for write into a "kernel file", echo
command appends newline symbol at the end of the string (this is explicitly mentioned in the documentation for echo
).
Kernel module can easily process this case by discarding the last input symbol if it is newline:
if(path_name[bytes - 1] == '\n')
path_name[bytes - 1] = '\0';
Upvotes: 1
Reputation: 65
In comments, @Tsyvarev gave me the correct answer. The string I pass to echo contains a newline character. I put the -n option and removed it.
Thanks, @Tsyvarev!
Upvotes: 0