From patchwork Thu Aug 18 12:03:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 9287471 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8E50A600CB for ; Thu, 18 Aug 2016 12:03:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7FD3828AB0 for ; Thu, 18 Aug 2016 12:03:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 745ED28AE2; Thu, 18 Aug 2016 12:03:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0A6328AB0 for ; Thu, 18 Aug 2016 12:03:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753186AbcHRMD0 (ORCPT ); Thu, 18 Aug 2016 08:03:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:11507 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752449AbcHRMD0 (ORCPT ); Thu, 18 Aug 2016 08:03:26 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9B28330C7BB; Thu, 18 Aug 2016 12:03:25 +0000 (UTC) Received: from tlielax.poochiereds.net (ovpn-116-26.rdu2.redhat.com [10.10.116.26]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u7IC3OWh022527; Thu, 18 Aug 2016 08:03:25 -0400 From: Jeff Layton To: linux-fsdevel@vger.kernel.org Cc: libc-alpha@sourceware.org, chrubis@suse.cz Subject: [Linux PATCH] fcntl: add new F_OFD_*32 constants and handle them appropriately Date: Thu, 18 Aug 2016 08:03:24 -0400 Message-Id: <1471521804-4291-1-git-send-email-jlayton@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 18 Aug 2016 12:03:25 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When I originally added OFD lock support, we made the assumption that userland would always pass in a struct flock64 for an OFD lock. It's possible however for someone to build a binary without large file support (aka LFS), which will call down into the kernel with the standard F_OFD_* constants, but pass in a "legacy" struct flock. My first thought was to patch glibc to cause a build break if anyone tries to use OFD locks without LFS, but now I think it might be less problematic to simply support OFD locks without LFS enabled. The kernel handles this for classic POSIX locks with a separate set of constants (postfixed with "64") to indicate that the incoming structure is an LFS one. We can't do that here since the kernel already assumes that the structure is an LFS one. Instead, we can define a new set of constants that are postfixed with "32" to indicate that the incoming structure is a non-LFS one. This patch adds the kernel plumbing to handle that case. We'll also need a small patch for glibc to make it to use these constants when LFS is disabled. In the event that someone builds a program with a new glibc, and runs it on a kernel without support for F_OFD_*32 constants, they will just get back EINVAL. That's preferable to the current situation which is undefined behavior due to misinterpretation of the struct flock argument. Cc: stable@vger.kernel.org # v3.15+ Reported-by: Cyril Hrubis Signed-off-by: Jeff Layton --- fs/compat.c | 3 +++ fs/fcntl.c | 4 +++- fs/locks.c | 4 +++- include/uapi/asm-generic/fcntl.h | 4 ++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/compat.c b/fs/compat.c index be6e48b0a46c..a7e9640e9107 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -426,6 +426,9 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, case F_GETLK: case F_SETLK: case F_SETLKW: + case F_OFD_GETLK32: + case F_OFD_SETLK32: + case F_OFD_SETLKW32: ret = get_compat_flock(&f, compat_ptr(arg)); if (ret != 0) break; diff --git a/fs/fcntl.c b/fs/fcntl.c index 350a2c8cfd28..71704aa11170 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -270,6 +270,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, /* 32-bit arches must use fcntl64() */ case F_OFD_GETLK: #endif + case F_OFD_GETLK32: case F_GETLK: err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); break; @@ -278,7 +279,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, case F_OFD_SETLK: case F_OFD_SETLKW: #endif - /* Fallthrough */ + case F_OFD_SETLK32: + case F_OFD_SETLKW32: case F_SETLK: case F_SETLKW: err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); diff --git a/fs/locks.c b/fs/locks.c index 7e428b78be07..4ffde68322de 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -2065,7 +2065,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) if (error) goto out; - if (cmd == F_OFD_GETLK) { + if (cmd == F_OFD_GETLK || cmd == F_OFD_GETLK32) { error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2222,6 +2222,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, */ switch (cmd) { case F_OFD_SETLK: + case F_OFD_SETLK32: error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2231,6 +2232,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, file_lock->fl_owner = filp; break; case F_OFD_SETLKW: + case F_OFD_SETLKW32: error = -EINVAL; if (flock.l_pid != 0) goto out; diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index e063effe0cc1..b407deee68e1 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h @@ -148,6 +148,10 @@ #define F_OFD_SETLK 37 #define F_OFD_SETLKW 38 +#define F_OFD_GETLK32 39 +#define F_OFD_SETLK32 40 +#define F_OFD_SETLKW32 41 + #define F_OWNER_TID 0 #define F_OWNER_PID 1 #define F_OWNER_PGRP 2