lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <87sk4xehf0.fsf@linux.vnet.ibm.com>
Date:	Tue, 08 Jun 2010 19:48:59 +0530
From:	"Aneesh Kumar K. V" <aneesh.kumar@...ux.vnet.ibm.com>
To:	hch@...radead.org, viro@...iv.linux.org.uk, adilger@....com,
	corbet@....net, serue@...ibm.com, neilb@...e.de,
	hooanon05@...oo.co.jp, bfields@...ldses.org
Cc:	linux-fsdevel@...r.kernel.org, sfrench@...ibm.com,
	philippe.deniel@....FR, linux-kernel@...r.kernel.org
Subject: Re: [PATCH -V13 0/11] Generic name to handle and open by handle syscalls

On Thu,  3 Jun 2010 21:44:06 +0530, "Aneesh Kumar K.V" <aneesh.kumar@...ux.vnet.ibm.com> wrote:
> Hi,
> 
> The below set of patches implement open by handle support using exportfs
> operations. This allows user space application to map a file name to file 
> handle and later open the file using handle. This should be usable
> for userspace NFS [1] and 9P server [2]. XFS already support this with the ioctls
> XFS_IOC_PATH_TO_HANDLE and XFS_IOC_OPEN_BY_HANDLE.
> 
> [1] http://nfs-ganesha.sourceforge.net/
> [2] http://thread.gmane.org/gmane.comp.emulators.qemu/68992
> 
> Changes from V12:
> a) Use CAP_DAC_READ_SEARCH instead of CAP_DAC_OVERRIDE in open_by_handle
> b) Return -ENOTDIR if O_DIRECTORY flag is specified in open_by_handle with
>    handle for non directory
> 
> Changes from V11:
> a) Add necessary documentation to different functions
> b) Add null pathname support to faccessat and linkat similar to
>    readlinkat.
> c) compile fix on x86_64
> 
> Changes from V10:
> a) Missed an stg refresh before sending out the patchset. Send
>    updated patchset.
> 
> Changes from V9:
> a) Fix compile errors with CONFIG_EXPORTFS not defined
> b) Return -EOPNOTSUPP if file system doesn't support fh_to_dentry exportfs callback.
> 
> Changes from V8:
> a)  exportfs_decode_fh now returns -ESTALE if export operations is not defined.
> b)  drop get_fsid super_operations. Instead use superblock to store uuid.
> 
> Changes from V7:
> a) open_by_handle now use mountdirfd to identify the vfsmount.
> b) We don't validate the UUID passed as a part of file handle in open_by_handle.
>    UUID is provided as a part of file handle as an easy way for userspace to
>    use the kernel returned handle as it is. It also helps in finding the 16 byte
>    filessytem UUID in userspace without using file system specific libraries to
>    read file system superblock. If a particular file system doesn't support UUID
>    or any form of unique id this field in the file handle will be zero filled.
> c) drop freadlink syscall. Instead use readlinkat with NULL pathname to indicate
>    read the link target name of the link pointed by fd. This is similar to
>    sys_utimensat
> d) Instead of opencoding all the open flag related check use helper functions.
>    Did finish_open_by_handle similar to finish_open.
> c) Fix may_open to not return ELOOP for symlink when we are called from handle open.
>    open(2) still returns error as expected. 
> 
> Changes from V6:
> a) Add uuid to vfsmount lookup and drop uuid to superblock lookup
> b) Return -EOPNOTSUPP in sys_name_to_handle if the file system returned uuid
>    doesn't give the same vfsmount on lookup. This ensure that we fail
>    sys_name_to_handle when we have multiple file system returning same UUID.
> 
> Changes from V5:
> a) added sys_name_to_handle_at syscall which takes AT_SYMLINK_NOFOLLOW flag 
>    instead of two syscalls sys_name_to_handle and sys_lname_to_handle.
> b) addressed review comments from Niel Brown
> c) rebased to b91ce4d14a21fc04d165be30319541e0f9204f15
> d) Add compat_sys_open_by_handle
> 
> Chages from V4:
> a) Changed the syscal arguments so that we don't need compat syscalls
>    as suggested by Christoph
> c) Added two new syscall sys_lname_to_handle and sys_freadlink to work with
>    symlinks
> d) Changed open_by_handle to work with all file types
> e) Add ext3 support
> 
> Changes from V3:
> a) Code cleanup suggested by Andreas
> b) x86_64 syscall support
> c) add compat syscall
> 
> Chages from V2:
> a) Support system wide unique handle.
> 
> Changes from v1:
> a) handle size is now specified in bytes
> b) returns -EOVERFLOW if the handle size is small
> c) dropped open_handle syscall and added open_by_handle_at syscall
>    open_by_handle_at takes mount_fd as the directory fd of the mount point
>    containing the file
> e) handle will only be unique in a given file system. So for an NFS server
>    exporting multiple file system, NFS server will have to internally track the
>    mount point to which a file handle belongs to. We should be able to do it much
>    easily than expecting kernel to give a system wide unique file handle. System
>    wide unique file handle would need much larger changes to the exportfs or VFS
>    interface and I was not sure whether we really need to do that in the kernel or
>    in the user space
> f) open_handle_at now only check for DAC_OVERRIDE capability
> 
> 
> Example program: (x86_32). (x86_64 would need a different syscall number)
> -------
> cc <source.c> -luuid
> --------
> #define _GNU_SOURCE
> #include <stdio.h>
> #include <stdlib.h>
> 
> #include <fcntl.h>
> #include <unistd.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <string.h>
> #include <uuid/uuid.h>
> 
> struct file_handle {
>         int handle_size;
>         int handle_type;
> 	uuid_t fs_uuid;
>         unsigned char handle[0];
> };
> 
> #define AT_FDCWD		-100
> #define AT_SYMLINK_FOLLOW	0x400
> 
> static int name_to_handle(const char *name, struct file_handle  *fh)
> {
> 	return syscall(338, AT_FDCWD, name, fh, AT_SYMLINK_FOLLOW);
> }
> 
> static int lname_to_handle(const char *name, struct file_handle  *fh)
> {
> 	return syscall(338, AT_FDCWD, name, fh, 0);
> }
> 
> static int open_by_handle(int mountfd, struct file_handle *fh,  int flags)
> {
> 	return syscall(339, mountfd, fh, flags);
> }
> 
> #define BUFSZ 100
> int main(int argc, char *argv[])
> {
>         int fd;
>         int ret;
> 	int mountfd;
> 	int handle_sz;
> 	struct stat bufstat;
>         char buf[BUFSZ];
> 	char uuid[36];
>         struct file_handle *fh = NULL;;
> 	if (argc != 3 ) {
> 		printf("Usage: %s <filename> <mount-dir-name>\n", argv[0]);
> 		exit(1);
> 	}
> again:
> 	if (fh && fh->handle_size) {
> 		handle_sz = fh->handle_size;
> 		free(fh);
> 		fh = malloc(sizeof(struct file_handle) + handle_sz);
> 		fh->handle_size = handle_sz;
> 	} else {
> 		fh = malloc(sizeof(struct file_handle));
> 		fh->handle_size = 0;
> 	}
>         errno  = 0;
>         ret = lname_to_handle(argv[1], fh);
>         if (ret && errno == EOVERFLOW) {
> 		printf("Found the handle size needed to be %d\n", fh->handle_size);
> 		goto again;
>         } else if (ret) {
>                 perror("Error:");
> 		exit(1);
> 	}
> 	uuid_unparse(fh->fs_uuid, uuid);
> 	printf("UUID:%s\n", uuid);
> 	printf("Waiting for input");
> 	getchar();
> 	mountfd = open(argv[2], O_RDONLY | O_DIRECTORY);
> 	if (mountfd <= 0) {
>                 perror("Error:");
>                 exit(1);
>         }
>         fd = open_by_handle(mountfd, fh, O_RDONLY);
>         if (fd <= 0 ) {
>                 perror("Error:");
>                 exit(1);
>         }
> 	printf("Reading the content now \n");
> 	fstat(fd, &bufstat);
> 	ret = S_ISLNK(bufstat.st_mode);
> 	if (ret) {
> 		memset(buf, 0 , BUFSZ);
> 		readlinkat(fd, NULL, buf, BUFSZ);
> 		printf("%s is a symlink pointing to %s\n", argv[1], buf);
> 	}
>         memset(buf, 0 , BUFSZ);
> 	while (1) {
> 		ret = read(fd, buf, BUFSZ -1);
> 		if (ret <= 0)
> 			break;
> 		buf[ret] = '\0';
>                 printf("%s", buf);
>                 memset(buf, 0 , BUFSZ);
>         }
> 	/* Now check for faccess */
> 	if (faccessat(fd, NULL, W_OK, 0) == 0) {
> 		printf("Got write permission on the file \n");
> 	} else
> 		perror("faccess error");
> 	/* now try to create a hardlink */
> 	if (linkat(fd, NULL, AT_FDCWD, "test", 0) == 0){
> 		printf("created hardlink\n");
> 	} else
> 		perror("linkat error");
>         return 0;
> }
> 
> 

git tree for this patch series is available at

http://git.kernel.org/?p=linux/kernel/git/kvaneesh/linux-open-handle.git

git://git.kernel.org/pub/scm/linux/kernel/git/kvaneesh/linux-open-handle.git open-by-handle-v13


-aneesh
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ