Fix dangling symlink resolving for AVFS and add test61
This commit is contained in:
		
							parent
							
								
									21168577a5
								
							
						
					
					
						commit
						706873142e
					
				| @ -326,7 +326,6 @@ PRIVATE struct vnode *new_node(struct lookup *resolve, int oflags, mode_t bits) | |||||||
|   /* The combination of a symlink with absolute path followed by a danglink
 |   /* The combination of a symlink with absolute path followed by a danglink
 | ||||||
|    * symlink results in a new path that needs to be re-resolved entirely. */ |    * symlink results in a new path that needs to be re-resolved entirely. */ | ||||||
|   if (path[0] == '/') { |   if (path[0] == '/') { | ||||||
| printf("XXX: dangling symlink needs re-resolving\n"); |  | ||||||
| 	unlock_vnode(dirp); | 	unlock_vnode(dirp); | ||||||
| 	unlock_vmnt(dir_vmp); | 	unlock_vmnt(dir_vmp); | ||||||
| 	put_vnode(dirp); | 	put_vnode(dirp); | ||||||
| @ -391,15 +390,19 @@ printf("XXX: dangling symlink needs re-resolving\n"); | |||||||
| 			/* Try to create the inode the dangling symlink was
 | 			/* Try to create the inode the dangling symlink was
 | ||||||
| 			 * pointing to. We have to use dirp as starting point | 			 * pointing to. We have to use dirp as starting point | ||||||
| 			 * as there might be multiple successive symlinks | 			 * as there might be multiple successive symlinks | ||||||
| 			 * crossing multiple mountpoints. */ | 			 * crossing multiple mountpoints. | ||||||
|  | 			 * Unlock vnodes and vmnts as we're going to recurse. | ||||||
|  | 			 */ | ||||||
|  | 			unlock_vnode(dirp); | ||||||
|  | 			unlock_vnode(vp); | ||||||
|  | 			unlock_vmnt(dir_vmp); | ||||||
|  | 
 | ||||||
| 			old_wd = fp->fp_wd; /* Save orig. working dirp */ | 			old_wd = fp->fp_wd; /* Save orig. working dirp */ | ||||||
| 			fp->fp_wd = dirp; | 			fp->fp_wd = dirp; | ||||||
| 			vp = new_node(resolve, oflags, bits); | 			vp = new_node(resolve, oflags, bits); | ||||||
| 			fp->fp_wd = old_wd; /* Restore */ | 			fp->fp_wd = old_wd; /* Restore */ | ||||||
| 
 | 
 | ||||||
| 			if (vp != NULL) { | 			if (vp != NULL) { | ||||||
| 				unlock_vnode(dirp); |  | ||||||
| 				unlock_vmnt(dir_vmp); |  | ||||||
| 				put_vnode(dirp); | 				put_vnode(dirp); | ||||||
| 				*(resolve->l_vnode) = vp; | 				*(resolve->l_vnode) = vp; | ||||||
| 				return(vp); | 				return(vp); | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ OBJ=	test1  test2  test3  test4  test5  test6  test7  test8  test9  \ | |||||||
| 	test54 test56 test58 t60a t60b | 	test54 test56 test58 t60a t60b | ||||||
| 
 | 
 | ||||||
| BIGOBJ=  test20 test24 | BIGOBJ=  test20 test24 | ||||||
| ROOTOBJ= test11 test33 test43 test44 test46 test60 | ROOTOBJ= test11 test33 test43 test44 test46 test60 test61 | ||||||
| GCCOBJ=  test45-gcc test48 test49-gcc test55 | GCCOBJ=  test45-gcc test48 test49-gcc test55 | ||||||
| GCCFPUOBJ= test51-gcc test52-gcc | GCCFPUOBJ= test51-gcc test52-gcc | ||||||
| OTHEROBJ= test57 test59 | OTHEROBJ= test57 test59 | ||||||
| @ -133,3 +133,4 @@ test59: test59.c | |||||||
| test60: test60.c | test60: test60.c | ||||||
| t60a: t60a.c | t60a: t60a.c | ||||||
| t60b: t60b.c | t60b: t60b.c | ||||||
|  | test61: test61.c | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								test/run
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								test/run
									
									
									
									
									
								
							| @ -15,7 +15,7 @@ tests="   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 \ | |||||||
|          21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \ |          21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \ | ||||||
|          41 42 43 44 45 45-gcc 46 47 48 49 49-gcc 50 \ |          41 42 43 44 45 45-gcc 46 47 48 49 49-gcc 50 \ | ||||||
|          51 51-gcc 52 52-gcc 53 54 55 56 57 58 59\ |          51 51-gcc 52 52-gcc 53 54 55 56 57 58 59\ | ||||||
|          60 \ |          60 61 \ | ||||||
| 	 sh1.sh sh2.sh" | 	 sh1.sh sh2.sh" | ||||||
| tests_no=`expr 0` | tests_no=`expr 0` | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								test/test61.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								test/test61.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <sys/wait.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | #define MAX_ERROR 5 | ||||||
|  | #include "common.c" | ||||||
|  | 
 | ||||||
|  | void dangling_slink(int sub_test, char const slink_to[PATH_MAX]); | ||||||
|  | 
 | ||||||
|  | void dangling_slink(int sub_test, char const slink_to[PATH_MAX]) | ||||||
|  | { | ||||||
|  |   pid_t child; | ||||||
|  | 
 | ||||||
|  |   subtest = sub_test; | ||||||
|  | 
 | ||||||
|  |   child = fork(); | ||||||
|  |   if (child == (pid_t) -1) { | ||||||
|  | 	e(1); | ||||||
|  | 	return; | ||||||
|  |   } else if (child == (pid_t) 0) { | ||||||
|  | 	/* I'm the child. Create a dangling symlink with an absolute path */ | ||||||
|  | 	int fd; | ||||||
|  | 	char buf[4]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	/* We don't want to actually write to '/', so instead we pretend */ | ||||||
|  | 	if (chroot(".") != 0) e(2); | ||||||
|  | 
 | ||||||
|  | 	/* Create file 'slink_to' with contents "bar" */ | ||||||
|  | 	if ((fd = open(slink_to, O_CREAT|O_WRONLY)) == -1) e(3); | ||||||
|  | 	if (write(fd, "bar", strlen("bar")) != strlen("bar")) e(4); | ||||||
|  | 	close(fd); | ||||||
|  | 
 | ||||||
|  | 	if (symlink(slink_to, "a") == -1) e(5); /* Create the symlink */ | ||||||
|  | 	if (rename(slink_to, "c") == -1) e(6); /* Make it a dangling symlink */ | ||||||
|  | 
 | ||||||
|  | 	/* Write "foo" to symlink; this should recreate file 'slink_to' with
 | ||||||
|  | 	 * contents "foo" */ | ||||||
|  | 	if ((fd = open("a", O_CREAT|O_WRONLY)) == -1) e(7); | ||||||
|  | 	if (write(fd, "foo", strlen("foo")) != strlen("foo")) e(8); | ||||||
|  | 	close(fd); | ||||||
|  | 
 | ||||||
|  | 	/* Verify 'a' and 'slink_to' contain "foo" */ | ||||||
|  | 	memset(buf, '\0', sizeof(buf)); | ||||||
|  | 	if ((fd = open("a", O_RDONLY)) == -1) e(9); | ||||||
|  | 	if (read(fd, buf, 3) != 3) e(10); | ||||||
|  | 	if (strncmp(buf, "foo", strlen("foo"))) e(11); | ||||||
|  | 	close(fd); | ||||||
|  | 	memset(buf, '\0', sizeof(buf)); | ||||||
|  | 	if ((fd = open(slink_to, O_RDONLY)) == -1) e(12); | ||||||
|  | 	if (read(fd, buf, 3) != 3) e(13); | ||||||
|  | 	if (strncmp(buf, "foo", strlen("foo"))) e(14); | ||||||
|  | 	close(fd); | ||||||
|  | 
 | ||||||
|  | 	/* Verify 'c' contains 'bar' */ | ||||||
|  | 	memset(buf, '\0', sizeof(buf)); | ||||||
|  | 	if ((fd = open("c", O_RDONLY)) == -1) e(15); | ||||||
|  | 	if (read(fd, buf, 3) != 3) e(16); | ||||||
|  | 	if (strncmp(buf, "bar", strlen("bar"))) e(17); | ||||||
|  | 	close(fd); | ||||||
|  | 
 | ||||||
|  | 	/* Cleanup created files */ | ||||||
|  | 	if (unlink(slink_to) == -1) e(18); | ||||||
|  | 	if (unlink("a") == -1) e(19); | ||||||
|  | 	if (unlink("c") == -1) e(20); | ||||||
|  | 
 | ||||||
|  | 	exit(EXIT_SUCCESS); | ||||||
|  |   } else { | ||||||
|  | 	int status; | ||||||
|  | 	if (wait(&status) == -1) e(7); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |   start(61); | ||||||
|  |   dangling_slink(1, "/abs"); /* Create dangling symlink with absolute path */ | ||||||
|  |   dangling_slink(2, "rel"); /* Create dangling symlink with relative path */ | ||||||
|  |   quit(); | ||||||
|  |   return(-1);	/* Unreachable */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Thomas Veerman
						Thomas Veerman