Test checks kernel API to safely access user-space memory using
copy_to_user(), copy_from_user(), get_user(), put_user() functions.

Signed-off-by: Alexey Kodanev <[email protected]>
---
 testcases/kernel/device-drivers/uaccess/.gitignore |    8 +
 testcases/kernel/device-drivers/uaccess/Makefile   |   33 +++++
 .../kernel/device-drivers/uaccess/ltp_uaccess.c    |  140 ++++++++++++++++++++
 .../kernel/device-drivers/uaccess/ltp_uaccess.h    |   32 +++++
 testcases/kernel/device-drivers/uaccess/uaccess.c  |  121 +++++++++++++++++
 5 files changed, 334 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/device-drivers/uaccess/.gitignore
 create mode 100644 testcases/kernel/device-drivers/uaccess/Makefile
 create mode 100644 testcases/kernel/device-drivers/uaccess/ltp_uaccess.c
 create mode 100644 testcases/kernel/device-drivers/uaccess/ltp_uaccess.h
 create mode 100644 testcases/kernel/device-drivers/uaccess/uaccess.c

diff --git a/testcases/kernel/device-drivers/uaccess/.gitignore 
b/testcases/kernel/device-drivers/uaccess/.gitignore
new file mode 100644
index 0000000..cf59b68
--- /dev/null
+++ b/testcases/kernel/device-drivers/uaccess/.gitignore
@@ -0,0 +1,8 @@
+/ltp_uaccess.ko
+/uaccess
+/*.mod.c
+/modules.order
+/.tmp_versions
+/.*.ko
+/.*.cmd
+/Module.symvers
diff --git a/testcases/kernel/device-drivers/uaccess/Makefile 
b/testcases/kernel/device-drivers/uaccess/Makefile
new file mode 100644
index 0000000..b0e50e8
--- /dev/null
+++ b/testcases/kernel/device-drivers/uaccess/Makefile
@@ -0,0 +1,33 @@
+# Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := ltp_uaccess.o
+
+else
+
+top_srcdir     ?= ../../../..
+include $(top_srcdir)/include/mk/testcases.mk
+
+REQ_VERSION_MAJOR      := 2
+REQ_VERSION_PATCH      := 6
+MAKE_TARGETS           := uaccess ltp_uaccess.ko
+
+include $(top_srcdir)/include/mk/module.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/device-drivers/uaccess/ltp_uaccess.c 
b/testcases/kernel/device-drivers/uaccess/ltp_uaccess.c
new file mode 100644
index 0000000..e628ba9
--- /dev/null
+++ b/testcases/kernel/device-drivers/uaccess/ltp_uaccess.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Alexey Kodanev <[email protected]>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <asm-generic/uaccess.h>
+#include "ltp_uaccess.h"
+
+MODULE_AUTHOR("Alexey Kodanev <[email protected]>");
+MODULE_DESCRIPTION("User-space access LTP test");
+MODULE_LICENSE("GPL");
+
+#define prk_err(fmt, ...) \
+       pr_err(DEV_NAME ": " fmt "\n", ##__VA_ARGS__)
+#define prk_info(fmt, ...) \
+       pr_info(DEV_NAME ": " fmt "\n", ##__VA_ARGS__)
+
+/*
+ * Test-case result,
+ * if test is passed, value will be set to 0
+ */
+static int test_result;
+
+static void device_release(struct device *dev)
+{
+       prk_info("device released");
+}
+
+static struct device tdev = {
+       .init_name      = DEV_NAME,
+       .release        = device_release
+};
+
+static ssize_t sys_result(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%d\n", test_result);
+}
+static DEVICE_ATTR(result, S_IRUSR, sys_result, NULL);
+
+
+static ssize_t sys_tcase(struct device *dev,
+       struct device_attribute *attr,  const char *buf, size_t count)
+{
+       unsigned long ptr = 0;
+       int tc = 0;
+       char *str, ch, buffer[str_size];
+
+       sscanf(buf, "%d %lu", &tc, &ptr);
+       str = (char *) ptr;
+       test_result = 0;
+
+       switch (tc) {
+       case TC_READ_USER:
+               if (copy_from_user(buffer, str, str_size))
+                       prk_err("copy_from_user() failed");
+               test_result = strncmp(test_str, buffer, str_size) ? 1 : 0;
+               if (get_user(ch, str))
+                       prk_err("get_user() failed");
+               test_result |= ch != test_str[0];
+       break;
+       case TC_WRITE_USER:
+               if (copy_to_user(str + 1, test_str + 1, str_size - 1)) {
+                       prk_err("copy_to_user() failed");
+                       test_result = 1;
+               }
+               /* write the first skipped character */
+               if (put_user(test_str[0], str)) {
+                       prk_err("put_user() failed");
+                       test_result |= 1;
+               }
+       break;
+       }
+
+       return count;
+}
+static DEVICE_ATTR(tcase, S_IWUSR, NULL, sys_tcase);
+
+static int uaccess_init(void)
+{
+       int err = 0;
+       prk_info("Starting module");
+
+       err = device_register(&tdev);
+       if (err) {
+               prk_err("Unable to register device");
+               goto err0;
+       }
+       prk_info("device registered");
+
+       err = device_create_file(&tdev, &dev_attr_result);
+       if (err) {
+               prk_err("Can't create sysfs file 'result'");
+               goto err1;
+       }
+
+       err = device_create_file(&tdev, &dev_attr_tcase);
+       if (err) {
+               prk_err(": Can't create sysfs file 'tc'");
+               goto err2;
+       }
+
+       return 0;
+
+err2:
+       device_remove_file(&tdev, &dev_attr_result);
+err1:
+       device_unregister(&tdev);
+err0:
+       return err;
+}
+module_init(uaccess_init)
+
+static void uaccess_exit(void)
+{
+       prk_info("Unloading module");
+
+       device_remove_file(&tdev, &dev_attr_result);
+       device_remove_file(&tdev, &dev_attr_tcase);
+       device_unregister(&tdev);
+}
+module_exit(uaccess_exit)
diff --git a/testcases/kernel/device-drivers/uaccess/ltp_uaccess.h 
b/testcases/kernel/device-drivers/uaccess/ltp_uaccess.h
new file mode 100644
index 0000000..90141c9
--- /dev/null
+++ b/testcases/kernel/device-drivers/uaccess/ltp_uaccess.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef LTP_UACCESS_H
+#define LTP_UACCESS_H
+
+#define DEV_NAME "ltp_uaccess"
+
+static const char test_str[]   = "Test string";
+static const int str_size      = sizeof(test_str) + 1;
+
+enum {
+       TC_READ_USER = 0,
+       TC_WRITE_USER
+};
+
+#endif /* LTP_UACCESS_H */
diff --git a/testcases/kernel/device-drivers/uaccess/uaccess.c 
b/testcases/kernel/device-drivers/uaccess/uaccess.c
new file mode 100644
index 0000000..e0fe7d9
--- /dev/null
+++ b/testcases/kernel/device-drivers/uaccess/uaccess.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Alexey Kodanev <[email protected]>
+ *
+ * Test checks kernel API to safely access user-space memory using
+ * copy_to_user(), copy_from_user(), get_user(), put_user() functions.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "tst_module.h"
+#include "safe_macros.h"
+#include "safe_stdio.h"
+
+#include "ltp_uaccess.h"
+
+char *TCID = DEV_NAME;
+
+static const char dev_result[] = "/sys/devices/" DEV_NAME "/result";
+static const char dev_tcase[]  = "/sys/devices/" DEV_NAME "/tcase";
+static const char module_name[]        = DEV_NAME ".ko";
+static int module_loaded;
+
+static void cleanup(void)
+{
+       if (module_loaded)
+               tst_module_unload(NULL, module_name);
+
+       TEST_CLEANUP;
+}
+
+static int set_ptr_to_sysfs(int id, const void *ptr, const char *descr)
+{
+       int res;
+       tst_resm(TINFO, "TC %d: %s, ptr '%p'", id, descr, ptr);
+       SAFE_FILE_PRINTF(cleanup, dev_tcase, "%d %lu", id, (unsigned long) ptr);
+       SAFE_FILE_SCANF(cleanup, dev_result, "%d", &res);
+       if (res)
+               return TFAIL;
+
+       return TPASS;
+}
+
+/*
+ * Read user-space memory using copy_from_user(), get_user().
+ */
+static void tc_read_userspace(void)
+{
+       int res = set_ptr_to_sysfs(TC_READ_USER, test_str,
+               "read user-space memory from kernel");
+
+       tst_resm(res, "copy_from_user(), get_user(): strings%sequal",
+               (res) ? " not " : " ");
+}
+
+/*
+ * Write from kernel-space to user-space
+ * using copy_to_user(), put_user().
+ */
+static void tc_write_userspace(void)
+{
+       char buf[str_size];
+       memset(buf, 0, str_size);
+
+       int res = set_ptr_to_sysfs(TC_WRITE_USER, buf,
+               "write from kernel-space to user-space");
+       if (res) {
+               tst_resm(TFAIL, "failed to write from kernel");
+               return;
+       }
+
+       res = strncmp(buf, test_str, str_size) ? TFAIL : TPASS;
+       tst_resm(res, "copy_to_user(), put_user(): strings%sequal",
+               (res) ? " not " : " ");
+}
+
+int main(int argc, char *argv[])
+{
+       char *msg;
+       msg = parse_opts(argc, argv, NULL, NULL);
+       if (msg != NULL)
+               tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+       tst_require_root(NULL);
+
+       if (tst_kvercmp(2, 6, 0) < 0) {
+               tst_brkm(TCONF, NULL,
+                       "Test must be run with kernel 2.6 or newer");
+       }
+
+       tst_sig(FORK, DEF_HANDLER, cleanup);
+
+       tst_module_load(NULL, module_name, NULL);
+       module_loaded = 1;
+
+       tc_read_userspace();
+       tc_write_userspace();
+
+       cleanup();
+       tst_exit();
+}
-- 
1.7.1


------------------------------------------------------------------------------
Sponsored by Intel(R) XDK 
Develop, test and display web and hybrid apps with a single code base.
Download it for free now!
http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to