mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-10-31 07:58:45 +00:00 
			
		
		
		
	Don't fail to apply umask for O_TMPFILE files
Apply umask to `mode` which will eventually be applied to inode. This is needed since VFS doesn't apply umask for O_TMPFILE files. (Note that zpl_init_acl() applies `ip->i_mode &= ~current_umask();` only when POSIX ACL is used.) Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com> Closes #8997 Closes #8998
This commit is contained in:
		
							parent
							
								
									c317c8c811
								
							
						
					
					
						commit
						ddb4e69db5
					
				| @ -218,6 +218,12 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||||
| 
 | ||||
| 	crhold(cr); | ||||
| 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); | ||||
| 	/*
 | ||||
| 	 * The VFS does not apply the umask, therefore it is applied here | ||||
| 	 * when POSIX ACLs are not enabled. | ||||
| 	 */ | ||||
| 	if (!IS_POSIXACL(dir)) | ||||
| 		mode &= ~current_umask(); | ||||
| 	zpl_vap_init(vap, dir, mode, cr); | ||||
| 
 | ||||
| 	cookie = spl_fstrans_mark(); | ||||
|  | ||||
| @ -118,7 +118,8 @@ tests = ['snapshot_015_pos', 'snapshot_016_pos'] | ||||
| tags = ['functional', 'snapshot'] | ||||
| 
 | ||||
| [tests/functional/tmpfile:Linux] | ||||
| tests = ['tmpfile_001_pos', 'tmpfile_002_pos', 'tmpfile_003_pos'] | ||||
| tests = ['tmpfile_001_pos', 'tmpfile_002_pos', 'tmpfile_003_pos', | ||||
|     'tmpfile_stat_mode'] | ||||
| tags = ['functional', 'tmpfile'] | ||||
| 
 | ||||
| [tests/functional/upgrade:Linux] | ||||
|  | ||||
| @ -2,3 +2,4 @@ | ||||
| /tmpfile_001_pos | ||||
| /tmpfile_002_pos | ||||
| /tmpfile_003_pos | ||||
| /tmpfile_stat_mode | ||||
|  | ||||
| @ -8,7 +8,8 @@ dist_pkgdata_SCRIPTS = \ | ||||
| 
 | ||||
| pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/tmpfile | ||||
| 
 | ||||
| pkgexec_PROGRAMS = tmpfile_test tmpfile_001_pos tmpfile_002_pos tmpfile_003_pos | ||||
| pkgexec_PROGRAMS = tmpfile_test tmpfile_001_pos tmpfile_002_pos \
 | ||||
| 	tmpfile_003_pos tmpfile_stat_mode | ||||
| tmpfile_test_SOURCES= tmpfile_test.c | ||||
| tmpfile_001_pos_SOURCES = tmpfile_001_pos.c | ||||
| tmpfile_002_pos_SOURCES = tmpfile_002_pos.c | ||||
|  | ||||
							
								
								
									
										121
									
								
								tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | ||||
| /*
 | ||||
|  * CDDL HEADER START | ||||
|  * | ||||
|  * The contents of this file are subject to the terms of the | ||||
|  * Common Development and Distribution License (the "License"). | ||||
|  * You may not use this file except in compliance with the License. | ||||
|  * | ||||
|  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | ||||
|  * or http://www.opensolaris.org/os/licensing.
 | ||||
|  * See the License for the specific language governing permissions | ||||
|  * and limitations under the License. | ||||
|  * | ||||
|  * When distributing Covered Code, include this CDDL HEADER in each | ||||
|  * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | ||||
|  * If applicable, add the following below this CDDL HEADER, with the | ||||
|  * fields enclosed by brackets "[]" replaced with your own identifying | ||||
|  * information: Portions Copyright [yyyy] [name of copyright owner] | ||||
|  * | ||||
|  * CDDL HEADER END | ||||
|  */ | ||||
| /*
 | ||||
|  * Copyright (c) 2019 by Tomohiro Kusumi. All rights reserved. | ||||
|  */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| 
 | ||||
| /* backward compat in case it's not defined */ | ||||
| #ifndef O_TMPFILE | ||||
| #define	O_TMPFILE	(020000000|O_DIRECTORY) | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * DESCRIPTION: | ||||
|  *	Verify stat(2) for O_TMPFILE file considers umask. | ||||
|  * | ||||
|  * STRATEGY: | ||||
|  *	1. open(2) with O_TMPFILE. | ||||
|  *	2. linkat(2). | ||||
|  *	3. fstat(2)/stat(2) and verify .st_mode value. | ||||
|  */ | ||||
| 
 | ||||
| static void | ||||
| test_stat_mode(mode_t mask) | ||||
| { | ||||
| 	struct stat st, fst; | ||||
| 	int i, fd; | ||||
| 	char spath[1024], dpath[1024]; | ||||
| 	char *penv[] = {"TESTDIR", "TESTFILE0"}; | ||||
| 	mode_t masked = 0777 & ~mask; | ||||
| 	mode_t mode; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Get the environment variable values. | ||||
| 	 */ | ||||
| 	for (i = 0; i < sizeof (penv) / sizeof (char *); i++) { | ||||
| 		if ((penv[i] = getenv(penv[i])) == NULL) { | ||||
| 			fprintf(stderr, "getenv(penv[%d])\n", i); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	umask(mask); | ||||
| 	fd = open(penv[0], O_RDWR|O_TMPFILE, 0777); | ||||
| 	if (fd == -1) { | ||||
| 		perror("open"); | ||||
| 		exit(2); | ||||
| 	} | ||||
| 
 | ||||
| 	if (fstat(fd, &fst) == -1) { | ||||
| 		perror("fstat"); | ||||
| 		close(fd); | ||||
| 		exit(3); | ||||
| 	} | ||||
| 
 | ||||
| 	snprintf(spath, sizeof (spath), "/proc/self/fd/%d", fd); | ||||
| 	snprintf(dpath, sizeof (dpath), "%s/%s", penv[0], penv[1]); | ||||
| 
 | ||||
| 	unlink(dpath); | ||||
| 	if (linkat(AT_FDCWD, spath, AT_FDCWD, dpath, AT_SYMLINK_FOLLOW) == -1) { | ||||
| 		perror("linkat"); | ||||
| 		close(fd); | ||||
| 		exit(4); | ||||
| 	} | ||||
| 	close(fd); | ||||
| 
 | ||||
| 	if (stat(dpath, &st) == -1) { | ||||
| 		perror("stat"); | ||||
| 		exit(5); | ||||
| 	} | ||||
| 	unlink(dpath); | ||||
| 
 | ||||
| 	/* Verify fstat(2) result */ | ||||
| 	mode = fst.st_mode & 0777; | ||||
| 	if (mode != masked) { | ||||
| 		fprintf(stderr, "fstat(2) %o != %o\n", mode, masked); | ||||
| 		exit(6); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Verify stat(2) result */ | ||||
| 	mode = st.st_mode & 0777; | ||||
| 	if (mode != masked) { | ||||
| 		fprintf(stderr, "stat(2) %o != %o\n", mode, masked); | ||||
| 		exit(7); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	fprintf(stdout, "Verify stat(2) for O_TMPFILE file considers umask.\n"); | ||||
| 
 | ||||
| 	test_stat_mode(0022); | ||||
| 	test_stat_mode(0077); | ||||
| 
 | ||||
| 	return (0); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Tomohiro Kusumi
						Tomohiro Kusumi