From 9f516c2214db4dc515ac817ec3379a9765202d3e Mon Sep 17 00:00:00 2001 From: ericm Date: Tue, 27 Apr 2004 21:41:24 +0000 Subject: [PATCH 1/1] liblustre: b=2862 - use real uid/gid instead of simply be as root - set group info - set capability info --- lustre/include/liblustre.h | 18 ++++-- lustre/liblustre/genlib.sh | 2 +- lustre/liblustre/llite_lib.c | 116 ++++++++++++++++++++++++++++++++----- lustre/liblustre/namei.c | 10 +++- lustre/liblustre/super.c | 10 +++- lustre/liblustre/tests/Makefile.am | 4 +- lustre/liblustre/tests/echo_test.c | 5 ++ lustre/obdecho/echo_client.c | 1 + 8 files changed, 138 insertions(+), 28 deletions(-) diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index af80f44..30d9574 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -116,9 +116,6 @@ static inline void *kmalloc(int size, int prot) #define PTR_ERR(a) ((long)(a)) #define ERR_PTR(a) ((void*)((long)(a))) -#define capable(foo) 1 -#define CAP_SYS_ADMIN 1 - typedef struct { void *cwd; }mm_segment_t; @@ -578,12 +575,23 @@ struct task_struct { int pid; int fsuid; int fsgid; + int max_groups; + int ngroups; + gid_t *groups; __u32 cap_effective; + + struct fs_struct __fs; }; extern struct task_struct *current; - -#define in_group_p(a) 0 /* FIXME */ +int in_group_p(gid_t gid); +static inline int capable(int cap) +{ + if (current->cap_effective & (1 << cap)) + return 1; + else + return 0; +} #define set_current_state(foo) do { current->state = foo; } while (0) diff --git a/lustre/liblustre/genlib.sh b/lustre/liblustre/genlib.sh index f371650..c31ea2f 100755 --- a/lustre/liblustre/genlib.sh +++ b/lustre/liblustre/genlib.sh @@ -83,6 +83,6 @@ $RANLIB $CWD/liblustre.a # create shared lib lustre rm -f $CWD/liblustre.so $LD -shared -o $CWD/liblustre.so -init __liblustre_setup_ -fini __liblustre_cleanup_ \ - $ALL_OBJS -lpthread + $ALL_OBJS -lcap -lpthread #rm -rf $sysio_tmp diff --git a/lustre/liblustre/llite_lib.c b/lustre/liblustre/llite_lib.c index bd000bb..2dddb2f 100644 --- a/lustre/liblustre/llite_lib.c +++ b/lustre/liblustre/llite_lib.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -99,18 +100,112 @@ char *portals_nid2str(int nal, ptl_nid_t nid, char *str) return str; } -void init_current(char *comm) +int in_group_p(gid_t gid) +{ + int i; + + if (gid == current->fsgid) + return 1; + + for (i = 0; i < current->ngroups; i++) { + if (gid == current->groups[i]) + return 1; + } + + return 0; +} + +static void init_capability(int *res) +{ + cap_value_t cap_types[] = { + CAP_CHOWN, + CAP_DAC_OVERRIDE, + CAP_DAC_READ_SEARCH, + CAP_FOWNER, + CAP_FSETID, + CAP_KILL, + CAP_SETGID, + CAP_SETUID, + /* following are linux specific, we could simply + * remove them I think */ + CAP_SETPCAP, + CAP_LINUX_IMMUTABLE, + CAP_NET_BIND_SERVICE, + CAP_NET_BROADCAST, + CAP_NET_ADMIN, + CAP_NET_RAW, + CAP_IPC_LOCK, + CAP_IPC_OWNER, + CAP_SYS_MODULE, + CAP_SYS_RAWIO, + CAP_SYS_CHROOT, + CAP_SYS_PTRACE, + CAP_SYS_PACCT, + CAP_SYS_ADMIN, + CAP_SYS_BOOT, + CAP_SYS_NICE, + CAP_SYS_RESOURCE, + CAP_SYS_TIME, + CAP_SYS_TTY_CONFIG, + CAP_MKNOD, + CAP_LEASE, + }; + cap_t syscap; + cap_flag_value_t capval; + int i; + + *res = 0; + + syscap = cap_get_proc(); + if (!syscap) { + printf("Liblustre: Warning: failed to get system capability, " + "set to minimal\n"); + return; + } + + for (i = 0; i < sizeof(cap_types)/sizeof(cap_t); i++) { + LASSERT(cap_types[i] < 32); + if (!cap_get_flag(syscap, cap_types[i], + CAP_EFFECTIVE, &capval)) { + if (capval == CAP_SET) { + *res |= 1 << cap_types[i]; + } + } + } +} + +static int init_current(char *comm) { current = malloc(sizeof(*current)); - current->fs = malloc(sizeof(*current->fs)); + if (!current) { + CERROR("Not enough memory\n"); + return -ENOMEM; + } + current->fs = ¤t->__fs; current->fs->umask = umask(0777); umask(current->fs->umask); + strncpy(current->comm, comm, sizeof(current->comm)); current->pid = getpid(); - current->fsuid = 0; - current->fsgid = 0; - current->cap_effective = -1; + current->fsuid = geteuid(); + current->fsgid = getegid(); memset(¤t->pending, 0, sizeof(current->pending)); + + current->max_groups = sysconf(_SC_NGROUPS_MAX); + current->groups = malloc(sizeof(gid_t) * current->max_groups); + if (!current->groups) { + CERROR("Not enough memory\n"); + return -ENOMEM; + } + current->ngroups = getgroups(current->max_groups, current->groqps); + if (current->ngroups < 0) { + perror("Error getgroups"); + return -EINVAL; + } + + init_capability(¤t->cap_effective); + + return 0; } /* FIXME */ @@ -204,8 +299,8 @@ int lllib_init(char *dumpfile) printf("LibLustre: TCPNAL NID: %016llx\n", tcpnal_mynid); } - init_current("dummy"); - if (init_obdclass() || + if (init_current("dummy") || + init_obdclass() || init_lib_portals() || ptlrpc_init() || mdc_init() || @@ -332,11 +427,6 @@ out: RETURN(rc); } -static void sighandler_USR1(int signum) -{ - /* do nothing */ -} - /* parse host:/mdsname/profile string */ int ll_parse_mount_target(const char *target, char **mdsnid, char **mdsname, char **profile) @@ -399,8 +489,6 @@ void __liblustre_setup_(void) */ srand(time(NULL) + getpid()); - signal(SIGUSR1, sighandler_USR1); - lustre_path = getenv(ENV_LUSTRE_MNTPNT); if (!lustre_path) { lustre_path = "/mnt/lustre"; diff --git a/lustre/liblustre/namei.c b/lustre/liblustre/namei.c index 0403ad5..6e596d2 100644 --- a/lustre/liblustre/namei.c +++ b/lustre/liblustre/namei.c @@ -319,7 +319,11 @@ static int lookup_it_finish(struct ptlrpc_request *request, int offset, /* NB 1 request reference will be taken away by ll_intent_lock() * when I return - * Note: libsysio require the inode must be generated here + */ + /* FIXME: for CREAT, libsysio require the inode must be generated here + * currently here we don't know the whether the create is successful + * or failed on mds. thus blinded return -EPERM in llu_iget(). need + * a fix later. */ if ((it->it_op & IT_CREAT) || !it_disposition(it, DISP_LOOKUP_NEG)) { struct lustre_md md; @@ -331,11 +335,11 @@ static int lookup_it_finish(struct ptlrpc_request *request, int offset, RETURN(rc); inode = llu_iget(parent->i_fs, &md); - if (!inode) { + if (!inode || IS_ERR(inode)) { /* free the lsm if we allocated one above */ if (md.lsm != NULL) obd_free_memmd(sbi->ll_osc_exp, &md.lsm); - RETURN(-ENOMEM); + RETURN(inode ? PTR_ERR(inode) : -ENOMEM); } else if (md.lsm != NULL && llu_i2info(inode)->lli_smd != md.lsm) { obd_free_memmd(sbi->ll_osc_exp, &md.lsm); diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 86048e6..de8cf3b 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifndef __CYGWIN__ # include #else @@ -1290,8 +1291,11 @@ struct inode *llu_iget(struct filesys *fs, struct lustre_md *md) if ((md->body->valid & (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) != - (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) - CERROR("invalide fields!\n"); + (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) { + /* FIXME this is workaround for for open(O_CREAT), + * see lookup_it_finish(). */ + return ERR_PTR(-EPERM); + } /* try to find existing inode */ fid.id = md->body->ino; @@ -1490,7 +1494,7 @@ llu_fsswop_mount(const char *source, LASSERT(sbi->ll_rootino != 0); root = llu_iget(fs, &md); - if (root == NULL) { + if (!root || IS_ERR(root)) { CERROR("fail to generate root inode\n"); GOTO(out_request, err = -EBADF); } diff --git a/lustre/liblustre/tests/Makefile.am b/lustre/liblustre/tests/Makefile.am index 81e7058..ff73edf 100644 --- a/lustre/liblustre/tests/Makefile.am +++ b/lustre/liblustre/tests/Makefile.am @@ -4,7 +4,7 @@ AM_CPPFLAGS = -I$(SYSIO)/include -I/opt/lam/include $(LLCPPFLAGS) -I$(top_srcdir AM_CFLAGS = $(LLCFLAGS) LIBS = $(LIBEFENCE) $(LIBREADLINE) -LLIB_EXEC= ../liblustre.a -lpthread +LLIB_EXEC= ../liblustre.a -lcap -lpthread if LIBLUSTRE noinst_LIBRARIES = libtestcommon.a @@ -21,7 +21,7 @@ libtestcommon_a_SOURCES = test_common.c test_common.h echo_test_SOURCES = echo_test.c ../../utils/parser.c ../../utils/obd.c ../../utils/lustre_cfg.c echo_test_CFLAGS = $(LL_CFLAGS) -echo_test_LDADD = ../liblsupport.a $(LIBREADLINE) -lpthread +echo_test_LDADD = ../liblsupport.a $(LIBREADLINE) -lcap -lpthread echo_test_DEPENDENCIES=$(top_builddir)/liblustre/liblsupport.a sanity_SOURCES = sanity.c diff --git a/lustre/liblustre/tests/echo_test.c b/lustre/liblustre/tests/echo_test.c index 139a10a..1f2ccbe 100644 --- a/lustre/liblustre/tests/echo_test.c +++ b/lustre/liblustre/tests/echo_test.c @@ -82,6 +82,11 @@ libcfs_nal_cmd(struct portals_cfg *pcfg) return 0; } +int in_group_p(gid_t gid) +{ + return 0; +} + int init_current(int argc, char **argv) { current = malloc(sizeof(*current)); diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 67935cb..e6471c8 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -31,6 +31,7 @@ #include #else #include +#include #endif #include -- 1.8.3.1