Subject: port-i386/4083: Linux emulation of fcntl(...,F_GETLK,...) is broken
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Scheler <tron@lyssa.owl.de>
List: netbsd-bugs
Date: 09/05/1997 01:49:25
>Number:         4083
>Category:       port-i386
>Synopsis:       Linux emulation of fcntl(...,F_GETLK,...) is broken
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Sep  4 18:20:02 1997
>Last-Modified:
>Originator:     Matthias Scheler
>Organization:
Matthias Scheler                                http://home.owl.de/~tron/
>Release:        970829
>Environment:
System: NetBSD lyssa 1.2G NetBSD 1.2G (LYSSA) #3: Fri Sep 5 01:37:32 MEST 1997 tron@lyssa:/usr/src/sys/arch/i386/compile/LYSSA i386

>Description:
Because the Linux emulation of fcntl(...,F_GETLK,...) handles its arguments
incorrectly the call to NetBSD's fcntl() syscall will fail with EINVAL.

>How-To-Repeat:
Try to save a file with "swriter3" from the StarOffice 3.1 package.

>Fix:
*** src/sys/compat/linux/linux_file.c.old	Fri Aug 29 11:49:43 1997
--- src/sys/compat/linux/linux_file.c	Fri Sep  5 01:36:19 1997
*************** linux_sys_fcntl(p, v, retval)
*** 345,360 ****
  		return sys_fcntl(p, &fca, retval);
  	case LINUX_F_GETLK:
  		sg = stackgap_init(p->p_emul);
  		bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
  		SCARG(&fca, fd) = fd;
  		SCARG(&fca, cmd) = F_GETLK;
  		SCARG(&fca, arg) = bfp;
! 		if ((error = sys_fcntl(p, &fca, retval)))
  			return error;
! 		if ((error = copyin(bfp, &bfl, sizeof bfl)))
  			return error;
  		bsd_to_linux_flock(&bfl, &lfl);
! 		return copyout(&lfl, arg, sizeof lfl);
  		break;
  	case LINUX_F_SETLK:
  	case LINUX_F_SETLKW:
--- 345,375 ----
  		return sys_fcntl(p, &fca, retval);
  	case LINUX_F_GETLK:
  		sg = stackgap_init(p->p_emul);
+ 		if ((error = copyin(arg, &lfl, sizeof lfl))) {
+ 			printf("Fail copyin: %d\n",error);
+ 			return error;
+ 		}
+ 		linux_to_bsd_flock(&lfl, &bfl);
  		bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
  		SCARG(&fca, fd) = fd;
  		SCARG(&fca, cmd) = F_GETLK;
  		SCARG(&fca, arg) = bfp;
! 		if ((error = copyout(&bfl, bfp, sizeof bfl))) {
! 			printf("Fail copyout: %d\n",error);
! 			return error;
! 		}
! 		if ((error = sys_fcntl(p, &fca, retval))) {
! 			printf("Fail sys_fcntl: %d\n",error);
  			return error;
! 		}
! 		if ((error = copyin(bfp, &bfl, sizeof bfl))) {
! 			printf("Fail copyin: %d\n",error);
  			return error;
+ 		}
  		bsd_to_linux_flock(&bfl, &lfl);
! 		if ((error = copyout(&lfl, arg, sizeof lfl)))
! 			printf("Fail copyout: %d\n",error);
! 		return error;
  		break;
  	case LINUX_F_SETLK:
  	case LINUX_F_SETLKW:
>Audit-Trail:
>Unformatted: