From patchwork Fri Apr 19 14:42:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bethany Jamison X-Patchwork-Id: 1925571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VLcn74vxVz1yPJ for ; Sat, 20 Apr 2024 00:42:35 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rxpRe-0001cZ-DV; Fri, 19 Apr 2024 14:42:30 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rxpRZ-0001XM-PU for kernel-team@lists.ubuntu.com; Fri, 19 Apr 2024 14:42:25 +0000 Received: from mail-io1-f72.google.com (mail-io1-f72.google.com [209.85.166.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 8EDF83F16A for ; Fri, 19 Apr 2024 14:42:25 +0000 (UTC) Received: by mail-io1-f72.google.com with SMTP id ca18e2360f4ac-7da42114485so154770439f.2 for ; Fri, 19 Apr 2024 07:42:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713537744; x=1714142544; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6HFPC1Pz3GJjb42KP4/2IBIIUH3zVDpIH3QVVJ/V8S8=; b=lC2w487ODEjZr5zLWcL0ryjAusfJ31pLnyT2NNCeN1k079RnJ/gCF3HPlnm1pc+7ec CBQVmt+NBUuJYTD4pj3l+PaEF+wNhEhuBIEs055WoIlhuwfE6vPcDHmNSyJiGLiKj7nB lKtp5rO5W+nevZ7dGcaZLTOqsmB1tt/BC3coNGOpJWC2YLE3hLu1KQLkGW8Ldk4iGUv5 +fJm+0nBEHFT3euUHwhnX6+YvBTh0pjwQDp9Q9rRC4CoO2fdAWGMpqBxV9KDenoSJK1v qmsFSaWkRdkMS2qLH74pQT2ILl+lyFAJa7uCgscuB+ezsDzRkxCp8OvZd6BeQyd4POFz rpiw== X-Gm-Message-State: AOJu0YwTUv/AJ0nBA1byAYj2ZSP4OIYn4aVq1GsOm94387u9xuEzwf7e oulOu/Df+3p+fCEiqbqbzR4TbaB8bqAR8K1VdDwo1aqbuM65/kaBOVNmgWneNa0A4SyL8ntWCOi Bdp3go6bdJLcmkuY29w1rSl4Mdh12csrWPObORGbZ0i6Sx6tt4UDexkzvDzLJpVj6ay9maeY71k V+hsF7+fgLNHK3 X-Received: by 2002:a05:6602:6603:b0:7d9:62bb:8990 with SMTP id gx3-20020a056602660300b007d962bb8990mr3048152iob.13.1713537744294; Fri, 19 Apr 2024 07:42:24 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHcL9uXKp+lhVqPbjb3OUVuTH/GMjxmDfVAM9sRCvr15MD1W2t+S3lhkpKfXLBEKb/H1daGlA== X-Received: by 2002:a05:6602:6603:b0:7d9:62bb:8990 with SMTP id gx3-20020a056602660300b007d962bb8990mr3048130iob.13.1713537743872; Fri, 19 Apr 2024 07:42:23 -0700 (PDT) Received: from smtp.gmail.com (104-218-69-129.dynamic.lnk.ne.allofiber.net. [104.218.69.129]) by smtp.gmail.com with ESMTPSA id i10-20020a05663813ca00b00482d033889csm1089235jaj.171.2024.04.19.07.42.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Apr 2024 07:42:23 -0700 (PDT) From: Bethany Jamison To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 2/3] net: dev: Convert sa_data to flexible array in struct sockaddr Date: Fri, 19 Apr 2024 09:42:15 -0500 Message-Id: <20240419144219.21413-4-bethany.jamison@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240419144219.21413-1-bethany.jamison@canonical.com> References: <20240419144219.21413-1-bethany.jamison@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Kees Cook One of the worst offenders of "fake flexible arrays" is struct sockaddr, as it is the classic example of why GCC and Clang have been traditionally forced to treat all trailing arrays as fake flexible arrays: in the distant misty past, sa_data became too small, and code started just treating it as a flexible array, even though it was fixed-size. The special case by the compiler is specifically that sizeof(sa->sa_data) and FORTIFY_SOURCE (which uses __builtin_object_size(sa->sa_data, 1)) do not agree (14 and -1 respectively), which makes FORTIFY_SOURCE treat it as a flexible array. However, the coming -fstrict-flex-arrays compiler flag will remove these special cases so that FORTIFY_SOURCE can gain coverage over all the trailing arrays in the kernel that are _not_ supposed to be treated as a flexible array. To deal with this change, convert sa_data to a true flexible array. To keep the structure size the same, move sa_data into a union with a newly introduced sa_data_min with the original size. The result is that FORTIFY_SOURCE can continue to have no idea how large sa_data may actually be, but anything using sizeof(sa->sa_data) must switch to sizeof(sa->sa_data_min). Cc: Jens Axboe Cc: Pavel Begunkov Cc: David Ahern Cc: Dylan Yudaken Cc: Yajun Deng Cc: Petr Machata Cc: Hangbin Liu Cc: Leon Romanovsky Cc: syzbot Cc: Willem de Bruijn Cc: Pablo Neira Ayuso Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221018095503.never.671-kees@kernel.org Signed-off-by: Jakub Kicinski (cherry picked from commit b5f0de6df6dce8d641ef58ef7012f3304dffb9a1) CVE-2024-26733 Signed-off-by: Bethany Jamison --- include/linux/socket.h | 5 ++++- net/core/dev.c | 2 +- net/core/dev_ioctl.c | 2 +- net/packet/af_packet.c | 10 +++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 041d6032a3489..4c5ce8124f8e7 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -31,7 +31,10 @@ typedef __kernel_sa_family_t sa_family_t; struct sockaddr { sa_family_t sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ + union { + char sa_data_min[14]; /* Minimum 14 bytes of protocol address */ + DECLARE_FLEX_ARRAY(char, sa_data); + }; }; struct linger { diff --git a/net/core/dev.c b/net/core/dev.c index 8501645ff67dd..af77dc77eb9c8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9090,7 +9090,7 @@ EXPORT_SYMBOL(dev_set_mac_address_user); int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name) { - size_t size = sizeof(sa->sa_data); + size_t size = sizeof(sa->sa_data_min); struct net_device *dev; int ret = 0; diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 0e87237fd8712..6ddfd7bfc5127 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -339,7 +339,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, if (ifr->ifr_hwaddr.sa_family != dev->type) return -EINVAL; memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, - min(sizeof(ifr->ifr_hwaddr.sa_data), + min(sizeof(ifr->ifr_hwaddr.sa_data_min), (size_t)dev->addr_len)); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); return 0; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d62f79cf873dd..75fb80717e489 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3252,7 +3252,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; - char name[sizeof(uaddr->sa_data) + 1]; + char name[sizeof(uaddr->sa_data_min) + 1]; /* * Check legality @@ -3263,8 +3263,8 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, /* uaddr->sa_data comes from the userspace, it's not guaranteed to be * zero-terminated. */ - memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); - name[sizeof(uaddr->sa_data)] = 0; + memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data_min)); + name[sizeof(uaddr->sa_data_min)] = 0; return packet_do_bind(sk, name, 0, 0); } @@ -3536,11 +3536,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, return -EOPNOTSUPP; uaddr->sa_family = AF_PACKET; - memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); + memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data_min)); rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex)); if (dev) - strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); + strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data_min)); rcu_read_unlock(); return sizeof(*uaddr);