From: Arvid Brodin <Arvid.Brodin@xdin.com>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Al Viro <viro@zeniv.linux.org.uk>,
Cyrill Gorcunov <gorcunov@openvz.org>,
"David Rientjes" <rientjes@google.com>,
"Eric W. Biederman" <ebiederm@xmission.com>
Subject: fs/proc/base.c: text md5sums; tgid vs tid; and INF vs ONE?
Date: Tue, 30 Oct 2012 21:02:33 +0000 [thread overview]
Message-ID: <50904066.4060404@xdin.com> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4633 bytes --]
Hi,
Below is a patch that adds a file /proc/PID/text_md5sum which when read returns the md5
checksum of a process' text segment. (This would be used e.g. to make sure a process'
code hasn't been tampered with.)
However, I have a few questions:
* What's the difference between the tgid_base_stuff and tid_base_stuff arrays? (One for
processes and one for the process' threads? I haven't been able to find any info about
this so I'm guessing.)
* When should I use the INF ("read") vs the ONE ("show") macro?
* Any other comments about the code?
Thanks!
---
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 15af622..317ad92 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -67,3 +67,13 @@ config PROC_PAGE_MONITOR
/proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
/proc/kpagecount, and /proc/kpageflags. Disabling these
interfaces will reduce the size of the kernel by approximately 4kb.
+
+config PROC_TEXT_MD5SUM
+ bool "/proc/<pid>/text_md5sum support"
+ depends on PROC_FS
+ select CRYPTO
+ select CRYPTO_MD5
+ help
+ Read /proc/<pid>/text_md5sum to get the kernel to perform an MD5
+ checksum over the process' text segment and print the result. Can be
+ used to make sure a process' code has not been tampered with.
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 91da78c..14a825f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -85,6 +85,10 @@
#include <linux/fs_struct.h>
#include <linux/slab.h>
#include <linux/flex_array.h>
+#ifdef CONFIG_PROC_TEXT_MD5SUM
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#endif
#ifdef CONFIG_HARDWALL
#include <asm/hardwall.h>
#endif
@@ -2526,6 +2530,107 @@ static int proc_pid_personality(struct seq_file *m, struct
pid_namespace *ns,
return err;
}
+#ifdef CONFIG_PROC_TEXT_MD5SUM
+#define MD5_DIGEST_SIZE 16
+static int proc_get_text_md5sum(struct seq_file *m, struct pid_namespace *ns,
+ struct pid *pid, struct task_struct *task)
+{
+ int retval;
+ int text_size;
+ int nr_pages, nr_pages_mapped;
+ int i;
+ struct page **pages;
+ struct scatterlist *sgl, *sg;
+ u8 result[MD5_DIGEST_SIZE + 2];
+ struct crypto_hash *tfm;
+ struct hash_desc desc;
+
+ retval = 0;
+
+ if (!task->mm)
+ return -EINVAL;
+
+ text_size = task->mm->end_code - task->mm->start_code;
+ nr_pages = (text_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+
+ /**** User page code ****/
+
+ pages = kmalloc(nr_pages * sizeof(*pages), GFP_KERNEL);
+ if (!pages) {
+ retval = -ENOMEM;
+ goto err_pages;
+ }
+
+ down_read(&task->mm->mmap_sem);
+ nr_pages_mapped = get_user_pages(current, task->mm,
+ task->mm->start_code, nr_pages, 0, 0, pages, NULL);
+ up_read(&task->mm->mmap_sem);
+ if (nr_pages_mapped < 0) {
+ retval = nr_pages_mapped;
+ goto err_mapped;
+ }
+ if (nr_pages_mapped < nr_pages) {
+ retval = -EBUSY; /* Weird error code for this,
+ but couldn't find any better */
+ goto err_not_all_pages;
+ }
+
+
+ /**** Scatterlist code ****/
+
+ sgl = kmalloc(nr_pages_mapped * sizeof(*sgl), GFP_KERNEL);
+ if (!sgl) {
+ retval = -ENOMEM;
+ goto err_sg;
+ }
+
+ sg_init_table(sgl, nr_pages_mapped);
+ for_each_sg(sgl, sg, nr_pages_mapped, i)
+ sg_set_page(sg, pages[i], (i < nr_pages_mapped) ? PAGE_SIZE :
+ text_size & ~PAGE_MASK, 0);
+
+
+ /**** Crypto code ****/
+
+ tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm)) {
+ retval = -ENOMEM;
+ goto err_crypto;
+ }
+
+ desc.tfm = tfm;
+ desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ memset(result, 0, MD5_DIGEST_SIZE + 2);
+ retval = crypto_hash_digest(&desc, sgl, text_size, result);
+ if (retval)
+ goto err_digest;
+
+ for (i = 0; i < MD5_DIGEST_SIZE; i++)
+ seq_printf(m, "%02x", result[i]);
+ seq_printf(m, "\n");
+
+
+err_digest:
+ crypto_free_hash(tfm);
+
+err_crypto:
+ kfree(sgl);
+
+err_sg:
+err_not_all_pages:
+ for (i = 0; i < nr_pages_mapped; i++)
+ put_page(pages[i]);
+
+err_mapped:
+ kfree(pages);
+
+err_pages:
+ return retval;
+}
+#endif /* CONFIG_PROC_TEXT_MD5SUM */
+
/*
* Thread groups
*/
@@ -2621,6 +2726,9 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
#endif
+#ifdef CONFIG_PROC_TEXT_MD5SUM
+ ONE("text_md5sum", S_IRUGO, proc_get_text_md5sum),
+#endif
};
static int proc_tgid_base_readdir(struct file * filp,
--
Arvid Brodin | Consultant (Linux)
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.comÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
next reply other threads:[~2012-10-30 21:10 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-30 21:02 Arvid Brodin [this message]
2012-10-30 21:22 ` fs/proc/base.c: text md5sums; tgid vs tid; and INF vs ONE? Al Viro
2012-11-01 20:22 ` Arvid Brodin
2012-10-30 21:23 ` Cyrill Gorcunov
2012-10-30 22:45 ` Eric W. Biederman
2012-11-01 20:29 ` Arvid Brodin
2012-11-02 22:49 ` Arvid Brodin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50904066.4060404@xdin.com \
--to=arvid.brodin@xdin.com \
--cc=akpm@linux-foundation.org \
--cc=ebiederm@xmission.com \
--cc=gorcunov@openvz.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rientjes@google.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.