From patchwork Wed Jul 13 07:32:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Georget X-Patchwork-Id: 9227023 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D2C5060868 for ; Wed, 13 Jul 2016 07:33:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6DE1277D9 for ; Wed, 13 Jul 2016 07:33:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BB86627C38; Wed, 13 Jul 2016 07:33:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EA74277D9 for ; Wed, 13 Jul 2016 07:33:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751162AbcGMHdR (ORCPT ); Wed, 13 Jul 2016 03:33:17 -0400 Received: from lgeorget.eu ([178.170.116.192]:59860 "EHLO lgeorget.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750961AbcGMHdR (ORCPT ); Wed, 13 Jul 2016 03:33:17 -0400 Received: from localhost (unknown [193.54.192.15]) by lgeorget.eu (Postfix) with ESMTPSA id 305CF6BFB8; Wed, 13 Jul 2016 09:33:10 +0200 (CEST) From: Laurent Georget To: James Morris , LSM Cc: Paul Moore , Laurent Georget Subject: [PATCH 1/2] Add LSM hooks in vmsplice, splice and tee Date: Wed, 13 Jul 2016 09:32:50 +0200 Message-Id: <8d4e11f95111306427e18d08d4ba9ea759c24576.1468394884.git.laurent.georget@supelec.fr> X-Mailer: git-send-email 2.9.0 In-Reply-To: References: In-Reply-To: References: Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Laurent Georget --- fs/splice.c | 29 +++++++++++++++++++++++------ include/linux/security.h | 7 +++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index dd9bf7e..308514e 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "internal.h" /* @@ -1375,6 +1376,10 @@ static long do_splice(struct file *in, loff_t __user *off_in, if (ipipe == opipe) return -EINVAL; + ret = security_file_splice_pipe_to_pipe(in, out); + if (ret) + return ret; + return splice_pipe_to_pipe(ipipe, opipe, len, flags); } @@ -1564,6 +1569,10 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *uiov, if (!pipe) return -EBADF; + ret = security_file_permission(file, MAY_READ); + if (ret) + return ret; + ret = import_iovec(READ, uiov, nr_segs, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0) @@ -1610,6 +1619,10 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, if (!pipe) return -EBADF; + ret = security_file_permission(file, MAY_WRITE); + if (ret) + return ret; + if (splice_grow_spd(pipe, &spd)) return -ENOMEM; @@ -2005,18 +2018,22 @@ static long do_tee(struct file *in, struct file *out, size_t len, * copying the data. */ if (ipipe && opipe && ipipe != opipe) { + ret = security_file_splice_pipe_to_pipe(in, out); + if (ret) + goto out; /* * Keep going, unless we encounter an error. The ipipe/opipe * ordering doesn't really matter. */ ret = ipipe_prep(ipipe, flags); - if (!ret) { - ret = opipe_prep(opipe, flags); - if (!ret) - ret = link_pipe(ipipe, opipe, len, flags); - } + if (ret) + goto out; + ret = opipe_prep(opipe, flags); + if (ret) + goto out; + ret = link_pipe(ipipe, opipe, len, flags); } - +out: return ret; } diff --git a/include/linux/security.h b/include/linux/security.h index 157f0cb..c3e2109 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -292,6 +292,7 @@ int security_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int sig); int security_file_receive(struct file *file); int security_file_open(struct file *file, const struct cred *cred); +int security_file_splice_pipe_to_pipe(struct file *in, struct file *out); int security_task_create(unsigned long clone_flags); void security_task_free(struct task_struct *task); int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); @@ -815,6 +816,12 @@ static inline int security_file_open(struct file *file, return 0; } +static inline int security_file_splice_pipe_to_pipe(struct file *in, + struct file *out) +{ + return 0; +} + static inline int security_task_create(unsigned long clone_flags) { return 0;