プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

[kernel watch没ネタ集] secure_bzero このエントリーをはてなブックマークに追加

暗号処理関係とかはセキュリティ上の理由でkfreeの直前に0クリアしてることがよくあるけど、
最適化で0クリアが消えない保証がないので、絶対最適化で消えないゼロクリアを作ろう。
という提案。

ちなみに、Windowsは本当に消えるゼロクリアで脆弱性つくったことあったりする
secure_bzero()って名前がださい。とか変な方向に議論がながれて発散、入らなかった。

アイィィィィィィィム、セキュアーーーーー!!!!


とか叫んでればマージされたかもしれないのに。



From: Roel Kluin
To: "David S. Miller" ,
Mikael Pettersson ,
penberg@cs.helsinki.fi,
Brian Gerst ,
andi@firstfloor.org,
Andrew Morton ,
LKML ,
linux-crypto@vger.kernel.org,
Herbert@gondor.apana.org.au
Subject: [PATCH v1] compiler: prevent dead store elimination

Due to optimization A call to memset() may be removed as a dead store when
the buffer is not used after its value is overwritten. The new function
secure_bzero() ensures a section of memory is padded with zeroes.

From the GCC manual, section 5.37:
If your assembler instructions access memory in an unpredictable
fashion, add `memory' to the list of clobbered registers. This will
cause GCC to not keep memory values cached in registers across the
assembler instruction and not optimize stores or loads to that memory.

Every byte in the [p,p+n[ range must be used. If you only use the
first byte, via e.g. asm("" :: "m"(*(char*)p)), then the compiler
_will_ skip scrubbing bytes beyond the first. This works with
gcc-3.2.3 up to gcc-4.4.3.

Signed-off-by: Roel Kluin
---
include/linux/compiler-gcc.h | 11 +++++++++++
include/linux/compiler-intel.h | 2 ++
include/linux/string.h | 1 +
lib/string.c | 13 +++++++++++++
4 files changed, 27 insertions(+), 0 deletions(-)

Thanks all for the required information, checkpatch.pl and compile
tested. In my (non-kernel) testcase this prevents dead store elimination.
Comments?

Roel

diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 73dcf80..0799938 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -12,6 +12,17 @@
#define barrier() __asm__ __volatile__("": : :"memory")

/*
+ * Dead store elimination (DSE) is an optimization that may remove a write to
+ * a buffer that is not used anymore. Use ARRAY_PREVENT_DSE after a write when
+ * the scrub is required for security reasons.
+ */
+#define ARRAY_PREVENT_DSE(p, n) \
+ do { \
+ struct __scrub { char c[n]; }; \
+ asm("" : : "m"(*(struct __scrub *)p)); \
+ } while (0)
+
+/*
* This macro obfuscates arithmetic on a variable address so that gcc
* shouldn't recognize the original var, and make assumptions about it.
*
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
index d8e636e..e8e11f3 100644
--- a/include/linux/compiler-intel.h
+++ b/include/linux/compiler-intel.h
@@ -14,9 +14,11 @@
* It uses intrinsics to do the equivalent things.
*/
#undef barrier
+#undef ARRAY_PREVENT_DSE
#undef RELOC_HIDE

#define barrier() __memory_barrier()
+#define ARRAY_PREVENT_DSE(p, n)

#define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
diff --git a/include/linux/string.h b/include/linux/string.h
index a716ee2..36213e6 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -118,6 +118,7 @@ extern void * memchr(const void *,int,__kernel_size_t);
extern char *kstrdup(const char *s, gfp_t gfp);
extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
+extern void secure_bzero(void *, __kernel_size_t);

extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv);
diff --git a/lib/string.c b/lib/string.c
index a1cdcfc..588ac31 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -559,6 +559,19 @@ void *memset(void *s, int c, size_t count)
EXPORT_SYMBOL(memset);
#endif

+/**
+ * secure_bzero - Call memset to fill a region of memory with zeroes and
+ * ensure this memset is not removed due to dead store elimination.
+ * @p: Pointer to the start of the area.
+ * @n: The size of the area.
+ */
+void secure_bzero(void *p, size_t n)
+{
+ memset(p, 0, n);
+ ARRAY_PREVENT_DSE(p, n);
+}
+EXPORT_SYMBOL(secure_bzero);
+
#ifndef __HAVE_ARCH_MEMCPY
/**
* memcpy - Copy one area of memory to another

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
関連記事


linux | 【2010-04-02(Fri) 15:26:27】 | Trackback:(0) | Comments:(0)
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。