diff options
Diffstat (limited to 'module/splat')
-rw-r--r-- | module/splat/Makefile.in | 1 | ||||
-rw-r--r-- | module/splat/splat-cred.c | 247 | ||||
-rw-r--r-- | module/splat/splat-ctl.c | 2 | ||||
-rw-r--r-- | module/splat/splat-internal.h | 3 |
4 files changed, 253 insertions, 0 deletions
diff --git a/module/splat/Makefile.in b/module/splat/Makefile.in index c2d4c3f22..2f63b458a 100644 --- a/module/splat/Makefile.in +++ b/module/splat/Makefile.in @@ -20,3 +20,4 @@ splat-objs += splat-kobj.o splat-objs += splat-atomic.o splat-objs += splat-list.o splat-objs += splat-generic.o +splat-objs += splat-cred.o diff --git a/module/splat/splat-cred.c b/module/splat/splat-cred.c new file mode 100644 index 000000000..f808625e8 --- /dev/null +++ b/module/splat/splat-cred.c @@ -0,0 +1,247 @@ +/* + * This file is part of the SPL: Solaris Porting Layer. + * + * Copyright (c) 2009 Lawrence Livermore National Security, LLC. + * Produced at Lawrence Livermore National Laboratory + * Written by: + * Brian Behlendorf <[email protected]>, + * UCRL-CODE-235197 + * + * This 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 is distributed in the hope that it will 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 to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "splat-internal.h" + +#define SPLAT_CRED_NAME "cred" +#define SPLAT_CRED_DESC "Kernel Cred Tests" + +#define SPLAT_CRED_TEST1_ID 0x0e01 +#define SPLAT_CRED_TEST1_NAME "cred" +#define SPLAT_CRED_TEST1_DESC "Task Credential Test" + +#define SPLAT_CRED_TEST2_ID 0x0e02 +#define SPLAT_CRED_TEST2_NAME "kcred" +#define SPLAT_CRED_TEST2_DESC "Kernel Credential Test" + +#define SPLAT_CRED_TEST3_ID 0x0e03 +#define SPLAT_CRED_TEST3_NAME "groupmember" +#define SPLAT_CRED_TEST3_DESC "Group Member Test" + +#define GROUP_STR_SIZE 128 +#define GROUP_STR_REDZONE 16 + +static int +splat_cred_test1(struct file *file, void *arg) +{ + char str[GROUP_STR_SIZE]; + uid_t uid, ruid, suid; + gid_t gid, rgid, sgid, *groups; + int ngroups, i, count = 0; + + uid = crgetuid(CRED()); + ruid = crgetruid(CRED()); + suid = crgetsuid(CRED()); + + gid = crgetgid(CRED()); + rgid = crgetrgid(CRED()); + sgid = crgetsgid(CRED()); + + crhold(CRED()); + ngroups = crgetngroups(CRED()); + groups = crgetgroups(CRED()); + + memset(str, 0, GROUP_STR_SIZE); + for (i = 0; i < ngroups; i++) { + count += sprintf(str + count, "%d ", groups[i]); + + if (count > (GROUP_STR_SIZE - GROUP_STR_REDZONE)) { + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "Failed too many group entries for temp " + "buffer: %d, %s\n", ngroups, str); + return -ENOSPC; + } + } + + crfree(CRED()); + + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "uid: %d ruid: %d suid: %d " + "gid: %d rgid: %d sgid: %d\n", + uid, ruid, suid, gid, rgid, sgid); + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "ngroups: %d groups: %s\n", ngroups, str); + + if (uid || ruid || suid || gid || rgid || sgid) { + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "Failed expected all uids+gids to be %d\n", 0); + return -EIDRM; + } + + if (ngroups > NGROUPS_MAX) { + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "Failed ngroups must not exceed NGROUPS_MAX: " + "%d > %d\n", ngroups, NGROUPS_MAX); + return -EIDRM; + } + + splat_vprint(file, SPLAT_CRED_TEST1_NAME, + "Success sane CRED(): %d\n", 0); + + return 0; +} /* splat_cred_test1() */ + +static int +splat_cred_test2(struct file *file, void *arg) +{ + char str[GROUP_STR_SIZE]; + uid_t uid, ruid, suid; + gid_t gid, rgid, sgid, *groups; + int ngroups, i, count = 0; + + uid = crgetuid(kcred); + ruid = crgetruid(kcred); + suid = crgetsuid(kcred); + + gid = crgetgid(kcred); + rgid = crgetrgid(kcred); + sgid = crgetsgid(kcred); + + crhold(kcred); + ngroups = crgetngroups(kcred); + groups = crgetgroups(kcred); + + memset(str, 0, GROUP_STR_SIZE); + for (i = 0; i < ngroups; i++) { + count += sprintf(str + count, "%d ", groups[i]); + + if (count > (GROUP_STR_SIZE - GROUP_STR_REDZONE)) { + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "Failed too many group entries for temp " + "buffer: %d, %s\n", ngroups, str); + return -ENOSPC; + } + } + + crfree(kcred); + + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "uid: %d ruid: %d suid: %d " + "gid: %d rgid: %d sgid: %d\n", + uid, ruid, suid, gid, rgid, sgid); + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "ngroups: %d groups: %s\n", ngroups, str); + + if (uid || ruid || suid || gid || rgid || sgid) { + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "Failed expected all uids+gids to be %d\n", 0); + return -EIDRM; + } + + if (ngroups > NGROUPS_MAX) { + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "Failed ngroups must not exceed NGROUPS_MAX: " + "%d > %d\n", ngroups, NGROUPS_MAX); + return -EIDRM; + } + + splat_vprint(file, SPLAT_CRED_TEST2_NAME, + "Success sane kcred: %d\n", 0); + + return 0; +} /* splat_cred_test2() */ + +/* + * On most/all systems it can be expected that a task with root + * permissions also is a member of the root group, Since the + * test suite is always run as root we check first that CRED() is + * a member of the root group, and secondly that it is not a member + * of our fake group. This test will break is someone happens to + * create group number NGROUPS_MAX-1 and then added root to it. + */ +static int +splat_cred_test3(struct file *file, void *arg) +{ + gid_t root_gid, fake_gid; + int rc; + + root_gid = 0; + fake_gid = NGROUPS_MAX-1; + + rc = groupmember(root_gid, CRED()); + if (!rc) { + splat_vprint(file, SPLAT_CRED_TEST3_NAME, + "Failed root git %d expected to be member " + "of CRED() groups: %d\n", root_gid, rc); + return -EIDRM; + } + + rc = groupmember(fake_gid, CRED()); + if (rc) { + splat_vprint(file, SPLAT_CRED_TEST3_NAME, + "Failed fake git %d expected not to be member " + "of CRED() groups: %d\n", fake_gid, rc); + return -EIDRM; + } + + splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Success root gid " + "is a member of the expected groups: %d\n", rc); + + return rc; +} /* splat_cred_test3() */ + +splat_subsystem_t * +splat_cred_init(void) +{ + splat_subsystem_t *sub; + + sub = kmalloc(sizeof(*sub), GFP_KERNEL); + if (sub == NULL) + return NULL; + + memset(sub, 0, sizeof(*sub)); + strncpy(sub->desc.name, SPLAT_CRED_NAME, SPLAT_NAME_SIZE); + strncpy(sub->desc.desc, SPLAT_CRED_DESC, SPLAT_DESC_SIZE); + INIT_LIST_HEAD(&sub->subsystem_list); + INIT_LIST_HEAD(&sub->test_list); + spin_lock_init(&sub->test_lock); + sub->desc.id = SPLAT_SUBSYSTEM_CRED; + + SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST1_NAME, SPLAT_CRED_TEST1_DESC, + SPLAT_CRED_TEST1_ID, splat_cred_test1); + SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST2_NAME, SPLAT_CRED_TEST2_DESC, + SPLAT_CRED_TEST2_ID, splat_cred_test2); + SPLAT_TEST_INIT(sub, SPLAT_CRED_TEST3_NAME, SPLAT_CRED_TEST3_DESC, + SPLAT_CRED_TEST3_ID, splat_cred_test3); + + return sub; +} /* splat_cred_init() */ + +void +splat_cred_fini(splat_subsystem_t *sub) +{ + ASSERT(sub); + + SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST3_ID); + SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST2_ID); + SPLAT_TEST_FINI(sub, SPLAT_CRED_TEST1_ID); + + kfree(sub); +} /* splat_cred_fini() */ + +int +splat_cred_id(void) +{ + return SPLAT_SUBSYSTEM_CRED; +} /* splat_cred_id() */ diff --git a/module/splat/splat-ctl.c b/module/splat/splat-ctl.c index c8925636a..159103980 100644 --- a/module/splat/splat-ctl.c +++ b/module/splat/splat-ctl.c @@ -630,6 +630,7 @@ splat_init(void) SPLAT_SUBSYSTEM_INIT(atomic); SPLAT_SUBSYSTEM_INIT(list); SPLAT_SUBSYSTEM_INIT(generic); + SPLAT_SUBSYSTEM_INIT(cred); dev = MKDEV(SPLAT_MAJOR, 0); if ((rc = register_chrdev_region(dev, SPLAT_MINORS, SPLAT_NAME))) @@ -676,6 +677,7 @@ splat_fini(void) cdev_del(&splat_cdev); unregister_chrdev_region(dev, SPLAT_MINORS); + SPLAT_SUBSYSTEM_FINI(cred); SPLAT_SUBSYSTEM_FINI(generic); SPLAT_SUBSYSTEM_FINI(list); SPLAT_SUBSYSTEM_FINI(atomic); diff --git a/module/splat/splat-internal.h b/module/splat/splat-internal.h index 0fa177c02..c1c84d8d1 100644 --- a/module/splat/splat-internal.h +++ b/module/splat/splat-internal.h @@ -208,6 +208,7 @@ splat_subsystem_t *splat_kobj_init(void); splat_subsystem_t *splat_atomic_init(void); splat_subsystem_t *splat_list_init(void); splat_subsystem_t *splat_generic_init(void); +splat_subsystem_t *splat_cred_init(void); void splat_condvar_fini(splat_subsystem_t *); void splat_kmem_fini(splat_subsystem_t *); @@ -222,6 +223,7 @@ void splat_kobj_fini(splat_subsystem_t *); void splat_atomic_fini(splat_subsystem_t *); void splat_list_fini(splat_subsystem_t *); void splat_generic_fini(splat_subsystem_t *); +void splat_cred_fini(splat_subsystem_t *); int splat_condvar_id(void); int splat_kmem_id(void); @@ -236,5 +238,6 @@ int splat_kobj_id(void); int splat_atomic_id(void); int splat_list_id(void); int splat_generic_id(void); +int splat_cred_id(void); #endif /* _SPLAT_INTERNAL_H */ |