From patchwork Sat Mar 9 07:53:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587507 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 383D0208A8 for ; Sat, 9 Mar 2024 07:53:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970811; cv=none; b=R1BpOcpVOrFEv33x75jV9HIOszb9cFQfmd68ntvjrUIow8yBg0ZC4ibPr+AVIYyoQi0peWEFaFjT84sMkTXDq2WWbjqBcKMcqwkbcG6/SRP769EPFnRnXFD4UU/t1XbbWTQAen57M8TMTMzKNWdud6U7MGqu3iTED13ZSyyXWhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970811; c=relaxed/simple; bh=JBv0CKC61uVUxO4D9yRzCL2222gy1h0jRsw5TGJxmDY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cWGLfwnrT6SNeZGbgHqiltLKJVFKXYRiH2BjIC8zvjrwjQWpLZhiOiVqp2gLinmQhDttBmpQf5hj6IGZga/9A3imre/bd76e2Od3Xqy90+FmN5BRkDTZg2eodmIZlkkk2t3l4s088f/nhorazowQ7FsX5aukRiMHzWmYvnhWT98= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=vY8G0OnC; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vY8G0OnC" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-a4531df8727so59404466b.2 for ; Fri, 08 Mar 2024 23:53:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970808; x=1710575608; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=jATtGk1IqW9zkJU7m3Bn1lFjX0fb9etunp774c+XeqQ=; b=vY8G0OnC4dc5jJHJoM9IoDkTMRM0L6kbmsE83gULWMQk8D43m+zOhMHAIJYE4ErdAb rGIX5LDBjQuuGjOytZ23I1UAmBwXaHLP4vMGWtE53IM1yPmE6pyz3o5jIczGL0gkryJb inYdc2Fc0Evcvl9fi8eWu9t89WkTUQBpuVwTaCgxnAYginzuT0pY77cVZKzb+nhtjBlx D1igi39EHaCyXKfXhqomn3K7/eRzND8jvnlqLDyuIPt5IXhsUEMGGKbiGPbyJRuOSNwA jcI5ELznlDDoYWFcKZfNt3joaN6+grWpE3raoSvv1TfHpb6CWrc1goV5SvyUEJCK29Jl iKxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970808; x=1710575608; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=jATtGk1IqW9zkJU7m3Bn1lFjX0fb9etunp774c+XeqQ=; b=JtOiq5UoBOJEvS2bbKaqtiVuURzS7YRCV40ZndHGuLGGZeiJv4F+pb3wJb9lIzfU5C IoQurxYVn5IqoHvffvc5bhoD6r+fxZEqXET3EqVLL1I0rE3Av/pS7IDwSDXyLN/lRng1 v8g5AJqe/UdpxMmvRX8trVwq/4RZekXdc0Ob5DDGsh1A+uSrkxd/yDWtR56PMUYxTcRw zdETJm7R2Bmc0Grgnvom0+s9PAuzTh5zM2+MtFf3j9TT4phm0XtQYot8C1gps338Di76 06drxgcmYeP1Au0my8X15Ze35TKnL8dCKDV2SWWSvKFHnial6a1EgbpF9ttq6UxL1vaS NIWw== X-Gm-Message-State: AOJu0YyV7N0LkmKb94S0c0d/Mvr/HtvGnP3Z5MH6+RpSpd3G4h8o9oBe FAgh3+dejuk1gv7w8FwG2TC50hgyL5OHb02QYE4085DsO2Yo3h5eTHCQ6Fbpp9suQmvG/r2IJpw w+2g+GDJNN6fjTvYZFgnTd2t6VinRnaz65C+LqGjtE6jsy5vrTvtQalD9GLV3v7iMHz7JkkR1Kp b2GgJzMkeNwtqZVQrsABOhYsH56oheIM5rdsw8sFeiFJ+6AjB4zuwL X-Google-Smtp-Source: AGHT+IGZGv5WCrNTmbT0r7trdGDMvxq3sD+PnYOLejyqPwQMPJhFX74hvRdaAreQCCAnTjLS5K01DZVz1PY= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a17:906:99d6:b0:a3f:40ab:7677 with SMTP id s22-20020a17090699d600b00a3f40ab7677mr1653ejn.12.1709970807232; Fri, 08 Mar 2024 23:53:27 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:12 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-2-gnoack@google.com> Subject: [PATCH v10 1/9] security: Create security_file_vfs_ioctl hook From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " , Christian Brauner , Dave Chinner This LSM hook gets called just before the fs/ioctl.c logic delegates the requested IOCTL command to the file-specific implementation as implemented by f_op->unlocked_ioctl (or f_op->ioctl_compat). It is impractical for LSMs to make security guarantees about these f_op operations without having intimate knowledge of how they are implemented. Therefore, depending on the enabled Landlock policy, Landlock aims to block the calls to filp->f_op->unlocked_ioctl(), but permit the calls to the IOCTL commands which are already implemented in fs/ioctl.c. The current call graph is: * ioctl syscall * security_file_ioctl() LSM hook * do_vfs_ioctl() - standard operations * file_ioctl() - standard file operations * vfs_ioctl() - delegate to file (if do_vfs_ioctl() is a no-op) * filp->f_op->unlocked_ioctl() Why not use the existing security_file_ioctl() hook? With the existing security_file_ioctl() hook, it is technically feasible to prevent the call to filp->f_op->unlocked_ioctl(), but it would be difficult to maintain: security_file_ioctl() gets called further up the call stack, so an implementation of it would need to predict whether the logic further below will decide to call f_op->unlocked_ioctl(). That can only be done by mirroring the logic in do_vfs_ioctl() to some extent, and keeping this in sync. We therefore think that it is cleaner to add a new LSM hook, which gets called closer to the security boundary which we actually want to block, filp->f_op->unlocked_ioctl(). Why is it difficult to reason about f_op->unlocked_ioctl()? The unlocked_ioctl() and ioctl_compat() operations generally do the following things: 1. Execute code depending on the IOCTL command number, to implement the IOCTL command. 2. Execute code independent(!) of the IOCTL command number, usually to implement common locking and resource allocation behavior. Notably, this often happens before(!) the implementation looks at the command number. Due to the number of device drivers in Linux, it is infeasible for LSM maintainers to keep track of what these implementations do in detail. Due to 2., even permitting selected IOCTL command numbers to be implemented by devices would probably be a mistake, because even when a device does not implement a given IOCTL command, it might still execute code when you try to call it. Cc: Paul Moore Cc: Arnd Bergmann Cc: Christian Brauner Cc: Dave Chinner Cc: Mickaël Salaün Signed-off-by: Günther Noack --- fs/ioctl.c | 14 ++++++++++++-- include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 8 ++++++++ security/security.c | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index 76cf22ac97d7..e0a8ce300dcd 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -43,10 +43,16 @@ */ long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int error = -ENOTTY; + int error; + + error = security_file_vfs_ioctl(filp, cmd, arg); + if (error) + goto out; - if (!filp->f_op->unlocked_ioctl) + if (!filp->f_op->unlocked_ioctl) { + error = -ENOTTY; goto out; + } error = filp->f_op->unlocked_ioctl(filp, cmd, arg); if (error == -ENOIOCTLCMD) @@ -967,6 +973,10 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, if (error != -ENOIOCTLCMD) break; + error = security_file_vfs_ioctl(f.file, cmd, arg); + if (error != 0) + break; + if (f.file->f_op->compat_ioctl) error = f.file->f_op->compat_ioctl(f.file, cmd, arg); if (error == -ENOIOCTLCMD) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 76458b6d53da..d8a7c49b7eef 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -173,6 +173,8 @@ LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, unsigned long arg) LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd, unsigned long arg) +LSM_HOOK(int, 0, file_vfs_ioctl, struct file *file, unsigned int cmd, + unsigned long arg) LSM_HOOK(int, 0, mmap_addr, unsigned long addr) LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) diff --git a/include/linux/security.h b/include/linux/security.h index d0eb20f90b26..05a2e1852f66 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -396,6 +396,8 @@ void security_file_free(struct file *file); int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int security_file_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg); +int security_file_vfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags); int security_mmap_addr(unsigned long addr); @@ -1011,6 +1013,12 @@ static inline int security_file_ioctl_compat(struct file *file, return 0; } +static inline int security_file_vfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return 0; +} + static inline int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { diff --git a/security/security.c b/security/security.c index 7035ee35a393..15c635cd8366 100644 --- a/security/security.c +++ b/security/security.c @@ -2745,6 +2745,28 @@ int security_file_ioctl_compat(struct file *file, unsigned int cmd, } EXPORT_SYMBOL_GPL(security_file_ioctl_compat); +/** + * security_file_vfs_ioctl() - Check if a ioctl implemented by the file is allowed + * @file: associated file + * @cmd: ioctl cmd + * @arg: ioctl arguments + * + * Check permission for an ioctl operation on @file. Note that @arg sometimes + * represents a user space pointer; in other cases, it may be a simple integer + * value. When @arg represents a user space pointer, it should never be used + * by the security module. + * + * This hook is checked just before calling f_op->unlocked_ioctl() or + * f_op->compat_ioctl(). + * + * Return: Returns 0 if permission is granted. + */ +int security_file_vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return call_int_hook(file_vfs_ioctl, 0, file, cmd, arg); +} +EXPORT_SYMBOL_GPL(security_file_vfs_ioctl); + static inline unsigned long mmap_prot(struct file *file, unsigned long prot) { /* From patchwork Sat Mar 9 07:53:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587508 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 808A3208A8 for ; Sat, 9 Mar 2024 07:53:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970813; cv=none; b=ptvCtQRF6tkxdi4C61SQj7l/H4+fV0NVYBTCfNm1VUHq1jzmc01vQp+L4vFGxV5kPkIaKpm2utxsa2WLaCbiOxcBlD9y0EjL9V8z8hyaaMBotocoXAWlAqjqV5I6Qtunbum/5a7R9YBwKa48EX8F8niLsu4/R0iQxMdwJRgIn6M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970813; c=relaxed/simple; bh=wJmTGdVJAVesVzJ6a6JxcjdNRnDAjqA+pjYKlN8mId8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=eLCjxkt5bWtj/H4nZX82StoU6FI069i7LYYK0b+6isdiRULgw/QYbxaMm+d+wkDnUxuJlRIg4gqM4kyex8dSbuv/gDnCyroPl6gE29xBgehTO1OGiRWHCtHcekTS57whuDiLNb47OLL5ubGIMh4dr7+uNgqay1S87LLYxGIDWmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=WuYaBUOr; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="WuYaBUOr" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-609fe434210so29268297b3.1 for ; Fri, 08 Mar 2024 23:53:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970810; x=1710575610; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=vEp+ydMHSAWkFv/Vs8D4y4Cop1/7Ih7jN+mIT5vXzyk=; b=WuYaBUOr7PAEemRsk6lnO6e+YkDmS0pquLpT4og1kyGojH2Rg905CXLSBKDFThT3+K q4pqfGV56pNa9GqxJ/vHCudrq4f6oqL2KPHqphLzvH36YTAJvO0ipVzfwueqwGK8RPK6 Vtxkr2CYMww6oExLOEzRNw6KZnI7HgzkFOGw2DYoIZN+QfeKNO9QxhWckAVsmEEGitM5 7ZjNfEtJzWHhGZ8rclaw3UtAXvT4oCqvSZfyGBni/Gi5z87UXzLPDsPU0QscQfuoBLbj RHr6jV0mp0vVBsN+ado2/Ou8oQY4F6HVzA6GLRS7Oe6qvbkbFd9sfAC+JbE3x5ifGvCO gVZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970810; x=1710575610; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=vEp+ydMHSAWkFv/Vs8D4y4Cop1/7Ih7jN+mIT5vXzyk=; b=At818B1yw3iOqRp4ZTYCaTSiQF/HOA1/cRKjPuJGo/SlP7QUqOrEjapFpVBjICF4Za 79LKnYWZ0nMcZYlqSlg78QtLmGtKcvpTqjUlRakGQZ5PJ9wWTzl7xgm4ufrvw57TspNp KQH7WIQDHWi+9Pjl4kIG+l0lmh89CXivN+rMCzKryLLgWSiXAEi8vUxNAzTSu1BqQ81J OkQjyR6Ft9KNuaHKWCp7+Ttb1oPP2wH08C/6shPqy2RK6OnkplLvXJjxK6dP7Xc1iuAb MRGdBBEwIF+Cb0kivf6xeaI/iFlhtWGlfpMSwgQbM+d2R8OHKM51cqRqApJkIa35CZ45 oUBQ== X-Gm-Message-State: AOJu0YzbutnkJrKH1I9tQB2oPytFxavUdxAsWgudqom4giT1w1AeqHT8 GuYARU6TNv3h4VCYdjg9feUtQUdiOcEiIll5Bn0zFU/mu3Co0qT6EJMX2/omKY5wyoc/fy+z8je SdRW6wTn+WigkpwHU+9KLAotBGBO4DcI+7MbDsM9oVeHUVSpKE0NcJct/e7V7ySWnErNE1tOW4W vd3z2sdn7wNnOAGl39fmvBAfTdqLculrrce0Ivd4vcT+BMbdn6R3zk X-Google-Smtp-Source: AGHT+IE5cd51kXjWILQL+fkvPRrBN0CEn11tEraMbiaXfMc65ONft54Z67V/0ucCG1EwDaoCnawdb7tDN+c= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a5b:988:0:b0:dcc:9f24:692b with SMTP id c8-20020a5b0988000000b00dcc9f24692bmr56710ybq.13.1709970809870; Fri, 08 Mar 2024 23:53:29 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:13 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-3-gnoack@google.com> Subject: [PATCH v10 2/9] landlock: Add IOCTL access right for character and block devices From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " , Christian Brauner Introduces the LANDLOCK_ACCESS_FS_IOCTL_DEV right and increments the Landlock ABI version to 5. This access right applies to device-custom IOCTL commands when they are invoked on block or character device files. Like the truncate right, this right is associated with a file descriptor at the time of open(2), and gets respected even when the file descriptor is used outside of the thread which it was originally opened in. Therefore, a newly enabled Landlock policy does not apply to file descriptors which are already open. If the LANDLOCK_ACCESS_FS_IOCTL_DEV right is handled, only a small number of safe IOCTL commands will be permitted on newly opened device files. These include FIOCLEX, FIONCLEX, FIONBIO and FIOASYNC, as well as other IOCTL commands for regular files which are implemented in fs/ioctl.c. Noteworthy scenarios which require special attention: TTY devices are often passed into a process from the parent process, and so a newly enabled Landlock policy does not retroactively apply to them automatically. In the past, TTY devices have often supported IOCTL commands like TIOCSTI and some TIOCLINUX subcommands, which were letting callers control the TTY input buffer (and simulate keypresses). This should be restricted to CAP_SYS_ADMIN programs on modern kernels though. Known limitations: The LANDLOCK_ACCESS_FS_IOCTL_DEV access right is a coarse-grained control over IOCTL commands. Landlock users may use path-based restrictions in combination with their knowledge about the file system layout to control what IOCTLs can be done. Cc: Paul Moore Cc: Christian Brauner Cc: Arnd Bergmann Signed-off-by: Günther Noack --- include/uapi/linux/landlock.h | 35 +++++++++++++----- security/landlock/fs.c | 38 ++++++++++++++++++-- security/landlock/limits.h | 2 +- security/landlock/syscalls.c | 8 +++-- tools/testing/selftests/landlock/base_test.c | 2 +- tools/testing/selftests/landlock/fs_test.c | 5 +-- 6 files changed, 73 insertions(+), 17 deletions(-) diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index 25c8d7677539..193733d833b1 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -128,7 +128,7 @@ struct landlock_net_port_attr { * files and directories. Files or directories opened before the sandboxing * are not subject to these restrictions. * - * A file can only receive these access rights: + * The following access rights apply only to files: * * - %LANDLOCK_ACCESS_FS_EXECUTE: Execute a file. * - %LANDLOCK_ACCESS_FS_WRITE_FILE: Open a file with write access. Note that @@ -138,12 +138,13 @@ struct landlock_net_port_attr { * - %LANDLOCK_ACCESS_FS_READ_FILE: Open a file with read access. * - %LANDLOCK_ACCESS_FS_TRUNCATE: Truncate a file with :manpage:`truncate(2)`, * :manpage:`ftruncate(2)`, :manpage:`creat(2)`, or :manpage:`open(2)` with - * ``O_TRUNC``. Whether an opened file can be truncated with - * :manpage:`ftruncate(2)` is determined during :manpage:`open(2)`, in the - * same way as read and write permissions are checked during - * :manpage:`open(2)` using %LANDLOCK_ACCESS_FS_READ_FILE and - * %LANDLOCK_ACCESS_FS_WRITE_FILE. This access right is available since the - * third version of the Landlock ABI. + * ``O_TRUNC``. This access right is available since the third version of the + * Landlock ABI. + * + * Whether an opened file can be truncated with :manpage:`ftruncate(2)` or used + * with `ioctl(2)` is determined during :manpage:`open(2)`, in the same way as + * read and write permissions are checked during :manpage:`open(2)` using + * %LANDLOCK_ACCESS_FS_READ_FILE and %LANDLOCK_ACCESS_FS_WRITE_FILE. * * A directory can receive access rights related to files or directories. The * following access right is applied to the directory itself, and the @@ -198,13 +199,30 @@ struct landlock_net_port_attr { * If multiple requirements are not met, the ``EACCES`` error code takes * precedence over ``EXDEV``. * + * The following access right applies both to files and directories: + * + * - %LANDLOCK_ACCESS_FS_IOCTL_DEV: Invoke :manpage:`ioctl(2)` commands on an opened + * character or block device. + * + * This access right applies to all `ioctl(2)` commands implemented by device + * drivers. However, the following common IOCTL commands continue to be + * invokable independent of the %LANDLOCK_ACCESS_FS_IOCTL_DEV right: + * + * ``FIOCLEX``, ``FIONCLEX``, ``FIONBIO``, ``FIOASYNC``, ``FIOQSIZE``, + * ``FIFREEZE``, ``FITHAW``, ``FS_IOC_FIEMAP``, ``FIGETBSZ``, ``FICLONE``, + * ``FICLONERANGE``, ``FIDEDUPERANGE``, ``FS_IOC_GETFLAGS``, + * ``FS_IOC_SETFLAGS``, ``FS_IOC_FSGETXATTR``, ``FS_IOC_FSSETXATTR`` + * + * This access right is available since the fifth version of the Landlock + * ABI. + * * .. warning:: * * It is currently not possible to restrict some file-related actions * accessible through these syscall families: :manpage:`chdir(2)`, * :manpage:`stat(2)`, :manpage:`flock(2)`, :manpage:`chmod(2)`, * :manpage:`chown(2)`, :manpage:`setxattr(2)`, :manpage:`utime(2)`, - * :manpage:`ioctl(2)`, :manpage:`fcntl(2)`, :manpage:`access(2)`. + * :manpage:`fcntl(2)`, :manpage:`access(2)`. * Future Landlock evolutions will enable to restrict them. */ /* clang-format off */ @@ -223,6 +241,7 @@ struct landlock_net_port_attr { #define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12) #define LANDLOCK_ACCESS_FS_REFER (1ULL << 13) #define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14) +#define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15) /* clang-format on */ /** diff --git a/security/landlock/fs.c b/security/landlock/fs.c index 6f0bf1434a2c..bfa69ea94cf8 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -148,7 +148,8 @@ static struct landlock_object *get_inode_object(struct inode *const inode) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ /* @@ -1332,8 +1333,10 @@ static int hook_file_alloc_security(struct file *const file) static int hook_file_open(struct file *const file) { layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; - access_mask_t open_access_request, full_access_request, allowed_access; - const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE; + access_mask_t open_access_request, full_access_request, allowed_access, + optional_access; + const struct inode *inode = file_inode(file); + const bool is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode); const struct landlock_ruleset *const dom = get_current_fs_domain(); if (!dom) @@ -1350,6 +1353,10 @@ static int hook_file_open(struct file *const file) * We look up more access than what we immediately need for open(), so * that we can later authorize operations on opened files. */ + optional_access = LANDLOCK_ACCESS_FS_TRUNCATE; + if (is_device) + optional_access |= LANDLOCK_ACCESS_FS_IOCTL_DEV; + full_access_request = open_access_request | optional_access; if (is_access_to_paths_allowed( @@ -1406,6 +1413,30 @@ static int hook_file_truncate(struct file *const file) return -EACCES; } +static int hook_file_vfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + const struct inode *inode = file_inode(file); + const bool is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode); + access_mask_t required_access, allowed_access; + + if (!is_device) + return 0; + + /* + * It is the access rights at the time of opening the file which + * determine whether IOCTL can be used on the opened file later. + * + * The access right is attached to the opened file in hook_file_open(). + */ + required_access = LANDLOCK_ACCESS_FS_IOCTL_DEV; + allowed_access = landlock_file(file)->allowed_access; + if ((allowed_access & required_access) == required_access) + return 0; + + return -EACCES; +} + static struct security_hook_list landlock_hooks[] __ro_after_init = { LSM_HOOK_INIT(inode_free_security, hook_inode_free_security), @@ -1428,6 +1459,7 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { LSM_HOOK_INIT(file_alloc_security, hook_file_alloc_security), LSM_HOOK_INIT(file_open, hook_file_open), LSM_HOOK_INIT(file_truncate, hook_file_truncate), + LSM_HOOK_INIT(file_vfs_ioctl, hook_file_vfs_ioctl), }; __init void landlock_add_fs_hooks(void) diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 93c9c6f91556..20fdb5ff3514 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -18,7 +18,7 @@ #define LANDLOCK_MAX_NUM_LAYERS 16 #define LANDLOCK_MAX_NUM_RULES U32_MAX -#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_TRUNCATE +#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_IOCTL_DEV #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) #define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS) #define LANDLOCK_SHIFT_ACCESS_FS 0 diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 6788e73b6681..9ae3dfa47443 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -149,7 +149,7 @@ static const struct file_operations ruleset_fops = { .write = fop_dummy_write, }; -#define LANDLOCK_ABI_VERSION 4 +#define LANDLOCK_ABI_VERSION 5 /** * sys_landlock_create_ruleset - Create a new ruleset @@ -321,7 +321,11 @@ static int add_rule_path_beneath(struct landlock_ruleset *const ruleset, if (!path_beneath_attr.allowed_access) return -ENOMSG; - /* Checks that allowed_access matches the @ruleset constraints. */ + /* + * Checks that allowed_access matches the @ruleset constraints and only + * consists of publicly visible access rights (as opposed to synthetic + * ones). + */ mask = landlock_get_raw_fs_access_mask(ruleset, 0); if ((path_beneath_attr.allowed_access | mask) != mask) return -EINVAL; diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c index 646f778dfb1e..d292b419ccba 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -75,7 +75,7 @@ TEST(abi_version) const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, }; - ASSERT_EQ(4, landlock_create_ruleset(NULL, 0, + ASSERT_EQ(5, landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 2d6d9b43d958..0bcbbf594fd7 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -527,9 +527,10 @@ TEST_F_FORK(layout1, inval) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) -#define ACCESS_LAST LANDLOCK_ACCESS_FS_TRUNCATE +#define ACCESS_LAST LANDLOCK_ACCESS_FS_IOCTL_DEV #define ACCESS_ALL ( \ ACCESS_FILE | \ From patchwork Sat Mar 9 07:53:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587509 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2FD0C374FB for ; Sat, 9 Mar 2024 07:53:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970814; cv=none; b=BZ2dvPDU4sx8aJs9GuFg5vnhpT7ji59gcS5TkFGX0eGLjPfyIE/GxMFSHnZjR5TIhEpXyT5ZPFx2ZNIhMLhdVP3cidEMuZT3z/RtLdO49V0YTbeG/hhM4usDjPHfEI+SRgszPVW5ZVBmTwQf+52ldDDsuWkQ0Qv5Nlg7FP+fpfQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970814; c=relaxed/simple; bh=ww/Lbi3b5oWhje3vJaXa/bgTB/LbTEF9sD9yQf69RCw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=V8XGBVrhKLVCSdYUQ5OWaTHvoDd0UkSyaZN/FefMzb7cp1XZVFGTnsN/f3EENsNf7yiUpCaHjNsIQa34ePf0Csa6JhZRbRhPSj0Sudnb9ESFLXJUNDs87F64tu9FHejP31obmvbSEWwvra2/2innPruqhRdAm8Tx2T8YBGj2iCI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3pm9GlBU; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3pm9GlBU" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dbe9e13775aso4698598276.1 for ; Fri, 08 Mar 2024 23:53:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970812; x=1710575612; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=pjz0CSqWQYsBSnNDAgYUyOwTU5DFGITSG4sCgpVq7yg=; b=3pm9GlBUQ1KCHjDCDJXKKnrgFitl85Akal9t1r+Epq6HttfAf7ibPxgJXeZHktawAd XkCswQ3GXACkm/ZmoMah+dVALa23d8F8IjBUBcRPreMHuK24rjAovcik4LwsmQ2X74Vc oMvb/S9U7zmv0BA3jywzWm4mOIq8wRtpGEwTsQeBp6GVpJcJCljVzg4kQ3myrk5wPwrM Dac3ds3iDaGwHTYwV9QWOplU4KebQieFiTvpyaAU/ipUjRB1NLU4tOCG2rEUp3xzGlRn vKh4ZtrdUTvmtmGm2Dqrp0Km1O/p93zn00apngR8/TBNRnNJcCjQ1Fh0R4ihKOPOz6WS G7bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970812; x=1710575612; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=pjz0CSqWQYsBSnNDAgYUyOwTU5DFGITSG4sCgpVq7yg=; b=r2uAwTshZlk93gBYwpnwF0uOXt5Sp9sg7zJvkzkRSBPGOzPG57OMSwwUQbSGQ3E4u7 /GtikZL6knroKLwMphoGDFesNlYDgOkDt2RwCUQrTgn8f3w0IuGtcii6hRD9g6/30jFa nNpGlzjXXokjy+1W9dxmlJaJWOTetgHfsRnVz/Xiu6Guav4OoEXKfxmNMoB5e1N1NJaR U1qf6VFsJpMRpol0QqgxRpSHCqAZZLIYdZpKkKkEVpOa08RDlM48eRJlJvitMDb+iF3U WWV6UoFiJ2Mhr7oye92lPCYay+nLm9+KiJDt6ewzD+8rGFujwpa5wYIpPi8BG0BG24ST Ig0g== X-Gm-Message-State: AOJu0YyAaI0vDbZrf35x+49WMXRky+B6Zw57lZZuHSz/vrNqyKVP+FQv OkTs02XE6i5kFiF+EHohn4f0SSnQZ2YSfkCegmN8Kb3+CCqsKtU/6q/PUK6C+h1HhICFMYVRTLn W19SL+QO4jnwHghamxJy+9OXfXfQeoefWZAGpeVnsCA0zA8JH+csOk5ovClEX8YiIb3hOpCHn1s 9EMyEwmr9QBY+HecQnOg2Ng4mSc9unmMWNexHH1nx8tGQGX9o++nVQ X-Google-Smtp-Source: AGHT+IF/cXaUhgDCBIL4rLLvjR8a16XF+Hd8lFB/gPCt0C4vptQdgtrVoT799pakaFAnGKp5dydrvW1I980= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a25:c4c3:0:b0:dcd:ac69:eb1a with SMTP id u186-20020a25c4c3000000b00dcdac69eb1amr356402ybf.12.1709970812055; Fri, 08 Mar 2024 23:53:32 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:14 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-4-gnoack@google.com> Subject: [PATCH v10 3/9] selftests/landlock: Test IOCTL support From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Exercises Landlock's IOCTL feature in different combinations of handling and permitting the LANDLOCK_ACCESS_FS_IOCTL_DEV right, and in different combinations of using files and directories. Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 236 ++++++++++++++++++++- 1 file changed, 233 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 0bcbbf594fd7..91567e5db0fd 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -8,6 +8,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +25,12 @@ #include #include +/* + * Intentionally included last to work around header conflict. + * See https://sourceware.org/glibc/wiki/Synchronizing_Headers. + */ +#include + #include "common.h" #ifndef renameat2 @@ -735,6 +743,9 @@ static int create_ruleset(struct __test_metadata *const _metadata, } for (i = 0; rules[i].path; i++) { + if (!rules[i].access) + continue; + add_path_beneath(_metadata, ruleset_fd, rules[i].access, rules[i].path); } @@ -3443,7 +3454,7 @@ TEST_F_FORK(layout1, truncate_unhandled) LANDLOCK_ACCESS_FS_WRITE_FILE; int ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, handled, rules); ASSERT_LE(0, ruleset_fd); @@ -3526,7 +3537,7 @@ TEST_F_FORK(layout1, truncate) LANDLOCK_ACCESS_FS_TRUNCATE; int ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, handled, rules); ASSERT_LE(0, ruleset_fd); @@ -3752,7 +3763,7 @@ TEST_F_FORK(ftruncate, open_and_ftruncate) }; int fd, ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, variant->handled, rules); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); @@ -3829,6 +3840,16 @@ TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes) ASSERT_EQ(0, close(socket_fds[1])); } +/* Invokes the FS_IOC_GETFLAGS IOCTL and returns its errno or 0. */ +static int test_fs_ioc_getflags_ioctl(int fd) +{ + uint32_t flags; + + if (ioctl(fd, FS_IOC_GETFLAGS, &flags) < 0) + return errno; + return 0; +} + TEST(memfd_ftruncate) { int fd; @@ -3845,6 +3866,215 @@ TEST(memfd_ftruncate) ASSERT_EQ(0, close(fd)); } +/* clang-format off */ +FIXTURE(ioctl) {}; + +FIXTURE_SETUP(ioctl) {}; + +FIXTURE_TEARDOWN(ioctl) {}; +/* clang-format on */ + +FIXTURE_VARIANT(ioctl) +{ + const __u64 handled; + const __u64 allowed; + const mode_t open_mode; + /* + * TCGETS is used as a characteristic device-specific IOCTL command. + * The logic is the same for other IOCTL commands as well. + */ + const int expected_tcgets_result; /* terminal device IOCTL */ + /* + * FIONREAD is implemented in fs/ioctl.c for regular files, + * but we do not blanket-permit it for devices. + */ + const int expected_fionread_result; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_none) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .allowed = 0, + .open_mode = O_RDWR, + .expected_tcgets_result = EACCES, + .expected_fionread_result = EACCES, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_i) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .allowed = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .open_mode = O_RDWR, + .expected_tcgets_result = 0, + .expected_fionread_result = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, unhandled) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_EXECUTE, + .allowed = LANDLOCK_ACCESS_FS_EXECUTE, + .open_mode = O_RDWR, + .expected_tcgets_result = 0, + .expected_fionread_result = 0, +}; + +static int test_fioqsize_ioctl(int fd) +{ + size_t sz; + + if (ioctl(fd, FIOQSIZE, &sz) < 0) + return errno; + return 0; +} + +static int test_tcgets_ioctl(int fd) +{ + struct termios info; + + if (ioctl(fd, TCGETS, &info) < 0) + return errno; + return 0; +} + +static int test_fionread_ioctl(int fd) +{ + size_t sz = 0; + + if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES) + return errno; + return 0; +} + +TEST_F_FORK(ioctl, handle_dir_access_file) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev", + .access = variant->allowed, + }, + {}, + }; + int file_fd, ruleset_fd; + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + file_fd = open("/dev/tty", variant->open_mode); + ASSERT_LE(0, file_fd); + + /* Checks that IOCTL commands return the expected errors. */ + EXPECT_EQ(variant->expected_tcgets_result, test_tcgets_ioctl(file_fd)); + EXPECT_EQ(variant->expected_fionread_result, + test_fionread_ioctl(file_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(file_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag)); + EXPECT_EQ(ENOTTY, test_fioqsize_ioctl(file_fd)); + + ASSERT_EQ(0, close(file_fd)); +} + +TEST_F_FORK(ioctl, handle_dir_access_dir) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev", + .access = variant->allowed, + }, + {}, + }; + int dir_fd, ruleset_fd; + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* + * Ignore variant->open_mode for this test, as we intend to open a + * directory. If the directory can not be opened, the variant is + * infeasible to test with an opened directory. + */ + dir_fd = open("/dev", O_RDONLY); + if (dir_fd < 0) + return; + + /* + * Checks that IOCTL commands return the expected errors. + * We do not use the expected values from the fixture here. + * + * When using IOCTL on a directory, no Landlock restrictions apply. + * TCGETS will fail anyway because it is not invoked on a TTY device. + */ + EXPECT_EQ(ENOTTY, test_tcgets_ioctl(dir_fd)); + EXPECT_EQ(0, test_fionread_ioctl(dir_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(dir_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(dir_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(dir_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(dir_fd, FIOASYNC, &flag)); + EXPECT_EQ(0, test_fioqsize_ioctl(dir_fd)); + + ASSERT_EQ(0, close(dir_fd)); +} + +TEST_F_FORK(ioctl, handle_file_access_file) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev/tty0", + .access = variant->allowed, + }, + {}, + }; + int file_fd, ruleset_fd; + + if (variant->allowed & LANDLOCK_ACCESS_FS_READ_DIR) { + SKIP(return, "LANDLOCK_ACCESS_FS_READ_DIR " + "can not be granted on files"); + } + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + file_fd = open("/dev/tty0", variant->open_mode); + ASSERT_LE(0, file_fd) + { + TH_LOG("Failed to open /dev/tty0: %s", strerror(errno)); + } + + /* Checks that IOCTL commands return the expected errors. */ + EXPECT_EQ(variant->expected_tcgets_result, test_tcgets_ioctl(file_fd)); + EXPECT_EQ(variant->expected_fionread_result, + test_fionread_ioctl(file_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(file_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag)); + EXPECT_EQ(ENOTTY, test_fioqsize_ioctl(file_fd)); + + ASSERT_EQ(0, close(file_fd)); +} + /* clang-format off */ FIXTURE(layout1_bind) {}; /* clang-format on */ From patchwork Sat Mar 9 07:53:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587510 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A33E3770D for ; Sat, 9 Mar 2024 07:53:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970816; cv=none; b=BbG7+YZWUX9EFVda8iJMfPSTjknUPyP0QTTtBM2rDv+zasbWAp4eKGXhTLJMvoLaMTtrhP4HgiKnKQ/doY5Dz1Q5etQcCQfxjclOKAShCpaPSB2ENNr05Lf2VdLYGuvnoYofZoOtXzLwFMuRVDAa9xG54D+tyGd3+jx1djXE22o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970816; c=relaxed/simple; bh=/obajl3ZkTVmUpPImQ3RvaB01jwki71f/zy6U85I5dI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YVBmiRb6a1Gw/RhpFq00Sy1MHfve38kySomo9Mr1/umZvJTN3JIKYXKWyzXQiOiV81DNaMpmalyJATEmZszMASP5tyUU46l7xJ832XGP1wlxDeIt5wRNMU9yg1uVDjm2xkbXGpS7sL0exghw0DC/Xw621xkJaXjwd5OyRyU/ixY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=CwHRRfsR; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="CwHRRfsR" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dce775fa8adso4885210276.1 for ; Fri, 08 Mar 2024 23:53:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970814; x=1710575614; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=ReQG+ixmkuinsSdC9mIa5zvbWLbunHkO4cyd1gwaqNw=; b=CwHRRfsRAEboLvRB/dGeuc6idIET1LYy5XN2TlKysrd5Ibpa7ecWCXfHTJN5QE0mQO R4/eznZHDrz5f5doHFRZD0sXsuHrBgOK4/2D0bSyDpeHc/SEFTRJ8xyyRir/lJNOftNL cK1esdk+TKPijnJNQXRuYUmO64s2jlzDUau0QDr6LsXNpEnEMq1ac57kCr+wHsxIbd3d NxPhBxwPS8HVEET/4xWmBHqE/UiG7fPu5rpHqNQwxCNkhRXz1NQSsF0Fba9dHlOuZ4QK FP7AHL5/0r7MDkPu368+H4oVd2ebwod18xcAHG7jd3EDomNbxsQPIyLWALCivO+2Ll/2 7TBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970814; x=1710575614; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=ReQG+ixmkuinsSdC9mIa5zvbWLbunHkO4cyd1gwaqNw=; b=iJ6EX+grFqNf/A6xLKZBLad9W1L89gyHo51B0ZRReq6jvKlFP9oiuLCkXjkqGF+/s6 s9e6fsqRh1+7XFuIrDEnKug3GdjDYwtpytyi3+oGC/mJGQPm5GiOH1f71A6rdFOgiXkL H90Vk5PY9Iws4hc1ioZ/mt9VVZ0mns5t4G6Y3ZF4zAt2nL9eTIQw/DNFV4BiW1ngWdvB JivSOCmU78d6akW7V/UhG6bXlWMW+j4X0BrRTajgFO5RimOfwFNyxJXpKHCDJ6o2AqGh /CyZwoJ1aQ69VQLBpP3+JE3F/1wRpmuC+QB+cO1fgnpm/mR89oID/Hh79R397cnk1COm pb4A== X-Gm-Message-State: AOJu0Yz+mudBNgWWgmAcx0+qhnGfuTqwhA9gMnZxYLw3diLJuv/b2F52 vSXhmtn04Gju1OGYUzKm2WVG/6gjGkahwjFJ26Ya+kWrpYsVfZH78u6KKFVAJjpA9siEmdQFFEP 5j+MyJYdbWlz0WahqqCVyo95ibKaLrGJAabprufPD1CG37ur0rtAhpWXPzafkyyMrrUwU7qwWe/ X1izVieSKOuTwiJ0qKj2EzoIhryg25XXNGOtg0VA8V4YrfLJMUlShD X-Google-Smtp-Source: AGHT+IFsQK6KdZUXqxfmMwTeeireKmqfBtR3AMf5Sfdx/sdIj9m6huXfYFh5Tj7ElM47vS97G0KcCMnW+V8= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:1889:b0:dc6:dfc6:4207 with SMTP id cj9-20020a056902188900b00dc6dfc64207mr350796ybb.10.1709970814386; Fri, 08 Mar 2024 23:53:34 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:15 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-5-gnoack@google.com> Subject: [PATCH v10 4/9] selftests/landlock: Test IOCTL with memfds From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Because the LANDLOCK_ACCESS_FS_IOCTL_DEV right is associated with the opened file during open(2), IOCTLs are supposed to work with files which are opened by means other than open(2). Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 91567e5db0fd..f0e545c428eb 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3850,20 +3850,38 @@ static int test_fs_ioc_getflags_ioctl(int fd) return 0; } -TEST(memfd_ftruncate) +TEST(memfd_ftruncate_and_ioctl) { - int fd; - - fd = memfd_create("name", MFD_CLOEXEC); - ASSERT_LE(0, fd); + const struct landlock_ruleset_attr attr = { + .handled_access_fs = ACCESS_ALL, + }; + int ruleset_fd, fd, i; /* - * Checks that ftruncate is permitted on file descriptors that are - * created in ways other than open(2). + * We exercise the same test both with and without Landlock enabled, to + * ensure that it behaves the same in both cases. */ - EXPECT_EQ(0, test_ftruncate(fd)); + for (i = 0; i < 2; i++) { + /* Creates a new memfd. */ + fd = memfd_create("name", MFD_CLOEXEC); + ASSERT_LE(0, fd); - ASSERT_EQ(0, close(fd)); + /* + * Checks that operations associated with the opened file + * (ftruncate, ioctl) are permitted on file descriptors that are + * created in ways other than open(2). + */ + EXPECT_EQ(0, test_ftruncate(fd)); + EXPECT_EQ(0, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + } } /* clang-format off */ From patchwork Sat Mar 9 07:53:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587511 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB097374C2 for ; Sat, 9 Mar 2024 07:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970819; cv=none; b=s2EImUEdB2OJJUlwSrRDSwjJyOzdHQDI3RmhYZC+xXSdFyDn/UzU+3p8z/xtDjAC8GTHB+1bWEGj1DUiywqwgAgW3KCAyy7Pxj6t7Ww+MurYqUWGm8TT5aiPtLO297zUAU1WoMKQRalKRLL8qyRUtiEr0RLi+VWgQIphHI7Au5A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970819; c=relaxed/simple; bh=EM5NgZxl+/z295IW5qLK4Q86JjQrYvFmb5Dx8M6uibA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Dv+xHi/4kx/yx9yRao6Nnn3+xoBlryW553+lBK97QM1pLMRDUwBWcdhbjhv924uKL7sGNB9kZ1WU0WjgrLS6SGt5+4mS2kI4bXlAb1+c58BU+2sPu4a0iXfCPV9aqA69RjFDoaYLhFXdYMp0R5NybdaFHxoi+tfU6Q8BiwajMeE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kSUQ+KCL; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kSUQ+KCL" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc693399655so5296977276.1 for ; Fri, 08 Mar 2024 23:53:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970816; x=1710575616; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=vTiLehS4LJD5o9HUwzF3rxHkb5AeJhq43H6981Ab20o=; b=kSUQ+KCLY+qebDJaMmdQfkK/NBx+YmGDL631ZTJHSSGFDLjVnuJNXdf/cF61Uw2W48 MnuhEedFhP6sJElZsczvDcPt46NEcsuhaejrrdrxp9UZvDZ9xGuUHKAzDbj+0z8I759T W7HPXZG3A1sMCO53eQvMBpF8nKp2NqtVZfUE7ZrlTKloVdwckDR3sPw5qo5di67VAiYi 43/yp/p0Qwp/xHKcmQjE2kGBfb87uRGrpNWqpwT11LNEPilnu2D1MOTuy+JFimuwqZk0 WDrvPJpROKAtSj2LMCXdfGi1HzrI3FiH27quq99VHixwPyI2iClKuQlPJT3g5ilmsTpw mhTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970816; x=1710575616; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=vTiLehS4LJD5o9HUwzF3rxHkb5AeJhq43H6981Ab20o=; b=gpJiOLHKVBuONj670qtvgwn09sd1xfwWECjngWFw2N0FerujsQCOLDwjf1C8kRE2QV Jgal8u6tVuAKNBKYPCpwfsKeVzRG7XH+mGaaqkgcULmYHSlttrjSr3NYpm3piNars3yz +Vs9RXBPA5m4cqwAIKbyMAliDXsyltJxJj6KkJTiNVmXb/Ga+ZL0fG5cFdsfQSkCFm7v bPfT4csjaDfwjB5/i+cmYxi+jl44N1i6gj9TBlEPL9IWAHNadWsCf4KESt8vcU591sDl t7NBz0TLkJfPe/uc2nYwpKTUtNkB1dU126VT72S3cme01OljUb6ZigHoSgKJThlQJWlj 4wxw== X-Gm-Message-State: AOJu0YyrFQHyh2ryxJyAIBWTQ0xS4yMtAIfgnkurAnJUc1WTYLCuJUdw Bo3Zx0A7fr+khNtjx5NyOLpZBcXpsg+UCoF/e8NuOSpOcC/RgdQINqSQx+mDHCHMkVtS+nB/1at UlcG6LqQ3AyfJkXUREcumwcQRXSynnVi5mYytKp+YnVpfHpTj2K1hDI+Z01W7+DRCZIn/zPssyW KIcDTXv7eBq60SZdm8j9UwxouDBoF3cBxLePIEV1q5UEOZqo1sKjKS X-Google-Smtp-Source: AGHT+IHjhRMSidShXLUw0QQgJexcjKoFuZoKEuDKmaj/QYfeXCiIczp7cpV6e1rADR1i54xH/3kROGyCseI= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:1004:b0:dc7:48ce:d17f with SMTP id w4-20020a056902100400b00dc748ced17fmr289354ybt.10.1709970816715; Fri, 08 Mar 2024 23:53:36 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:16 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-6-gnoack@google.com> Subject: [PATCH v10 5/9] selftests/landlock: Test ioctl(2) and ftruncate(2) with open(O_PATH) From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " ioctl(2) and ftruncate(2) operations on files opened with O_PATH should always return EBADF, independent of the LANDLOCK_ACCESS_FS_TRUNCATE and LANDLOCK_ACCESS_FS_IOCTL_DEV access rights in that file hierarchy. Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index f0e545c428eb..5c47231a722e 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3884,6 +3884,46 @@ TEST(memfd_ftruncate_and_ioctl) } } +TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl) +{ + const struct landlock_ruleset_attr attr = { + .handled_access_fs = ACCESS_ALL, + }; + int ruleset_fd, fd; + + /* + * Checks that for files opened with O_PATH, both ioctl(2) and + * ftruncate(2) yield EBADF, as it is documented in open(2) for the + * O_PATH flag. + */ + fd = open(dir_s1d1, O_PATH | O_CLOEXEC); + ASSERT_LE(0, fd); + + EXPECT_EQ(EBADF, test_ftruncate(fd)); + EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* + * Checks that after enabling Landlock, + * - the file can still be opened with O_PATH + * - both ioctl and truncate still yield EBADF (not EACCES). + */ + fd = open(dir_s1d1, O_PATH | O_CLOEXEC); + ASSERT_LE(0, fd); + + EXPECT_EQ(EBADF, test_ftruncate(fd)); + EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); +} + /* clang-format off */ FIXTURE(ioctl) {}; From patchwork Sat Mar 9 07:53:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587512 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B375381B0 for ; Sat, 9 Mar 2024 07:53:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970821; cv=none; b=KuleGmopVQzQmjrCIJQu5KXdTMOMZh+vbIcYLZHVIJhR28+rWoUPX3uF0dqhHw9XHy91NsNbCO2aADiMgSgLZSsqhlZpgqQORTliPaJpMBxc4i1QxaOrPg+scOWA28enMiy7/lxTRkXKxGxOLQOMGfdKt2bskaLtjbi5JyaNTAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970821; c=relaxed/simple; bh=Z3q8TUMjwgpivCigA4vrhz3RNGKNneAYDv1Up6/p3tU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=bpiFlRPztyeGJh2vGGSbMujL3xArB9QASf7szbLAWAq7r+7R0qHRVI5hHUlZ2RA02znwz8jRvfczxsaNFnkF+tTg6KuIFuA51yXTHnla7Xxds5mMaJKqoEDkG+D7aVxqEUG4oXV2tdSSZCFzh33lFWlecZqEOAp19i8ip97lMek= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=yya/tQOJ; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="yya/tQOJ" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dbe9e13775aso4698658276.1 for ; Fri, 08 Mar 2024 23:53:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970819; x=1710575619; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=6ZWDgBnbZIfaFhFVfT7jsQxJgGlWIGxyoXMZnZq9C5M=; b=yya/tQOJneI+zLKmXqGxuwnCMIBnhWvFzyn0ISx/shUGbptwgMnlxPh5Dpdptv1Uud bM1F2qtyybxnEIfsf+1bVFDuqgCyo2HsLD7Lyo5kq/s7eBPncopCqO87cWJuwtzfAjDF yQPUGpQhffpyoHxSOeBFKylR98D5B+WEGM5ZUOMV7Z1iPDWrnRy5nU7HAKW9yUoWyk/7 tG/quUvQ/+Jz3bmLxHWLdypbAOFVNZLisJEb+slj/zHOldOsOiPioBiLFMzKy5yjqeDe iTXg2uU3Wfsctv/JjblcLZ4edDFlFO7x6OA1mK03xgOwpGkWtyUTygsmDdTNPFinwQpd o6LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970819; x=1710575619; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=6ZWDgBnbZIfaFhFVfT7jsQxJgGlWIGxyoXMZnZq9C5M=; b=UJ59k25uWrxazH0hWJiEHGupZ1VRvEp3b7JfSOohhPmNr1GuwQZfYYdLqGVetC5lYr sXXr+2s27TiMh5dBxj5sC1gGHU/x8OvGjrfo8hMUZseh+vHRuGRdBYguuKCd88FCLYf4 saydwycEv39r45GfMMQSVmQzRcWMR1p/HNzu45sFsq08sOOpqb3lmoB7MzzHguH0akMV NDU6l1jS6Tkw4vdLtsDmrKPUs4WdvyojiirxxCxnVMjGw++4XBcygsR5SVingtjoBKPM Tvh207UJgUHDSVLmmWvUTv6q8T13CfD6oCzcZVQZhhRG0uaN8X0UH/JMceis4VfakqbT rkKg== X-Gm-Message-State: AOJu0YyIhEZyLgDm7Ore6JzYHZCGwpxKjVRVobhs2iLvr+B4r6nrXiG4 xPp+MWR6huZO7BCZ7EmgqX+2y/sJzcbEpYr4BWdx5VaDOcXAaXYN69m/HFu6fAxdIKCCCp6JJbe m0GaYEIYh/hLSZqWMKtmygqKTembh+XfZP/jD23+xTjrWWzpRhLgYAaFvDkO/2JXsY1sqG8ovdh eF3Dcag9T8s7kxMNjcU/qdso1MjxzMDwFbFwLhTabp1q5cAkYotGjZ X-Google-Smtp-Source: AGHT+IFG5DX7qqXVTepRoOI8ZJVWe6Gadhv8jhaw+KaBWoOHLKfMIfTCOYgc+feUd9HW5jsS6V5+s/3qXRM= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:120a:b0:dc6:ff54:249f with SMTP id s10-20020a056902120a00b00dc6ff54249fmr357788ybu.8.1709970818999; Fri, 08 Mar 2024 23:53:38 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:17 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-7-gnoack@google.com> Subject: [PATCH v10 6/9] selftests/landlock: Test IOCTLs on named pipes From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Named pipes should behave like pipes created with pipe(2), so we don't want to restrict IOCTLs on them. Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 61 ++++++++++++++++++---- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 5c47231a722e..d991f44875bc 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3924,6 +3924,58 @@ TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl) ASSERT_EQ(0, close(fd)); } +static int test_fionread_ioctl(int fd) +{ + size_t sz = 0; + + if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES) + return errno; + return 0; +} + +/* + * Named pipes are not governed by the LANDLOCK_ACCESS_FS_IOCTL_DEV right, + * because they are not character or block devices. + */ +TEST_F_FORK(layout1, named_pipe_ioctl) +{ + pid_t child_pid; + int fd, ruleset_fd; + const char *const path = file1_s1d1; + const struct landlock_ruleset_attr attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV, + }; + + ASSERT_EQ(0, unlink(path)); + ASSERT_EQ(0, mkfifo(path, 0600)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* The child process opens the pipe for writing. */ + child_pid = fork(); + ASSERT_NE(-1, child_pid); + if (child_pid == 0) { + fd = open(path, O_WRONLY); + close(fd); + exit(0); + } + + fd = open(path, O_RDONLY); + ASSERT_LE(0, fd); + + /* FIONREAD is implemented by pipefifo_fops. */ + EXPECT_EQ(0, test_fionread_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + ASSERT_EQ(0, unlink(path)); + + ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0)); +} + /* clang-format off */ FIXTURE(ioctl) {}; @@ -3997,15 +4049,6 @@ static int test_tcgets_ioctl(int fd) return 0; } -static int test_fionread_ioctl(int fd) -{ - size_t sz = 0; - - if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES) - return errno; - return 0; -} - TEST_F_FORK(ioctl, handle_dir_access_file) { const int flag = 0; From patchwork Sat Mar 9 07:53:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587513 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4789374F1 for ; Sat, 9 Mar 2024 07:53:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970824; cv=none; b=kwVlCcUZrS/STV1PubUlD0Sg/l5N7nw0wg5/EFaUNLea9nDjso6IM1vBD5gHz7PKufXxbRHySeCiEt8XNI3RulMBtfTQcBtchUvFLVqBA6xk1Tie2VmX7GU1onOjgKrRfB46KGw764OJfdGzw/7aTvQ+p3XKF1yYbLpEE3XGD6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970824; c=relaxed/simple; bh=LnWWTWsCU0spX5jOHOmnt+NMIc+/Q5BpY3npXqS3RzI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=h5DEa9uwYDGYJLeWjguLwSG8KBQ6AMYblyf8ZAdMhyagdu34WQazw0F+IEnjAnoK5H8OIzln6Dz+m3WhllkmtZkhnQs8dU6+zdAfIKniXiHTR/KHIrl5Pf2jdLimlw0pcx5zBiFWV1HOJ13y/9EdpK2Qs/YiB/Uo29iK3VRCmHg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AmsyryWU; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AmsyryWU" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dcc0bcf9256so2389127276.3 for ; Fri, 08 Mar 2024 23:53:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970822; x=1710575622; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=Q5KAFkt8c3ebWOo+/ZIaVQQgVH/0sXUyTE45VSTpW7Q=; b=AmsyryWU0MC7E3/T1kekz88Z/FZAP++8yc0wk5BsKAqKvJcG3bpqjCHUpX8yfF2tHG /g2LE7gbeCJZQP2HGsBcw87s8zoPM/UYQcbv6FfrL7VuWnO1yu5VgF1R3GHhduIdM102 5Ykou+8LiasmKc71+475/aqhVxoIMgAD5M3CUHaw/lM915rgessvd6WrtRgMqREnrF85 inZ2QYYBxV6ilKb+O8lCQ8/YAyiQDj6mc6Hnvi7jYQw7/rI8owU9QhLGe2bLwCjMUGKg F6nMir9wr0QzQ/q6thxafjtFU9b9IH17AM5iTnFgDCOixmZmxiB4m5JzQoXHk7wTIww1 z0IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970822; x=1710575622; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Q5KAFkt8c3ebWOo+/ZIaVQQgVH/0sXUyTE45VSTpW7Q=; b=RK+XvX4VukNDfLwbmVrGju9roy0GHpmpzsFu1rlIma/xi6ya8/2xDkPs2QVmacRLUa /Tez+Wme7I5kIiny8YwYLZnckvmD1nHwMZhGlRKVrEjmrMguZYFMFYFFU4jfaXAco7sa DvaP8f1PU+u+wCdeMu6wu796G9kQNoefgnexJdQsXHkFpuLPZIgjZ1KPSjl8LudRy1Gv 8PSBoaBRpVJbkW/dfATN1Ryd1GLfjTlFfFeRq8Z743h7lf6P4G83r7mcHqCdlJ1oAWCS OsWTawtWYuwo4t/G2qucVG7OUSjJL00nLu8tAgYy8Vdhmq2urTXW9UmptTHGDc3/xiK6 E/Ag== X-Gm-Message-State: AOJu0YwdNgEvuFM7oqhriCXlpjJ94DOk0c2XSj39KgkHrP81exDBUc8s Bw3prtQRfJnvBvAToA/5niYyjwoSgXK3PwEoVSkkWEoIGAD4CH0pAF47QMcERgc4ZK8JKwhCQhI VKIyvGsb+aZHGvbnRtD/kwyT1chojNKKKG4qeuCKdY+lboQ+w1Z0/DjxlQuP53x6jtlYLc75aLr uL62L3PPRwJW2LkzG/p+YtuITvjtVvvWjqD/xIeGNg+xnAbTKVOpcP X-Google-Smtp-Source: AGHT+IG2UzW8T2XXCnZ0WKef9syIHtSKgT7HVGMP7GTket6ehHLA9AR/ZmA/bywD9mEzzCuohI2AJvz0ozU= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:1143:b0:dcd:59a5:7545 with SMTP id p3-20020a056902114300b00dcd59a57545mr64713ybu.10.1709970821249; Fri, 08 Mar 2024 23:53:41 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:18 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-8-gnoack@google.com> Subject: [PATCH v10 7/9] selftests/landlock: Check IOCTL restrictions for named UNIX domain sockets From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index d991f44875bc..941e6f9702b7 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -20,8 +20,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -3976,6 +3978,57 @@ TEST_F_FORK(layout1, named_pipe_ioctl) ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0)); } +/* For named UNIX domain sockets, no IOCTL restrictions apply. */ +TEST_F_FORK(layout1, named_unix_domain_socket_ioctl) +{ + const char *const path = file1_s1d1; + int srv_fd, cli_fd, ruleset_fd; + socklen_t size; + struct sockaddr_un srv_un, cli_un; + const struct landlock_ruleset_attr attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV, + }; + + /* Sets up a server */ + srv_un.sun_family = AF_UNIX; + strncpy(srv_un.sun_path, path, sizeof(srv_un.sun_path)); + + ASSERT_EQ(0, unlink(path)); + ASSERT_LE(0, (srv_fd = socket(AF_UNIX, SOCK_STREAM, 0))); + + size = offsetof(struct sockaddr_un, sun_path) + strlen(srv_un.sun_path); + ASSERT_EQ(0, bind(srv_fd, (struct sockaddr *)&srv_un, size)); + ASSERT_EQ(0, listen(srv_fd, 10 /* qlen */)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Sets up a client connection to it */ + cli_un.sun_family = AF_UNIX; + snprintf(cli_un.sun_path, sizeof(cli_un.sun_path), "%s%ld", path, + (long)getpid()); + + ASSERT_LE(0, (cli_fd = socket(AF_UNIX, SOCK_STREAM, 0))); + + size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path); + ASSERT_EQ(0, bind(cli_fd, (struct sockaddr *)&cli_un, size)); + + bzero(&cli_un, sizeof(cli_un)); + cli_un.sun_family = AF_UNIX; + strncpy(cli_un.sun_path, path, sizeof(cli_un.sun_path)); + size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path); + + ASSERT_EQ(0, connect(cli_fd, (struct sockaddr *)&cli_un, size)); + + /* FIONREAD and other IOCTLs should not be forbidden. */ + EXPECT_EQ(0, test_fionread_ioctl(cli_fd)); + + ASSERT_EQ(0, close(cli_fd)); +} + /* clang-format off */ FIXTURE(ioctl) {}; From patchwork Sat Mar 9 07:53:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587514 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 608BF374FF for ; Sat, 9 Mar 2024 07:53:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970826; cv=none; b=n3iDBvWFcO/Okk5zJQKIM2dS3BE8kpwMGCg9VnuTvv2ZzNlPLbyqK1HfFKD2CBWMbau95CBCPlvdgIa5My0hlGP0Rt6t8lviqPoxIONJPBXKwoJji0qaMT6UwsJ7LKnhif4ZGilB3dU2JleGKnNp1vtZDYpzY8/07fQW+jraOcY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970826; c=relaxed/simple; bh=XpHNaMw51kfwTcxWhMkN0GRYGhulnMClD0SZLPpObEU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cxkJ7o6qgUhnWaJxYPDZzmaKTyfIu+ya4BlIp/JfLGhqm7tnWsw9aieq6F77z3eqc5+lgqOQRDqfqzO/ZMUebGKuoAi+M3ErCoZnqlpJY3GeUiMXyDO2jVFIEp1cF47jXZxYtYiN/xJgO36aMJNNiTsgklI9U+cGJlmi+YPDA08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=GIW30M9l; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="GIW30M9l" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-a44a50d098dso162410666b.1 for ; Fri, 08 Mar 2024 23:53:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970824; x=1710575624; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=4Jm3POEMybiMvQ/3vdCRUI71c8LtW1JmAsyXMz3gRfE=; b=GIW30M9lPpcS0hseNo5AeMpA4EJwPGTXFx4ay7qrx2qJfbiNmmw+q3hJddXHNn2DBq NrTvJ2dvpY131mmBmzsdvYzI4SSA4PZ+ezimtR1qdLWpjYx4b9itQtvwoJY+lQq4di76 Jg7ArejDTCiNBsSxhqgisShp5IyWAvnMOWiIriYQcdxNBbEhgoEQWbOcMT5YFlS6/965 FZP8JNQQvBU6afeDNTSl8wV3w4BgB2PHa4oHviXN8DrLbyW5etmshV0gLN1Kv9gEQZvd 8R1HbAbxgQ8mzJ3JroRriRfoXidDUEAW64qlH6f6qTDsyzkyOzG3Vi1/fZP6/7PJwm+6 SyRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970824; x=1710575624; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=4Jm3POEMybiMvQ/3vdCRUI71c8LtW1JmAsyXMz3gRfE=; b=gyxHoDP/vXaT13AtydGTD6118U1WfywfSqOb7Yo/w6ONAv3RMp1qb1wpgIdwoCUw1O WOkyG5jObG4ZxtHcM+D/YFzlSUF3zSGv7/8/LFqvwNBY8lcgtbDxqsGUMkNs9BxZXFXj gxKzg1fzCtCriwkuN5HXPiJFIb43U133CVQdhgJZ4J3cfEVP/FMFXjm5QlXno4GkgrwN eaPCDj7DxkxUp7eBYf6YZAPvnXbPTOsrVQua10zrPFpMZ6D6Z4Tmw6RDotx+vLA6iWpN loNlXGLv5Kspq39H1qcnaWFGxPBnckC3en47qx6xBdr07vaW1BZ9rn7YzNJvcWosmU2d yRSg== X-Gm-Message-State: AOJu0Yyjm3j5wSmSvM61ZiUkZz2LLQKtX6RJAxGSAJ56DYuebHfk02jg iDodRW0bblzcwa9R03sw1k6YT2oZbpY5LFYxV2Ntz/V3bU+TDxKE9sksisOz/b/vW5J2n48PkYk WEOgJXH9bRyuP+iNDG6DBGTESN1h3JXR3BT3g+BwbeP9zDVdxV7WpqVRJWIwrgAa6CyaNJaFbjR 6Ne3hu7Yt3IAzZqGtIiLctS354dmLZkyRtMrNoY915+EC/ceBnBrwO X-Google-Smtp-Source: AGHT+IGLpXM+yuVfUWprHCPTtG+qTgEOtYUZ/27FY+xZlbXBgCi2PYlMNVjPDgR1F3OhtL1jvLlFQ/U3n2k= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6402:e8a:b0:568:13a1:2c2 with SMTP id h10-20020a0564020e8a00b0056813a102c2mr4921eda.5.1709970823517; Fri, 08 Mar 2024 23:53:43 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:19 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-9-gnoack@google.com> Subject: [PATCH v10 8/9] samples/landlock: Add support for LANDLOCK_ACCESS_FS_IOCTL_DEV From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Add IOCTL support to the Landlock sample tool. The IOCTL right is grouped with the read-write rights in the sample tool, as some IOCTL requests provide features that mutate state. Signed-off-by: Günther Noack --- samples/landlock/sandboxer.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index 08596c0ef070..c5228e8c4817 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -81,7 +81,8 @@ static int parse_path(char *env_path, const char ***const path_list) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ @@ -199,11 +200,12 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd, LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ LANDLOCK_ACCESS_FS_MAKE_SYM | \ LANDLOCK_ACCESS_FS_REFER | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ -#define LANDLOCK_ABI_LAST 4 +#define LANDLOCK_ABI_LAST 5 int main(const int argc, char *const argv[], char *const *const envp) { @@ -317,6 +319,11 @@ int main(const int argc, char *const argv[], char *const *const envp) ruleset_attr.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP); + __attribute__((fallthrough)); + case 4: + /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */ + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV; + fprintf(stderr, "Hint: You should update the running kernel " "to leverage Landlock features " From patchwork Sat Mar 9 07:53:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13587515 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7DE5376F4 for ; Sat, 9 Mar 2024 07:53:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970829; cv=none; b=X2vbtev2l67gMC6U7yzcHjJNtGKVucFQxumuiqH+JVsR8SvIPVeODFwMZgDEOvi7z6MNvce96/ZKTJK9SSsxO6nMomUcJtbZ2ipPdZs6WQeUO1xjLIA3kX2LNCk9L4+0asH46h6C1/eO5qzSVo9XWLQ3RMl3QXbVtHm3RpcPr2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709970829; c=relaxed/simple; bh=iNASLIvdJe+G6gv4UkYZwtV4xslMi/uxI/J6OfYzLr4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BW4rm7fv3pDgov68HXuVkyLsLkzvjlLDcFHb0HzU3Kvhbpx1Me/cORYzv7sIvt7ex48SZRjsuS9lL6MZ+UFgHWpJ2i/eyoFHZeqXX3pun2gmk6+3hsG1WtGkxbCEvNIh2lphB85CokBSK9CHwcWag/KwBfb+kA8iq45+GzEEhVU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=a9lEBZjN; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="a9lEBZjN" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-56813bb5e6eso1107407a12.3 for ; Fri, 08 Mar 2024 23:53:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709970826; x=1710575626; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=6xXJZ8Luy05jNZz1hxoLS/0EOiBPDRz4nsKqPpejmYo=; b=a9lEBZjNLqLYqxlfU6QcctJoL42PqqBJG/wKXQqzvuPWkiZYDQlW4OKg4gcJcch5OF f1eUg7Iz97s9wCTTkO+lyOZZlFom2d5VW2hpgq37yJ/3OQinVK0K/lLlavMhF09mK7ar bmyjupsrq2cQCZvvVUUiF4jkOwHShqLUnCLzf62Q1E0hfdBSsq3Rxt3ZccgM2iVbfQO6 6Rd9hpjoYXNgpKcS/+XZF4FIvgpZ9N/A767hfNfLOaI6RG2HuKYXHoL7FpNwieWn2zn4 VnJxy0mLlcaikWdfEBMqPAnFGREaRjtqLD5WSMu7jOEUJhID68zcabGmlLjgAcDXSonD GlQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709970826; x=1710575626; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=6xXJZ8Luy05jNZz1hxoLS/0EOiBPDRz4nsKqPpejmYo=; b=e/jebKmSSn10ILqZFFOEymsdBWq8qoC9lH48mLS5HAudKwYnmGP1K3w6kZJWXgJWW1 3ki7c5F/acw7cN9+iTusqrMNAZL3yHmvb3arBCRU6u08YiUtaCv/X3b8qNoxFDeWr+Rq UOtJ/tGXFjvDbr6pEgxawg8g6eUtAuCHNZvos1mIEfmWNZYbwRVwvGN83jaa1gLFPNbO hyNPjGTceinkUxYYK6HedQ1lBqpIsbGxSa8V5qCfJ+1e5S1USuIqcP6H3NRRAGd3Ks5m ulfyi33NK8IO/trhLpzu1UXsWzeFyA5f0vqQJbLoW5vlLQo2HbB2URVaWa5P+PlNemX2 wz0g== X-Gm-Message-State: AOJu0YxY0BMIzRf3xpRhFxUC5k8WQSpecVvZ8Z8BN890iXaoyFU/7tNf mFxq95+GY9GJ0C5E2xDf1cbEmURQnYbjuwJTyZa6e/i1PM2j0x/nRL9eWbY9WdVdnuSKyHnkQYN EKedzOHaFfi1ZxJSCIzNKXJfYsxFne+NVth8BT475aqL6a7afbUSK51OdIs74xfVG4wNrZ9IeRD YcpjAcYeoRHMzAha4him6hADu31p+uXqqGn5sL3EWD52Yosks9o28H X-Google-Smtp-Source: AGHT+IEB16Vl/CLO+9oSUIXkxJcIHM6QCLqVnsRZhcK17ONeugIEM3ZuOtBIVdNkYYAcgICZia0DsXcQOBc= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6402:f0a:b0:566:c465:20cf with SMTP id i10-20020a0564020f0a00b00566c46520cfmr7206eda.1.1709970826003; Fri, 08 Mar 2024 23:53:46 -0800 (PST) Date: Sat, 9 Mar 2024 07:53:20 +0000 In-Reply-To: <20240309075320.160128-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240309075320.160128-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Message-ID: <20240309075320.160128-10-gnoack@google.com> Subject: [PATCH v10 9/9] landlock: Document IOCTL support From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Arnd Bergmann , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " In the paragraph above the fallback logic, use the shorter phrasing from the landlock(7) man page. Signed-off-by: Günther Noack --- Documentation/userspace-api/landlock.rst | 76 +++++++++++++++++++----- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst index 838cc27db232..32391247f19a 100644 --- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst @@ -76,7 +76,8 @@ to be explicit about the denied-by-default access rights. LANDLOCK_ACCESS_FS_MAKE_BLOCK | LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_REFER | - LANDLOCK_ACCESS_FS_TRUNCATE, + LANDLOCK_ACCESS_FS_TRUNCATE | + LANDLOCK_ACCESS_FS_IOCTL_DEV, .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP, @@ -85,10 +86,10 @@ to be explicit about the denied-by-default access rights. Because we may not know on which kernel version an application will be executed, it is safer to follow a best-effort security approach. Indeed, we should try to protect users as much as possible whatever the kernel they are -using. To avoid binary enforcement (i.e. either all security features or -none), we can leverage a dedicated Landlock command to get the current version -of the Landlock ABI and adapt the handled accesses. Let's check if we should -remove access rights which are only supported in higher versions of the ABI. +using. + +To be compatible with older Linux versions, we detect the available Landlock ABI +version, and only use the available subset of access rights: .. code-block:: c @@ -114,6 +115,10 @@ remove access rights which are only supported in higher versions of the ABI. ruleset_attr.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP); + __attribute__((fallthrough)); + case 4: + /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */ + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV; } This enables to create an inclusive ruleset that will contain our rules. @@ -225,6 +230,7 @@ access rights per directory enables to change the location of such directory without relying on the destination directory access rights (except those that are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER`` documentation). + Having self-sufficient hierarchies also helps to tighten the required access rights to the minimal set of data. This also helps avoid sinkhole directories, i.e. directories where data can be linked to but not linked from. However, @@ -318,18 +324,26 @@ It should also be noted that truncating files does not require the system call, this can also be done through :manpage:`open(2)` with the flags ``O_RDONLY | O_TRUNC``. -When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` -right is associated with the newly created file descriptor and will be used for -subsequent truncation attempts using :manpage:`ftruncate(2)`. The behavior is -similar to opening a file for reading or writing, where permissions are checked -during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and +The truncate right is associated with the opened file (see below). + +Rights associated with file descriptors +--------------------------------------- + +When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` and +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` rights is associated with the newly created +file descriptor and will be used for subsequent truncation and ioctl attempts +using :manpage:`ftruncate(2)` and :manpage:`ioctl(2)`. The behavior is similar +to opening a file for reading or writing, where permissions are checked during +:manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and :manpage:`write(2)` calls. -As a consequence, it is possible to have multiple open file descriptors for the -same file, where one grants the right to truncate the file and the other does -not. It is also possible to pass such file descriptors between processes, -keeping their Landlock properties, even when these processes do not have an -enforced Landlock ruleset. +As a consequence, it is possible that a process has multiple open file +descriptors referring to the same file, but Landlock enforces different things +when operating with these file descriptors. This can happen when a Landlock +ruleset gets enforced and the process keeps file descriptors which were opened +both before and after the enforcement. It is also possible to pass such file +descriptors between processes, keeping their Landlock properties, even when some +of the involved processes do not have an enforced Landlock ruleset. Compatibility ============= @@ -458,6 +472,28 @@ Memory usage Kernel memory allocated to create rulesets is accounted and can be restricted by the Documentation/admin-guide/cgroup-v1/memory.rst. +IOCTL support +------------- + +The ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right restricts the use of +:manpage:`ioctl(2)`, but it only applies to *newly opened* device files. This +means specifically that pre-existing file descriptors like stdin, stdout and +stderr are unaffected. + +Users should be aware that TTY devices have traditionally permitted to control +other processes on the same TTY through the ``TIOCSTI`` and ``TIOCLINUX`` IOCTL +commands. Both of these require ``CAP_SYS_ADMIN`` on modern Linux systems, but +the behavior is configurable for ``TIOCSTI``. + +On older systems, it is therefore recommended to close inherited TTY file +descriptors, or to reopen them from ``/proc/self/fd/*`` without the +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right, if possible. + +Landlock's IOCTL support is coarse-grained at the moment, but may become more +fine-grained in the future. Until then, users are advised to establish the +guarantees that they need through the file hierarchy, by only allowing the +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right on files where it is really required. + Previous limitations ==================== @@ -495,6 +531,16 @@ bind and connect actions to only a set of allowed ports thanks to the new ``LANDLOCK_ACCESS_NET_BIND_TCP`` and ``LANDLOCK_ACCESS_NET_CONNECT_TCP`` access rights. +IOCTL (ABI < 5) +--------------- + +IOCTL operations could not be denied before the fifth Landlock ABI, so +:manpage:`ioctl(2)` is always allowed when using a kernel that only supports an +earlier ABI. + +Starting with the Landlock ABI version 5, it is possible to restrict the use of +:manpage:`ioctl(2)` using the new ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` access right. + .. _kernel_support: Kernel support