[Libsysio-commit] HEAD: libsysio/src access.c chdir.c init.c inode.c mkdir.c mknod.c module.mk namei
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2006-05-03 22:31:10
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18135/src Modified Files: access.c chdir.c init.c inode.c mkdir.c mknod.c module.mk namei.c open.c rmdir.c symlink.c unlink.c Log Message: Some code cleanup. Support permission (and RO mount) checks in some routines. Added two new tests; test_mkdir and test_mknod. Index: access.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/access.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -w -b -B -p -r1.11 -r1.12 --- access.c 3 May 2006 15:57:28 -0000 1.11 +++ access.c 3 May 2006 22:31:04 -0000 1.12 @@ -62,12 +62,13 @@ static unsigned ngids = 0; /* max # g * Check given access type on given inode. */ static int -_sysio_check_permission(struct inode *ino, +_sysio_check_permission(struct pnode *pno, uid_t uid, gid_t gid, gid_t gids[], size_t ngids, int amode) { mode_t mask; + struct inode *ino; struct intnl_stat *stat; /* @@ -91,9 +92,12 @@ _sysio_check_permission(struct inode *in * Check for RO access to the file due to mount * options. */ - if (amode & W_OK && IS_RDONLY(NULL, ino)) + if (amode & W_OK && IS_RDONLY(pno)) return -EROFS; + ino = pno->p_base->pb_ino; + assert(ino); + stat = &ino->i_stbuf; if (stat->st_uid == uid && (stat->st_mode & mask) == mask) return 0; @@ -119,7 +123,7 @@ _sysio_check_permission(struct inode *in * Determine if a given access is permitted to a give file. */ int -_sysio_permitted(struct inode *ino, int amode) +_sysio_permitted(struct pnode *pno, int amode) { int err; int n; @@ -158,7 +162,7 @@ _sysio_permitted(struct inode *ino, int } } err = - _sysio_check_permission(ino, + _sysio_check_permission(pno, geteuid(), getegid(), gids, (size_t )n, amode); @@ -200,7 +204,7 @@ SYSIO_INTERFACE_NAME(access)(const char if (err) SYSIO_INTERFACE_RETURN(-1, err); err = - _sysio_check_permission(pno->p_base->pb_ino, + _sysio_check_permission(pno, getuid(), getgid(), NULL, 0, amode); Index: chdir.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/chdir.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -w -b -B -p -r1.23 -r1.24 --- chdir.c 14 Oct 2004 14:59:29 -0000 1.23 +++ chdir.c 3 May 2006 22:31:04 -0000 1.24 @@ -101,11 +101,7 @@ _sysio_p_chdir(struct pnode *pno) return err; if (!(pno->p_base->pb_ino && S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode))) - err = -ENOTDIR; - else - err = _sysio_permitted(pno->p_base->pb_ino, X_OK); - if (err) - return err; + return -ENOTDIR; /* * Release old if set. Index: init.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/init.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -w -b -B -p -r1.27 -r1.28 --- init.c 3 May 2006 15:57:28 -0000 1.27 +++ init.c 3 May 2006 22:31:04 -0000 1.28 @@ -540,6 +540,15 @@ do_creat(char *args) struct intent intent; dev_t dev; int err; + enum { + CREATE_DIR = 1, + CREATE_CHR = 2, + CREATE_BLK = 3, + CREATE_FILE = 4 + } op; + int intent_mode; + struct inode *ino; + int i; len = strlen(args); if (_sysio_get_args(args, v) - args != (ssize_t )len || @@ -572,69 +581,65 @@ do_creat(char *args) if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) return -ENOENT; + + /* + * Init, get the operation, setup the intent. + */ err = 0; mode = perms; + op = 0; if (strcmp(v[0].ovi_value, "dir") == 0) { - INTENT_INIT(&intent, INT_CREAT, &mode, 0); - err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); - if (err) - return err; - if (pno->p_base->pb_ino) - err = -EEXIST; - else if (IS_RDONLY(pno->p_parent, - pno->p_parent->p_base->pb_ino)) - err = -EROFS; - else { - struct inode *ino; - - ino = pno->p_parent->p_base->pb_ino; - err = (*ino->i_ops.inop_mkdir)(pno, mode); - } - P_RELE(pno); + op = CREATE_DIR; + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); } else if (strcmp(v[0].ovi_value, "chr") == 0) { - if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) - return -EINVAL; + op = CREATE_CHR; mode |= S_IFCHR; - INTENT_INIT(&intent, INT_CREAT, &mode, 0); - err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); + if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) + err = -EINVAL; + } else if (strcmp(v[0].ovi_value, "blk") == 0) { + op = CREATE_BLK; + mode |= S_IFBLK; + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); + if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) + err = -EINVAL; + } else if (strcmp(v[0].ovi_value, "file") == 0) { + op = CREATE_FILE; + intent_mode = O_CREAT|O_EXCL; + INTENT_INIT(&intent, INT_CREAT, &mode, &intent_mode); + } else + err = -EINVAL; if (err) return err; - if (pno->p_base->pb_ino) - err = -EEXIST; - else if (IS_RDONLY(pno->p_parent, - pno->p_parent->p_base->pb_ino)) - err = -EROFS; - else { - struct inode *ino; - ino = pno->p_parent->p_base->pb_ino; - err = (*ino->i_ops.inop_mknod)(pno, mode, dev); - } - P_RELE(pno); - } else if (strcmp(v[0].ovi_value, "blk") == 0) { /* - * We don't support block special files yet. + * Lookup the given path. */ - return -EINVAL; - } else if (strcmp(v[0].ovi_value, "file") == 0) { - int i; - struct inode *ino; - - i = O_CREAT|O_EXCL; - INTENT_INIT(&intent, INT_CREAT, &mode, &i); err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); + _sysio_namei(dir, + v[1].ovi_value, + ND_NEGOK|ND_NOPERMCHECK, + &intent, + &pno); if (err) return err; + + /* + * Perform. + */ + switch (op) { + case CREATE_DIR: + err = _sysio_mkdir(pno, mode); + break; + case CREATE_CHR: + case CREATE_BLK: + err = _sysio_mknod(pno, mode, dev); + case CREATE_FILE: err = _sysio_open(pno, O_CREAT|O_EXCL, mode); - if (err) { - P_RELE(pno); - return err; - } + if (err) + break; ino = pno->p_base->pb_ino; - if (!err && v[6].ovi_value) { + if (v[6].ovi_value) { struct iovec iovec; struct intnl_xtvec xtvec; struct ioctx io_context; @@ -670,10 +675,12 @@ do_creat(char *args) i = (*ino->i_ops.inop_close)(ino); if (!err) err = i; - P_RELE(pno); - } else - err = -EINVAL; + break; + default: + abort(); + } + P_RELE(pno); return err; } @@ -758,8 +765,13 @@ do_cd(char *args) if (_sysio_get_args(args, v) - args != (ssize_t )len || !v[0].ovi_value) return -EINVAL; - if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) + if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) { + /* + * We have no namespace yet. They really need to give us + * something to work with. + */ return -ENOENT; + } err = _sysio_namei(dir, v[0].ovi_value, 0, NULL, &pno); if (err) return err; @@ -805,7 +817,7 @@ do_chmd(char *args) if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) return -ENOENT; - err = _sysio_namei(dir, v[0].ovi_value, 0, NULL, &pno); + err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, NULL, &pno); if (err) return err; err = _sysio_setattr(pno, pno->p_base->pb_ino, SETATTR_MODE, &stbuf); @@ -852,7 +864,7 @@ do_open(char *args) return -ENOENT; INTENT_INIT(&intent, INT_OPEN, &m, NULL); pno = NULL; - err = _sysio_namei(dir, v[0].ovi_value, 0, &intent, &pno); + err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, &intent, &pno); if (err) return err; fil = NULL; Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -w -b -B -p -r1.22 -r1.23 --- inode.c 14 Oct 2004 14:59:29 -0000 1.22 +++ inode.c 3 May 2006 22:31:04 -0000 1.23 @@ -861,27 +861,6 @@ _sysio_pb_path(struct pnode_base *pb, co } /* - * Common set attributes routine. - */ -int -_sysio_setattr(struct pnode *pno, - struct inode *ino, - unsigned mask, - struct intnl_stat *stbuf) -{ - /* It is possible that pno is null (for ftruncate call). */ - - if (pno) { - assert(!(pno->p_base->pb_ino && ino) || pno->p_base->pb_ino == ino); - if (IS_RDONLY(pno, ino)) - return -EROFS; - } - if (!ino && pno->p_base->pb_ino) - ino = pno->p_base->pb_ino; - return (*ino->i_ops.inop_setattr)(pno, ino, mask, stbuf); -} - -/* * Do nothing. */ void Index: mkdir.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/mkdir.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -w -b -B -p -r1.15 -r1.16 --- mkdir.c 12 May 2005 20:17:48 -0000 1.15 +++ mkdir.c 3 May 2006 22:31:04 -0000 1.16 @@ -55,6 +55,24 @@ #include "sysio-symbols.h" int +_sysio_mkdir(struct pnode *pno, mode_t mode) +{ + struct inode *ino; + + if (pno->p_base->pb_ino) + return -EEXIST; + + ino = pno->p_parent->p_base->pb_ino; + assert(ino); + + if (!IS_RDONLY(pno)) + return -EROFS; + + mode |= S_IFDIR; + return (*ino->i_ops.inop_mkdir)(pno, mode); +} + +int SYSIO_INTERFACE_NAME(mkdir)(const char *path, mode_t mode) { int err; @@ -67,16 +85,11 @@ SYSIO_INTERFACE_NAME(mkdir)(const char * err = _sysio_namei(_sysio_cwd, path, ND_NEGOK, &intent, &pno); if (err) goto out; - if (pno->p_base->pb_ino) { - err = -EEXIST; - goto error; - } - if (IS_RDONLY(pno, pno->p_base->pb_ino)) { - err = -EROFS; + err = _sysio_permitted(pno->p_parent, W_OK); + if (err) goto error; - } - mode |= S_IFDIR; + mode &= ~(_sysio_umask & 0777); /* apply umask */ err = (*pno->p_parent->p_base->pb_ino->i_ops.inop_mkdir)(pno, mode); error: Index: mknod.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/mknod.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -w -b -B -p -r1.17 -r1.18 --- mknod.c 12 May 2005 20:17:50 -0000 1.17 +++ mknod.c 3 May 2006 22:31:04 -0000 1.18 @@ -62,6 +62,31 @@ #undef mknod #undef __xmknod +/* + * Internal routine to make a device node. + */ +int +_sysio_mknod(struct pnode *pno, mode_t mode, dev_t dev) +{ + + if (pno->p_base->pb_ino) + return -EEXIST; + + /* + * Support only regular, character-special and fifos right now. + * (mode & S_IFMT) == 0 is the same as S_IFREG. + */ + if ((mode & S_IFMT) && + !(S_ISREG(mode) || S_ISCHR(mode) || S_ISFIFO(mode))) + return -EINVAL; + + if (IS_RDONLY(pno)) + return -EROFS; + return (*pno->p_parent->p_base->pb_ino->i_ops.inop_mknod)(pno, + mode, + dev); +} + int PREPEND(__, SYSIO_INTERFACE_NAME(xmknod))(int __ver, const char *path, @@ -79,33 +104,17 @@ PREPEND(__, SYSIO_INTERFACE_NAME(xmknod) goto out; } - /* - * Support only regular, character-special and fifos right now. - * (mode & S_IFMT) == 0 is the same as S_IFREG. - */ - if ((mode & S_IFMT) && - !(S_ISREG(mode) || S_ISCHR(mode) || S_ISFIFO(mode))) { - err = -EINVAL; - goto out; - } - mode &= ~(_sysio_umask & 0777); /* apply umask */ INTENT_INIT(&intent, INT_CREAT, &mode, NULL); err = _sysio_namei(_sysio_cwd, path, ND_NEGOK, &intent, &pno); if (err) goto out; - if (pno->p_base->pb_ino) { - err = -EEXIST; - goto error; - } - if (IS_RDONLY(pno, pno->p_base->pb_ino)) { - err = -EROFS; + err = _sysio_permitted(pno->p_parent, W_OK); + if (err) goto error; - } - err = - (*pno->p_parent->p_base->pb_ino->i_ops.inop_mknod)(pno, mode, *dev); + err = _sysio_mknod(pno, mode, *dev); error: P_RELE(pno); out: Index: module.mk =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/module.mk,v retrieving revision 1.10 retrieving revision 1.11 diff -u -w -b -B -p -r1.10 -r1.11 --- module.mk 25 Oct 2004 14:29:16 -0000 1.10 +++ module.mk 3 May 2006 22:31:04 -0000 1.11 @@ -23,7 +23,7 @@ SRCDIR_SRCS = src/access.c src/chdir.c s src/link.c src/lseek.c src/mkdir.c \ src/mknod.c src/mount.c src/namei.c \ src/open.c src/rw.c src/reconcile.c src/rename.c \ - src/rmdir.c src/stat64.c src/stat.c \ + src/rmdir.c src/setattr.c src/stat64.c src/stat.c \ src/stddir.c src/readdir.c src/readdir64.c \ src/symlink.c src/readlink.c \ src/truncate.c src/unlink.c src/utime.c \ Index: namei.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/namei.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -w -b -B -p -r1.19 -r1.20 --- namei.c 8 Feb 2006 17:17:43 -0000 1.19 +++ namei.c 3 May 2006 22:31:04 -0000 1.20 @@ -88,7 +88,8 @@ lookup(struct pnode *parent, struct qstr *name, struct pnode **pnop, struct intent *intnt, - const char *path) + const char *path, + int check_permissions) { int err; struct pnode *pno; @@ -96,9 +97,15 @@ lookup(struct pnode *parent, if (!parent->p_base->pb_ino) return -ENOTDIR; - err = _sysio_permitted(parent->p_base->pb_ino, X_OK); + if (check_permissions) { + /* + * Sometimes we don't want to do this. At initialization + * time, for instance. + */ + err = _sysio_permitted(parent, X_OK); if (err) return err; + } /* * Short-circuit `.' and `..'; We don't cache those. @@ -295,7 +302,8 @@ _sysio_path_walk(struct pnode *parent, s &_sysio_mount_file_name, &pno, NULL, - NULL); + NULL, + 1); if (pno) P_RELE(pno); if (!err && _sysio_automount(pno) == 0) { @@ -408,7 +416,8 @@ _sysio_path_walk(struct pnode *parent, s (path || !next.len) ? nd->nd_intent : NULL, - (path && next.len) ? path : NULL); + (path && next.len) ? path : NULL, + !(nd->nd_flags & ND_NOPERMCHECK)); if (err) { if (err == -ENOENT && !next.len && Index: open.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/open.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -w -b -B -p -r1.26 -r1.27 --- open.c 18 Jan 2006 00:42:41 -0000 1.26 +++ open.c 3 May 2006 22:31:04 -0000 1.27 @@ -79,7 +79,7 @@ _sysio_open(struct pnode *pno, int flags int err; struct inode *ino; - ro = IS_RDONLY(pno, pno->p_base->pb_ino); + ro = IS_RDONLY(pno); w = flags & (O_WRONLY|O_RDWR); if (w == (O_WRONLY|O_RDWR)) { /* @@ -103,10 +103,7 @@ _sysio_open(struct pnode *pno, int flags if (!err) { ino = parent->p_base->pb_ino; assert(ino); - err = - !IS_RDONLY(parent, ino) - ? (*ino->i_ops.inop_open)(pno, flags, mode) - : -EROFS; + err = (*ino->i_ops.inop_open)(pno, flags, mode); } } else if ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) err = -EEXIST; Index: rmdir.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/rmdir.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -w -b -B -p -r1.18 -r1.19 --- rmdir.c 25 Jan 2005 18:59:34 -0000 1.18 +++ rmdir.c 3 May 2006 22:31:04 -0000 1.19 @@ -72,10 +72,9 @@ SYSIO_INTERFACE_NAME(rmdir)(const char * err = -ENOTDIR; goto error; } - if (IS_RDONLY(pno, pno->p_base->pb_ino)) { - err = -EROFS; + err = _sysio_permitted(pno->p_parent, W_OK); + if (err) goto error; - } if (pno->p_ref > 1) { err = -EBUSY; goto error; @@ -85,7 +84,7 @@ SYSIO_INTERFACE_NAME(rmdir)(const char * * driver is implemented using differentiated inode operations based * on file type, such as incore does. */ - err = pno->p_parent->p_base->pb_ino->i_ops.inop_rmdir(pno); + err = (*pno->p_parent->p_base->pb_ino->i_ops.inop_rmdir)(pno); if (err) goto error; /* Index: symlink.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/symlink.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -w -b -B -p -r1.14 -r1.15 --- symlink.c 28 Apr 2006 15:01:48 -0000 1.14 +++ symlink.c 3 May 2006 22:31:04 -0000 1.15 @@ -76,11 +76,10 @@ SYSIO_INTERFACE_NAME(symlink)(const char err = -EEXIST; goto error; } - - if (IS_RDONLY(pno, pno->p_base->pb_ino)) { - err = -EROFS; + err = _sysio_permitted(pno->p_parent, W_OK); + if (err) goto error; - } + /* * Use the parent node operations to request the task in case the * driver is implemented using differentiated inode operations based Index: unlink.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/unlink.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -w -b -B -p -r1.16 -r1.17 --- unlink.c 25 Jan 2005 18:56:15 -0000 1.16 +++ unlink.c 3 May 2006 22:31:04 -0000 1.17 @@ -68,11 +68,12 @@ SYSIO_INTERFACE_NAME(unlink)(const char err = _sysio_namei(_sysio_cwd, path, ND_NOFOLLOW, &intent, &pno); if (err) goto out; - ino = pno->p_base->pb_ino; - if (IS_RDONLY(pno, ino)) { - err = -EROFS; + + err = _sysio_permitted(pno->p_parent, W_OK); + if (err) goto error; - } + + ino = pno->p_base->pb_ino; /* * Use the parent node operations to request the task in case the * driver is implemented using differentiated inode operations based |