get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/810687/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 810687,
    "url": "http://patchwork.ozlabs.org/api/patches/810687/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20170906155115.24400-2-juerg.haefliger@canonical.com/",
    "project": {
        "id": 15,
        "url": "http://patchwork.ozlabs.org/api/projects/15/?format=api",
        "name": "Ubuntu Kernel",
        "link_name": "ubuntu-kernel",
        "list_id": "kernel-team.lists.ubuntu.com",
        "list_email": "kernel-team@lists.ubuntu.com",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170906155115.24400-2-juerg.haefliger@canonical.com>",
    "list_archive_url": null,
    "date": "2017-09-06T15:51:15",
    "name": "[trusty,CVE-2016-7097,v2,1/1] posix_acl: Clear SGID bit when setting file permissions",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a31fc168dcb66964131d75804232a0a0f1b4b804",
    "submitter": {
        "id": 71819,
        "url": "http://patchwork.ozlabs.org/api/people/71819/?format=api",
        "name": "Juerg Haefliger",
        "email": "juerg.haefliger@canonical.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20170906155115.24400-2-juerg.haefliger@canonical.com/mbox/",
    "series": [
        {
            "id": 1844,
            "url": "http://patchwork.ozlabs.org/api/series/1844/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=1844",
            "date": "2017-09-06T15:51:14",
            "name": "Fix for CVE-2016-7097",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/1844/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/810687/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/810687/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<kernel-team-bounces@lists.ubuntu.com>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com\n\t(client-ip=91.189.94.19; helo=huckleberry.canonical.com;\n\tenvelope-from=kernel-team-bounces@lists.ubuntu.com;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from huckleberry.canonical.com (huckleberry.canonical.com\n\t[91.189.94.19])\n\tby ozlabs.org (Postfix) with ESMTP id 3xnSk54gJsz9sNV;\n\tThu,  7 Sep 2017 01:51:25 +1000 (AEST)",
            "from localhost ([127.0.0.1] helo=huckleberry.canonical.com)\n\tby huckleberry.canonical.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1dpcbq-0003Fx-QR; Wed, 06 Sep 2017 15:51:22 +0000",
            "from youngberry.canonical.com ([91.189.89.112])\n\tby huckleberry.canonical.com with esmtps\n\t(TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128)\n\t(Exim 4.86_2) (envelope-from <juerg.haefliger@canonical.com>)\n\tid 1dpcbn-0003EW-Q9\n\tfor kernel-team@lists.ubuntu.com; Wed, 06 Sep 2017 15:51:19 +0000",
            "from mail-wm0-f71.google.com ([74.125.82.71])\n\tby youngberry.canonical.com with esmtps\n\t(TLS1.0:RSA_AES_128_CBC_SHA1:16)\n\t(Exim 4.76) (envelope-from <juerg.haefliger@canonical.com>)\n\tid 1dpcbn-00015j-Br\n\tfor kernel-team@lists.ubuntu.com; Wed, 06 Sep 2017 15:51:19 +0000",
            "by mail-wm0-f71.google.com with SMTP id 187so6461857wmn.2\n\tfor <kernel-team@lists.ubuntu.com>;\n\tWed, 06 Sep 2017 08:51:19 -0700 (PDT)",
            "from gollum.fritz.box (adsl-84-227-115-101.adslplus.ch.\n\t[84.227.115.101]) by smtp.gmail.com with ESMTPSA id\n\tx28sm1606799edd.83.2017.09.06.08.51.17\n\tfor <kernel-team@lists.ubuntu.com>\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 06 Sep 2017 08:51:17 -0700 (PDT)"
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=B2R+PKto2f6zvTf/UDIKUcJgK2bEteMFPmVhhkBbYnY=;\n\tb=Mw4p7gpm5XAAZjZeQX/vEQjgmSJyUIv1awE9CjdHL6qqobkaBaUsaKDyHj8fgyb+Gb\n\thcCYmecglhqvHIVYZGrYWzucTwy3fo2A3Z6AB2abIihbmfxeNG0mFIwLAkNbE7XQFxMZ\n\tmjK35RntHWP9/zsHkhEnbDpjn+H1agrY9y/d5FotMXYi5r0TmYLS0Yt4rANvGsIe806h\n\t0TCtnGBGg+TzFpRzwlWWG1sffTiDK+v+peOZSUNWmbGEJQczD7+p9haWDP7dORz6zO74\n\tTJl6IJK/xDwAOyQcGdi3kNSHyOSKSXjnB3d87jcp08d5eMq7/HkTzSj/nMILxmJ8Lwl+\n\tWNQg==",
        "X-Gm-Message-State": "AHPjjUjAh0pV1B+F+rgnm7bqK4c7DlC3OsanF3RAVUrhZeZCeAAGvz8v\n\tQcB28djVJMdADEglPH3tS7/z27IO1ae3XcW4HsH07uOZSbiw531appbKPmmyTUAUGfW4oDSE1ts\n\tAzZVgWGJMLX5pSIN7DubQu474SEptyks8",
        "X-Received": [
            "by 10.80.206.68 with SMTP id k4mr171710edj.48.1504713078634;\n\tWed, 06 Sep 2017 08:51:18 -0700 (PDT)",
            "by 10.80.206.68 with SMTP id k4mr171691edj.48.1504713078190;\n\tWed, 06 Sep 2017 08:51:18 -0700 (PDT)"
        ],
        "X-Google-Smtp-Source": "ADKCNb4vb2kXbzRqOoO8lu8RTcO6U863kEscv3I4NfBlJnvyYNRoY66CsLVpNtI+ZAVl/a24ucfirQ==",
        "From": "Juerg Haefliger <juerg.haefliger@canonical.com>",
        "To": "kernel-team@lists.ubuntu.com",
        "Subject": "[trusty CVE-2016-7097 v2 1/1] posix_acl: Clear SGID bit when setting\n\tfile permissions",
        "Date": "Wed,  6 Sep 2017 17:51:15 +0200",
        "Message-Id": "<20170906155115.24400-2-juerg.haefliger@canonical.com>",
        "X-Mailer": "git-send-email 2.14.1",
        "In-Reply-To": "<20170906155115.24400-1-juerg.haefliger@canonical.com>",
        "References": "<20170906085453.22382-1-juerg.haefliger@canonical.com>\n\t<20170906155115.24400-1-juerg.haefliger@canonical.com>",
        "X-BeenThere": "kernel-team@lists.ubuntu.com",
        "X-Mailman-Version": "2.1.20",
        "Precedence": "list",
        "List-Id": "Kernel team discussions <kernel-team.lists.ubuntu.com>",
        "List-Unsubscribe": "<https://lists.ubuntu.com/mailman/options/kernel-team>,\n\t<mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>",
        "List-Archive": "<https://lists.ubuntu.com/archives/kernel-team>",
        "List-Post": "<mailto:kernel-team@lists.ubuntu.com>",
        "List-Help": "<mailto:kernel-team-request@lists.ubuntu.com?subject=help>",
        "List-Subscribe": "<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n\t<mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "kernel-team-bounces@lists.ubuntu.com",
        "Sender": "\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>"
    },
    "content": "From: Jan Kara <jack@suse.cz>\n\ncommit 073931017b49d9458aa351605b43a7e34598caef upstream.\n\nWhen file permissions are modified via chmod(2) and the user is not in\nthe owning group or capable of CAP_FSETID, the setgid bit is cleared in\ninode_change_ok().  Setting a POSIX ACL via setxattr(2) sets the file\npermissions as well as the new ACL, but doesn't clear the setgid bit in\na similar way; this allows to bypass the check in chmod(2).  Fix that.\n\nReferences: CVE-2016-7097\nReviewed-by: Christoph Hellwig <hch@lst.de>\nReviewed-by: Jeff Layton <jlayton@redhat.com>\nSigned-off-by: Jan Kara <jack@suse.cz>\nSigned-off-by: Andreas Gruenbacher <agruenba@redhat.com>\n[bwh: Backported to 3.16:\n - Drop changes to orangefs\n - Adjust context\n - Update ext3 as well]\nSigned-off-by: Ben Hutchings <ben@decadent.org.uk>\n\nCVE-2016-7097\n\n(backported from f2ba3e2310b3967720b83126db8684c69ce41894 3.16.y)\n[juergh: Backported to 3.13:\n - Drop changes to ceph\n - Update generic_acl.c as well\n - In gfs2, jfs, and xfs, take care to avoid leaking the allocated ACL if\n   posix_acl_update_mode() determines it's not needed]\nSigned-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>\n---\n fs/9p/acl.c               | 40 +++++++++++++++++-----------------------\n fs/btrfs/acl.c            |  6 ++----\n fs/ext2/acl.c             | 12 ++++--------\n fs/ext3/acl.c             | 12 ++++--------\n fs/ext4/acl.c             | 12 ++++--------\n fs/f2fs/acl.c             |  6 ++----\n fs/generic_acl.c          | 15 ++++++++-------\n fs/gfs2/acl.c             | 16 +++++++---------\n fs/hfsplus/posix_acl.c    |  4 ++--\n fs/jffs2/acl.c            |  9 ++++-----\n fs/jfs/xattr.c            |  6 ++++--\n fs/ocfs2/acl.c            |  9 +++------\n fs/posix_acl.c            | 31 +++++++++++++++++++++++++++++++\n fs/reiserfs/xattr_acl.c   |  8 ++------\n fs/xfs/xfs_acl.c          | 17 +++++++----------\n include/linux/posix_acl.h |  1 +\n 16 files changed, 102 insertions(+), 102 deletions(-)",
    "diff": "diff --git a/fs/9p/acl.c b/fs/9p/acl.c\nindex 7af425f53bee..9686c1f17653 100644\n--- a/fs/9p/acl.c\n+++ b/fs/9p/acl.c\n@@ -320,32 +320,26 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,\n \tcase ACL_TYPE_ACCESS:\n \t\tname = POSIX_ACL_XATTR_ACCESS;\n \t\tif (acl) {\n-\t\t\tumode_t mode = inode->i_mode;\n-\t\t\tretval = posix_acl_equiv_mode(acl, &mode);\n-\t\t\tif (retval < 0)\n+\t\t\tstruct iattr iattr;\n+\n+\t\t\tretval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);\n+\t\t\tif (retval)\n \t\t\t\tgoto err_out;\n-\t\t\telse {\n-\t\t\t\tstruct iattr iattr;\n-\t\t\t\tif (retval == 0) {\n-\t\t\t\t\t/*\n-\t\t\t\t\t * ACL can be represented\n-\t\t\t\t\t * by the mode bits. So don't\n-\t\t\t\t\t * update ACL.\n-\t\t\t\t\t */\n-\t\t\t\t\tacl = NULL;\n-\t\t\t\t\tvalue = NULL;\n-\t\t\t\t\tsize = 0;\n-\t\t\t\t}\n-\t\t\t\t/* Updte the mode bits */\n-\t\t\t\tiattr.ia_mode = ((mode & S_IALLUGO) |\n-\t\t\t\t\t\t (inode->i_mode & ~S_IALLUGO));\n-\t\t\t\tiattr.ia_valid = ATTR_MODE;\n-\t\t\t\t/* FIXME should we update ctime ?\n-\t\t\t\t * What is the following setxattr update the\n-\t\t\t\t * mode ?\n+\t\t\tif (!acl) {\n+\t\t\t\t/*\n+\t\t\t\t * ACL can be represented\n+\t\t\t\t * by the mode bits. So don't\n+\t\t\t\t * update ACL.\n \t\t\t\t */\n-\t\t\t\tv9fs_vfs_setattr_dotl(dentry, &iattr);\n+\t\t\t\tvalue = NULL;\n+\t\t\t\tsize = 0;\n \t\t\t}\n+\t\t\tiattr.ia_valid = ATTR_MODE;\n+\t\t\t/* FIXME should we update ctime ?\n+\t\t\t * What is the following setxattr update the\n+\t\t\t * mode ?\n+\t\t\t */\n+\t\t\tv9fs_vfs_setattr_dotl(dentry, &iattr);\n \t\t}\n \t\tbreak;\n \tcase ACL_TYPE_DEFAULT:\ndiff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c\nindex 0890c83643e9..d6d53e5e7945 100644\n--- a/fs/btrfs/acl.c\n+++ b/fs/btrfs/acl.c\n@@ -118,11 +118,9 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,\n \tcase ACL_TYPE_ACCESS:\n \t\tname = POSIX_ACL_XATTR_ACCESS;\n \t\tif (acl) {\n-\t\t\tret = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (ret < 0)\n+\t\t\tret = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (ret)\n \t\t\t\treturn ret;\n-\t\t\tif (ret == 0)\n-\t\t\t\tacl = NULL;\n \t\t}\n \t\tret = 0;\n \t\tbreak;\ndiff --git a/fs/ext2/acl.c b/fs/ext2/acl.c\nindex 110b6b371a4e..48c3c2d7d261 100644\n--- a/fs/ext2/acl.c\n+++ b/fs/ext2/acl.c\n@@ -206,15 +206,11 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)\n \t\tcase ACL_TYPE_ACCESS:\n \t\t\tname_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;\n \t\t\tif (acl) {\n-\t\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\t\tif (error < 0)\n+\t\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\t\tif (error)\n \t\t\t\t\treturn error;\n-\t\t\t\telse {\n-\t\t\t\t\tinode->i_ctime = CURRENT_TIME_SEC;\n-\t\t\t\t\tmark_inode_dirty(inode);\n-\t\t\t\t\tif (error == 0)\n-\t\t\t\t\t\tacl = NULL;\n-\t\t\t\t}\n+\t\t\t\tinode->i_ctime = CURRENT_TIME_SEC;\n+\t\t\t\tmark_inode_dirty(inode);\n \t\t\t}\n \t\t\tbreak;\n \ndiff --git a/fs/ext3/acl.c b/fs/ext3/acl.c\nindex dbb5ad59a7fc..bb2f60a62d82 100644\n--- a/fs/ext3/acl.c\n+++ b/fs/ext3/acl.c\n@@ -205,15 +205,11 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,\n \t\tcase ACL_TYPE_ACCESS:\n \t\t\tname_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;\n \t\t\tif (acl) {\n-\t\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\t\tif (error < 0)\n+\t\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\t\tif (error)\n \t\t\t\t\treturn error;\n-\t\t\t\telse {\n-\t\t\t\t\tinode->i_ctime = CURRENT_TIME_SEC;\n-\t\t\t\t\text3_mark_inode_dirty(handle, inode);\n-\t\t\t\t\tif (error == 0)\n-\t\t\t\t\t\tacl = NULL;\n-\t\t\t\t}\n+\t\t\t\tinode->i_ctime = CURRENT_TIME_SEC;\n+\t\t\t\text3_mark_inode_dirty(handle, inode);\n \t\t\t}\n \t\t\tbreak;\n \ndiff --git a/fs/ext4/acl.c b/fs/ext4/acl.c\nindex 39a54a0e9fe4..c844f1bfb451 100644\n--- a/fs/ext4/acl.c\n+++ b/fs/ext4/acl.c\n@@ -211,15 +211,11 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,\n \tcase ACL_TYPE_ACCESS:\n \t\tname_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;\n \t\tif (acl) {\n-\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (error < 0)\n+\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (error)\n \t\t\t\treturn error;\n-\t\t\telse {\n-\t\t\t\tinode->i_ctime = ext4_current_time(inode);\n-\t\t\t\text4_mark_inode_dirty(handle, inode);\n-\t\t\t\tif (error == 0)\n-\t\t\t\t\tacl = NULL;\n-\t\t\t}\n+\t\t\tinode->i_ctime = ext4_current_time(inode);\n+\t\t\text4_mark_inode_dirty(handle, inode);\n \t\t}\n \t\tbreak;\n \ndiff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c\nindex d0fc287efeff..0eb2d66827ad 100644\n--- a/fs/f2fs/acl.c\n+++ b/fs/f2fs/acl.c\n@@ -224,12 +224,10 @@ static int f2fs_set_acl(struct inode *inode, int type,\n \tcase ACL_TYPE_ACCESS:\n \t\tname_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;\n \t\tif (acl) {\n-\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (error < 0)\n+\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (error)\n \t\t\t\treturn error;\n \t\t\tset_acl_inode(fi, inode->i_mode);\n-\t\t\tif (error == 0)\n-\t\t\t\tacl = NULL;\n \t\t}\n \t\tbreak;\n \ndiff --git a/fs/generic_acl.c b/fs/generic_acl.c\nindex b3f3676796d3..67319f168b42 100644\n--- a/fs/generic_acl.c\n+++ b/fs/generic_acl.c\n@@ -86,16 +86,17 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,\n \t\tif (error)\n \t\t\tgoto failed;\n \t\tswitch (type) {\n-\t\tcase ACL_TYPE_ACCESS:\n-\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (error < 0)\n+\t\tcase ACL_TYPE_ACCESS: {\n+\t\t\tstruct posix_acl *saved_acl = acl;\n+\n+\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (acl == NULL)\n+\t\t\t\tposix_acl_release(saved_acl);\n+\t\t\tif (error)\n \t\t\t\tgoto failed;\n \t\t\tinode->i_ctime = CURRENT_TIME;\n-\t\t\tif (error == 0) {\n-\t\t\t\tposix_acl_release(acl);\n-\t\t\t\tacl = NULL;\n-\t\t\t}\n \t\t\tbreak;\n+\t\t}\n \t\tcase ACL_TYPE_DEFAULT:\n \t\t\tif (!S_ISDIR(inode->i_mode)) {\n \t\t\t\terror = -EINVAL;\ndiff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c\nindex f69ac0af5496..015809a066b5 100644\n--- a/fs/gfs2/acl.c\n+++ b/fs/gfs2/acl.c\n@@ -267,16 +267,14 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,\n \t\tgoto out_release;\n \n \tif (type == ACL_TYPE_ACCESS) {\n-\t\tumode_t mode = inode->i_mode;\n-\t\terror = posix_acl_equiv_mode(acl, &mode);\n+\t\tstruct posix_acl *saved_acl = acl;\n+\t\tumode_t mode;\n \n-\t\tif (error <= 0) {\n-\t\t\tposix_acl_release(acl);\n-\t\t\tacl = NULL;\n-\n-\t\t\tif (error < 0)\n-\t\t\t\treturn error;\n-\t\t}\n+\t\terror = posix_acl_update_mode(inode, &mode, &acl);\n+\t\tif (error || acl == NULL)\n+\t\t\tposix_acl_release(saved_acl);\n+\t\tif (error)\n+\t\t\treturn error;\n \n \t\terror = gfs2_set_mode(inode, mode);\n \t\tif (error)\ndiff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c\nindex b609cc14c72e..9f7cc491ffb1 100644\n--- a/fs/hfsplus/posix_acl.c\n+++ b/fs/hfsplus/posix_acl.c\n@@ -72,8 +72,8 @@ static int hfsplus_set_posix_acl(struct inode *inode,\n \tcase ACL_TYPE_ACCESS:\n \t\txattr_name = POSIX_ACL_XATTR_ACCESS;\n \t\tif (acl) {\n-\t\t\terr = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (err < 0)\n+\t\t\terr = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (err)\n \t\t\t\treturn err;\n \t\t}\n \t\terr = 0;\ndiff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c\nindex 223283c30111..9335b8d3cf52 100644\n--- a/fs/jffs2/acl.c\n+++ b/fs/jffs2/acl.c\n@@ -243,9 +243,10 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)\n \tcase ACL_TYPE_ACCESS:\n \t\txprefix = JFFS2_XPREFIX_ACL_ACCESS;\n \t\tif (acl) {\n-\t\t\tumode_t mode = inode->i_mode;\n-\t\t\trc = posix_acl_equiv_mode(acl, &mode);\n-\t\t\tif (rc < 0)\n+\t\t\tumode_t mode;\n+\n+\t\t\trc = posix_acl_update_mode(inode, &mode, &acl);\n+\t\t\tif (rc)\n \t\t\t\treturn rc;\n \t\t\tif (inode->i_mode != mode) {\n \t\t\t\tstruct iattr attr;\n@@ -257,8 +258,6 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)\n \t\t\t\tif (rc < 0)\n \t\t\t\t\treturn rc;\n \t\t\t}\n-\t\t\tif (rc == 0)\n-\t\t\t\tacl = NULL;\n \t\t}\n \t\tbreak;\n \tcase ACL_TYPE_DEFAULT:\ndiff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c\nindex d3472f4cd530..6910662a8bf5 100644\n--- a/fs/jfs/xattr.c\n+++ b/fs/jfs/xattr.c\n@@ -693,9 +693,11 @@ static int can_set_system_xattr(struct inode *inode, const char *name,\n \t\t\treturn rc;\n \t\t}\n \t\tif (acl) {\n-\t\t\trc = posix_acl_equiv_mode(acl, &inode->i_mode);\n+\t\t\tstruct posix_acl *dummy = acl;\n+\n+\t\t\trc = posix_acl_update_mode(inode, &inode->i_mode, &dummy);\n \t\t\tposix_acl_release(acl);\n-\t\t\tif (rc < 0) {\n+\t\t\tif (rc) {\n \t\t\t\tprintk(KERN_ERR\n \t\t\t\t       \"posix_acl_equiv_mode returned %d\\n\",\n \t\t\t\t       rc);\ndiff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c\nindex b4f788e0ca31..b16bb5c70bc8 100644\n--- a/fs/ocfs2/acl.c\n+++ b/fs/ocfs2/acl.c\n@@ -270,14 +270,11 @@ static int ocfs2_set_acl(handle_t *handle,\n \tcase ACL_TYPE_ACCESS:\n \t\tname_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;\n \t\tif (acl) {\n-\t\t\tumode_t mode = inode->i_mode;\n-\t\t\tret = posix_acl_equiv_mode(acl, &mode);\n-\t\t\tif (ret < 0)\n+\t\t\tumode_t mode;\n+\t\t\tret = posix_acl_update_mode(inode, &mode, &acl);\n+\t\t\tif (ret)\n \t\t\t\treturn ret;\n \t\t\telse {\n-\t\t\t\tif (ret == 0)\n-\t\t\t\t\tacl = NULL;\n-\n \t\t\t\tret = ocfs2_acl_set_mode(inode, di_bh,\n \t\t\t\t\t\t\t handle, mode);\n \t\t\t\tif (ret)\ndiff --git a/fs/posix_acl.c b/fs/posix_acl.c\nindex 3542f1f814e2..7a82cf1601d5 100644\n--- a/fs/posix_acl.c\n+++ b/fs/posix_acl.c\n@@ -407,6 +407,37 @@ posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)\n }\n EXPORT_SYMBOL(posix_acl_create);\n \n+/**\n+ * posix_acl_update_mode  -  update mode in set_acl\n+ *\n+ * Update the file mode when setting an ACL: compute the new file permission\n+ * bits based on the ACL.  In addition, if the ACL is equivalent to the new\n+ * file mode, set *acl to NULL to indicate that no ACL should be set.\n+ *\n+ * As with chmod, clear the setgit bit if the caller is not in the owning group\n+ * or capable of CAP_FSETID (see inode_change_ok).\n+ *\n+ * Called from set_acl inode operations.\n+ */\n+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,\n+\t\t\t  struct posix_acl **acl)\n+{\n+\tumode_t mode = inode->i_mode;\n+\tint error;\n+\n+\terror = posix_acl_equiv_mode(*acl, &mode);\n+\tif (error < 0)\n+\t\treturn error;\n+\tif (error == 0)\n+\t\t*acl = NULL;\n+\tif (!in_group_p(inode->i_gid) &&\n+\t    !capable_wrt_inode_uidgid(inode, CAP_FSETID))\n+\t\tmode &= ~S_ISGID;\n+\t*mode_p = mode;\n+\treturn 0;\n+}\n+EXPORT_SYMBOL(posix_acl_update_mode);\n+\n int\n posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)\n {\ndiff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c\nindex 06c04f73da65..a86ad7ec7957 100644\n--- a/fs/reiserfs/xattr_acl.c\n+++ b/fs/reiserfs/xattr_acl.c\n@@ -288,13 +288,9 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,\n \tcase ACL_TYPE_ACCESS:\n \t\tname = POSIX_ACL_XATTR_ACCESS;\n \t\tif (acl) {\n-\t\t\terror = posix_acl_equiv_mode(acl, &inode->i_mode);\n-\t\t\tif (error < 0)\n+\t\t\terror = posix_acl_update_mode(inode, &inode->i_mode, &acl);\n+\t\t\tif (error)\n \t\t\t\treturn error;\n-\t\t\telse {\n-\t\t\t\tif (error == 0)\n-\t\t\t\t\tacl = NULL;\n-\t\t\t}\n \t\t}\n \t\tbreak;\n \tcase ACL_TYPE_DEFAULT:\ndiff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c\nindex 370eb3e121d1..89ac0522b38d 100644\n--- a/fs/xfs/xfs_acl.c\n+++ b/fs/xfs/xfs_acl.c\n@@ -402,17 +402,14 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,\n \t\tgoto out_release;\n \n \tif (type == ACL_TYPE_ACCESS) {\n-\t\tumode_t mode = inode->i_mode;\n-\t\terror = posix_acl_equiv_mode(acl, &mode);\n-\n-\t\tif (error <= 0) {\n-\t\t\tposix_acl_release(acl);\n-\t\t\tacl = NULL;\n-\n-\t\t\tif (error < 0)\n-\t\t\t\treturn error;\n-\t\t}\n+\t\tstruct posix_acl *saved_acl = acl;\n+\t\tumode_t mode;\n \n+\t\terror = posix_acl_update_mode(inode, &mode, &acl);\n+\t\tif (error || acl == NULL)\n+\t\t\tposix_acl_release(saved_acl);\n+\t\tif (error)\n+\t\t\treturn error;\n \t\terror = xfs_set_mode(inode, mode);\n \t\tif (error)\n \t\t\tgoto out_release;\ndiff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h\nindex 7931efe71175..2ae0bba45f12 100644\n--- a/include/linux/posix_acl.h\n+++ b/include/linux/posix_acl.h\n@@ -90,6 +90,7 @@ extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);\n extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);\n extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);\n extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);\n+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);\n \n extern struct posix_acl *get_posix_acl(struct inode *, int);\n extern int set_posix_acl(struct inode *, int, struct posix_acl *);\n",
    "prefixes": [
        "trusty",
        "CVE-2016-7097",
        "v2",
        "1/1"
    ]
}