From patchwork Wed Oct 21 09:47:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 533707 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 14A2F140DAE for ; Wed, 21 Oct 2015 20:48:24 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=0NRNu/ZR; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753631AbbJUJsT (ORCPT ); Wed, 21 Oct 2015 05:48:19 -0400 Received: from mail-wi0-f173.google.com ([209.85.212.173]:33773 "EHLO mail-wi0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752751AbbJUJsR (ORCPT ); Wed, 21 Oct 2015 05:48:17 -0400 Received: by wijp11 with SMTP id p11so86178853wij.0; Wed, 21 Oct 2015 02:48:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=4vcr9dwKQ4lTm5so1joo+F/g75gdLOPLjoGgUSZk+oA=; b=0NRNu/ZRWuQ4uzBwUvAS6M7wi2Ccvcqwzvg4KLqDFrbO/xwaMebtFQjpaPhv/i1oUz OgALi/2DE+AubmnzHMCc3+PpsrrfLYGDsbXVir9bEI/wb4gzlFoQjDAbPP/chc9WhqcP /4EM9VLjw9+PhlQBiBdCp7voFKqiGTFxZUW71l3+SVNUWTUZHVvSbpT1ajGVHL8Nqnld le2lm3qxDMh+peC1Ja3pwRGYR13tU5Bp1LvokUA+7AQQqoFqkQ8c6zsLO4oRWOTs/j4m A/XT9Teu6tVgdM70JCTNVrfhY2hxHb44TzPzgo3rwA3D58Tvd+JWq2gNU/CEvJvWye5x i0xQ== X-Received: by 10.180.82.34 with SMTP id f2mr23937302wiy.34.1445420896512; Wed, 21 Oct 2015 02:48:16 -0700 (PDT) Received: from david-t2.localdomain ([37.120.90.97]) by smtp.gmail.com with ESMTPSA id qq4sm9261939wjc.14.2015.10.21.02.48.15 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Oct 2015 02:48:15 -0700 (PDT) From: David Herrmann To: netdev@vger.kernel.org Cc: Dmitry Vyukov , David Miller , Eric Dumazet , Linus Torvalds , David Herrmann , "# 4 . 2+" Subject: [PATCH] netlink: fix locking around NETLINK_LIST_MEMBERSHIPS Date: Wed, 21 Oct 2015 11:47:43 +0200 Message-Id: <1445420863-1476-1-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 2.6.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently, NETLINK_LIST_MEMBERSHIPS grabs the netlink table while copying the membership state to user-space. However, grabing the netlink table is effectively a write_lock_irq(), and as such we should not be triggering page-faults in the critical section. This can be easily reproduced by the following snippet: int s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); void *p = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); int r = getsockopt(s, 0x10e, 9, p, (void*)((char*)p + 4092)); This should work just fine, but currently triggers EFAULT and a possible WARN_ON below handle_mm_fault(). Fix this by reducing locking of NETLINK_LIST_MEMBERSHIPS to a read-side lock. The write-lock was overkill in the first place, and the read-lock allows page-faults just fine. Cc: # 4.2+ Reported-by: Dmitry Vyukov Signed-off-by: David Herrmann --- net/netlink/af_netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8f060d7..2389602 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2371,7 +2371,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, int pos, idx, shift; err = 0; - netlink_table_grab(); + netlink_lock_table(); for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) { if (len - pos < sizeof(u32)) break; @@ -2386,7 +2386,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, } if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen)) err = -EFAULT; - netlink_table_ungrab(); + netlink_unlock_table(); break; } case NETLINK_CAP_ACK: