From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754480Ab1L2QOW (ORCPT ); Thu, 29 Dec 2011 11:14:22 -0500 Received: from mail-iy0-f174.google.com ([209.85.210.174]:54555 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754059Ab1L2QOU (ORCPT ); Thu, 29 Dec 2011 11:14:20 -0500 Date: Thu, 29 Dec 2011 08:14:14 -0800 From: Tejun Heo To: Cyrill Gorcunov Cc: linux-kernel@vger.kernel.org, Pavel Emelyanov , Glauber Costa , Andi Kleen , Matt Helsley , Pekka Enberg , Eric Dumazet , Vasiliy Kulikov , Andrew Morton , Alexey Dobriyan , Herbert Xu , "David S. Miller" Subject: Re: [patch 1/4] Add routine for generating an ID for kernel pointer Message-ID: <20111229161414.GC3516@google.com> References: <20111223124920.661126615@openvz.org> <20111228160655.GL17712@google.com> <20111228161809.GQ27266@moon> <20111228162653.GM17712@google.com> <20111228164055.GR27266@moon> <20111228164522.GO17712@google.com> <20111228165336.GS27266@moon> <20111228170116.GQ17712@google.com> <20111228171419.GA19321@moon> <20111229142438.GI4460@moon> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111229142438.GI4460@moon> User-Agent: Mutt/1.5.20 (2009-06-14) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello, On Thu, Dec 29, 2011 at 06:24:38PM +0400, Cyrill Gorcunov wrote: > Tejun, I've tried to use crypto engine here but it produced a warning > about being used in non-sleepable context (which takes place when we > read /proc//fdinfo/* files). So I used lib/sha1.c instead. The > final result is below, please review. I don't know anything about cryptography and have no idea whether sha1 is good enough, so I can't really say much. :) Which part triggered the context warning? IIRC, crypto context preparation and actual calculation can be done in separate steps. Can't the calculation part be done from non-sleepable context? cc'ing Herbert & David and quoting the whole message. Thanks. > The output as expected is sha1 hash but note I still placed root-only > access here since I prefer security guys to confirm if such production > is indeed safe to be exported for regular users. > > | [root@localhost ~]# cat /proc/2/ns/net > | id: ebfc829fc16a466c9c02b031ceab65c277040c02 > > Cyrill > --- > From: Cyrill Gorcunov > Subject: Add routine for generating an ID for kernel pointer v2 > > The routine XORs the given pointer with a random value, > expands the production to sha1 message block and compute > the sha1 hash producing an ID. > > Util confirmed that the production is a safe one to be > exported for the unprivileged users CAP_SYS_ADMIN guird > is used. > > Because the routine might be used in non-sleepable context > built-in realization of sha1 is chosen instead of crypto > manager and its helpers. > > v1: > - Tejun worried about the single poison value was a weak side - > leaking one makes all the IDs vulnerable. To address this > several poison values - one per object type - are introduced. > They are stored in a plain array. > - Pekka proposed to initialized poison values in the late_initcall callback > - ... and move the code to mm/util.c, but eventually it's moved > to an own file. > > v2: > - Tejun suggested to use crypto engine instead of plain XOR and > provide hashes to unprivilege users as well. > - A number of fixes for Kconfig prompt from Valdis > - Andrew pointed more #incclude's are needed > > Based-on-patch-from: Pavel Emelyanov > Signed-off-by: Cyrill Gorcunov > CC: Glauber Costa > CC: Andi Kleen > CC: Tejun Heo > CC: Matt Helsley > CC: Pekka Enberg > CC: Eric Dumazet > CC: Vasiliy Kulikov > CC: Andrew Morton > CC: Alexey Dobriyan > CC: Valdis.Kletnieks@vt.edu > --- > include/linux/gen_obj_id.h | 26 ++++++++++++++ > mm/Kconfig | 18 ++++++++++ > mm/Makefile | 1 > mm/gen_obj_id.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 126 insertions(+) > > Index: linux-2.6.git/include/linux/gen_obj_id.h > =================================================================== > --- /dev/null > +++ linux-2.6.git/include/linux/gen_obj_id.h > @@ -0,0 +1,26 @@ > +#ifndef _LINUX_GEN_OBJ_ID_H > +#define _LINUX_GEN_OBJ_ID_H > + > +#include > +#include > + > +#ifdef __KERNEL__ > + > +enum { > + GEN_OBJ_ID_TYPES, > +}; > +#define GEN_OBJ_ID_DIGEST_SIZE (SHA_DIGEST_WORDS * sizeof(__u32)) > +#define GEN_OBJ_ID_BUF_SIZE (GEN_OBJ_ID_DIGEST_SIZE * 2) > + > +#ifdef CONFIG_GENERIC_OBJECT_ID > +extern int gen_obj_id(void *ptr, int type, char *dst, unsigned long size); > +#else > +static inline int gen_obj_id(void *ptr, int type, char *dst, unsigned long size) > +{ > + return -EINVAL; > +} > +#endif > + > +#endif /* __KERNEL__ */ > +#endif /* _LINUX_GEN_OBJ_ID_H */ > Index: linux-2.6.git/mm/Kconfig > =================================================================== > --- linux-2.6.git.orig/mm/Kconfig > +++ linux-2.6.git/mm/Kconfig > @@ -373,3 +373,21 @@ config CLEANCACHE > in a negligible performance hit. > > If unsure, say Y to enable cleancache > + > +config GENERIC_OBJECT_ID > + bool "Enable generic object ID infrastructure" > + depends on CHECKPOINT_RESTORE > + depends on CRYPTO_SHA1 > + default n > + help > + Turn on functionality that can generate IDs for kernel > + objects, which are exported to the userspace via /proc > + filesystem. > + > + It is useful if you need to examine kernel objects and test > + if they are shared between several tasks. These IDs should never > + be used for anything but the "sameness" test. The IDs are dynamic > + and valid only while object is alive. Once it get freed or kernel > + is rebooted, the IDs will be changed. > + > + If unsure, say N here. > Index: linux-2.6.git/mm/Makefile > =================================================================== > --- linux-2.6.git.orig/mm/Makefile > +++ linux-2.6.git/mm/Makefile > @@ -51,3 +51,4 @@ obj-$(CONFIG_HWPOISON_INJECT) += hwpoiso > obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o > obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o > obj-$(CONFIG_CLEANCACHE) += cleancache.o > +obj-$(CONFIG_GENERIC_OBJECT_ID) += gen_obj_id.o > Index: linux-2.6.git/mm/gen_obj_id.c > =================================================================== > --- /dev/null > +++ linux-2.6.git/mm/gen_obj_id.c > @@ -0,0 +1,81 @@ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +static unsigned long gen_obj_cookie[GEN_OBJ_ID_TYPES] __read_mostly; > + > +int gen_obj_id(void *ptr, int type, char *dst, unsigned long size) > +{ > + __u32 hash[SHA_DIGEST_WORDS]; > + __u32 workspace[SHA_WORKSPACE_WORDS]; > + __u8 extract[SHA_MESSAGE_BYTES]; > + __u8 *t = (__u8 *)hash; > + unsigned long id; > + int i; > + > + BUG_ON(type >= GEN_OBJ_ID_TYPES); > + > + if (!capable(CAP_SYS_ADMIN) || > + size < GEN_OBJ_ID_BUF_SIZE) { > + memset(dst, '0', size); > + return -EINVAL; > + } > + > + id = ((unsigned long)ptr) ^ gen_obj_cookie[type]; > + > + BUILD_BUG_ON(SHA_MESSAGE_BYTES % sizeof(long)); > + > + /* > + * Expand the ID to the whole message block. > + */ > + for (i = 0; i < (SHA_MESSAGE_BYTES / sizeof(long)); i++) > + ((long *)extract)[i] = id; > + > + sha_init(hash); > + sha_transform(hash, extract, workspace); > + > + snprintf(dst, size, > + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" > + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", > + t[ 0], t[ 1], t[ 2], t[ 3], t[ 4], > + t[ 5], t[ 6], t[ 7], t[ 8], t[ 9], > + t[10], t[11], t[12], t[13], t[14], > + t[15], t[16], t[17], t[18], t[19]); > + > + return 0; > +} > + > +static __init int gen_obj_cookie_init(void) > +{ > +#if BITS_PER_LONG == 64 > + const unsigned long emergency_cookie = 0xefcdab8967452301; > +#else > + const unsigned long emergency_cookie = 0x98badcf9; > +#endif > + int i; > + > + for (i = 0; i < GEN_OBJ_ID_TYPES; i++) { > + get_random_bytes(&gen_obj_cookie[i], > + sizeof(unsigned long)); > + /* > + * In 'impossible' case of random-bytes = 0 > + * we still would have non-zero value. > + */ > + gen_obj_cookie[i] = > + (gen_obj_cookie[i] & __PAGE_OFFSET) + > + (emergency_cookie & ~__PAGE_OFFSET); > + } > + > + return 0; > +} > + > +late_initcall(gen_obj_cookie_init); -- tejun