From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754792AbcGLQLB (ORCPT ); Tue, 12 Jul 2016 12:11:01 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:26480 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754546AbcGLQLA (ORCPT ); Tue, 12 Jul 2016 12:11:00 -0400 X-Greylist: delayed 1720 seconds by postgrey-1.27 at vger.kernel.org; Tue, 12 Jul 2016 12:10:49 EDT Subject: [PATCH] prctl: remove one-shot limitation for changing exe link From: Stanislav Kinsburskiy To: peterz@infradead.org, mingo@redhat.com Cc: mhocko@suse.com, keescook@chromium.org, linux-kernel@vger.kernel.org, mguzik@redhat.com, bsegall@google.com, john.stultz@linaro.org, ebiederm@xmission.com, oleg@redhat.com, gorcunov@openvz.org, matthltc@us.ibm.com, akpm@linux-foundation.org, luto@amacapital.net, vbabka@suse.cz, xemul@virtuozzo.com Date: Tue, 12 Jul 2016 19:42:33 +0400 Message-ID: <20160712154146.25004.75440.stgit@localhost.localdomain> User-Agent: StGit/0.17-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This limitation came with the reason to remove "another way for malicious code to obscure a compromised program and masquerade as a benign process" by allowing "security-concious program can use this prctl once during its early initialization to ensure the prctl cannot later be abused for this purpose": http://marc.info/?l=linux-kernel&m=133160684517468&w=2 But the way how the feature can be used is the following: 1) Attach to process via ptrace (protected by CAP_SYS_PTRACE) 2) Unmap all the process file mappings, related to "exe" file. 3) Change exe link (protected by CAP_SYS_RESOURCE). IOW, some other process already has an access to process internals (and thus it's already compromised), and can inject fork and use the child of the compromised program to masquerade. Which means this limitation doesn't solve the problem it was aimed to. While removing this limitation allow to replace files from underneath of a running process as many times as required. One of the use cases is network file systems migration (NFS, to be precise) by CRIU. NFS mount can't be mounted on restore stage because network is locked. To overcome this limitation, another file system (FUSE-based) is used. Then opened files replaced by the proper ones NFS is remounted. Thus exe link replace has to be done twice: first on restore stage and second - when actual NFS was remounted. Signed-off-by: Stanislav Kinsburskiy --- include/linux/sched.h | 4 +++- kernel/sys.c | 10 ---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 553af29..83b5f2d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -518,7 +518,9 @@ static inline int get_dumpable(struct mm_struct *mm) /* leave room for more dump flags */ #define MMF_VM_MERGEABLE 16 /* KSM may merge identical pages */ #define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */ -#define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */ +/* This ine-shot flag is droped due to necessivity of changing exe once again + * on NFS restore */ +//#define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */ #define MMF_HAS_UPROBES 19 /* has uprobes */ #define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */ diff --git a/kernel/sys.c b/kernel/sys.c index 89d5be4..fd6f508 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1696,16 +1696,6 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) fput(exe_file); } - /* - * The symlink can be changed only once, just to disallow arbitrary - * transitions malicious software might bring in. This means one - * could make a snapshot over all processes running and monitor - * /proc/pid/exe changes to notice unusual activity if needed. - */ - err = -EPERM; - if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags)) - goto exit; - err = 0; /* set the new file, lockless */ get_file(exe.file);