Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753058AbcKHCSG (ORCPT ); Mon, 7 Nov 2016 21:18:06 -0500 Received: from mail-it0-f50.google.com ([209.85.214.50]:38431 "EHLO mail-it0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752158AbcKHCSE (ORCPT ); Mon, 7 Nov 2016 21:18:04 -0500 MIME-Version: 1.0 From: Nathaniel McCallum Date: Mon, 7 Nov 2016 21:18:02 -0500 Message-ID: Subject: Authenticating Unix Socket Connections by PGID To: linux-kernel@vger.kernel.org Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2338 Lines: 46 I apologize if this is the wrong mailing list for this query. I wasn't sure where else to post it. In user space, I have a process hierarchy. There is a root process which spawns a child which in turn may spawn more children. Hence, I have a standard hierarchy with a root process, zero or more branch processes and one or more leaf processes. I need a mechanism by which the leaf processes communicate with the root process. However, I also need to prevent parallel hierarchies from communicating with the root process: only descendants of the root process should have access to the root process. Further, I'd like to avoid the complication of proxying through branch processes. I'm already using a process group so that the root process can killpg() for cleanup. So I was wondering: can I use the PGID for authentication as well? Basically, I'd just use a well-known AF_UNIX/SOCK_STREAM socket. The root process would then check that new connections were in the process group by using: getpgid(getsockopt(SO_PEERCRED).pid) == getpid(). I inquired with several very knowledgeable people before sending this email, and they were all somewhat uncomfortable with this scheme but couldn't detail why. This system depends on a few features. First, it depends on the documented requirement that setpgid() fails if attempting to move to a different session. Since I create my own session (via setsid()) in the root process, it would seem that spoofing a child is impossible. This requirement is documented in the man page for setpgid() as failing with EPERM. I also confirmed this behavior by reviewing the kernel code for implementing the setpgid() syscall. Second, it depends on being able to properly determine the PGID of the unix socket connection peer. One concern that was voiced to me was a fear that this wouldn't work across namespaces; so I tested it. In child namespaces, getsockopt(SO_PEERCRED).pid returns the mapped PID in the parent. In parallel namespaces, the same approach returns PID = 0. Thus, AFAICS, this requirement is also met: we can accurately detect the PGID of a unix socket peer. Obviously, branch/leaf processes need to be sure not to call setpgid()/setsid(). But the worst case here is that they get authentication denied. Am shooting myself in the foot? Might there be some corner case that I'm missing?