aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 10:20:55 -0400
committerJames Morris <jmorris@namei.org>2011-06-28 19:31:21 -0400
commit2e503bbb435ae418aebbe4aeede1c6f2a33d6f74 (patch)
treec6b783c245716cf87b337b2a855e742133afb7ac /security/tomoyo/common.c
parent5625f2e3266319fd29fe4f1c76ccd3f550c79ac4 (diff)
TOMOYO: Fix lockdep warning.
Currently TOMOYO holds SRCU lock upon open() and releases it upon close() because list elements stored in the "struct tomoyo_io_buffer" instances are accessed until close() is called. However, such SRCU usage causes lockdep to complain about leaving the kernel with SRCU lock held. This patch solves the warning by holding/releasing SRCU upon each read()/write(). This patch is doing something similar to calling kfree() without calling synchronize_srcu(), by selectively deferring kfree() by keeping track of the "struct tomoyo_io_buffer" instances. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 50481d2cf970..691c34025a4a 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1820,9 +1820,7 @@ static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1820 * @type: Type of interface. 1820 * @type: Type of interface.
1821 * @file: Pointer to "struct file". 1821 * @file: Pointer to "struct file".
1822 * 1822 *
1823 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 1823 * Returns 0 on success, negative value otherwise.
1824 *
1825 * Caller acquires tomoyo_read_lock().
1826 */ 1824 */
1827int tomoyo_open_control(const u8 type, struct file *file) 1825int tomoyo_open_control(const u8 type, struct file *file)
1828{ 1826{
@@ -1921,9 +1919,6 @@ int tomoyo_open_control(const u8 type, struct file *file)
1921 return -ENOMEM; 1919 return -ENOMEM;
1922 } 1920 }
1923 } 1921 }
1924 if (type != TOMOYO_QUERY && type != TOMOYO_AUDIT)
1925 head->reader_idx = tomoyo_read_lock();
1926 file->private_data = head;
1927 /* 1922 /*
1928 * If the file is /sys/kernel/security/tomoyo/query , increment the 1923 * If the file is /sys/kernel/security/tomoyo/query , increment the
1929 * observer counter. 1924 * observer counter.
@@ -1932,6 +1927,8 @@ int tomoyo_open_control(const u8 type, struct file *file)
1932 */ 1927 */
1933 if (type == TOMOYO_QUERY) 1928 if (type == TOMOYO_QUERY)
1934 atomic_inc(&tomoyo_query_observers); 1929 atomic_inc(&tomoyo_query_observers);
1930 file->private_data = head;
1931 tomoyo_notify_gc(head, true);
1935 return 0; 1932 return 0;
1936} 1933}
1937 1934
@@ -2000,13 +1997,12 @@ static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2000 * @buffer_len: Size of @buffer. 1997 * @buffer_len: Size of @buffer.
2001 * 1998 *
2002 * Returns bytes read on success, negative value otherwise. 1999 * Returns bytes read on success, negative value otherwise.
2003 *
2004 * Caller holds tomoyo_read_lock().
2005 */ 2000 */
2006int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, 2001int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2007 const int buffer_len) 2002 const int buffer_len)
2008{ 2003{
2009 int len; 2004 int len;
2005 int idx;
2010 2006
2011 if (!head->read) 2007 if (!head->read)
2012 return -ENOSYS; 2008 return -ENOSYS;
@@ -2014,6 +2010,7 @@ int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2014 return -EINTR; 2010 return -EINTR;
2015 head->read_user_buf = buffer; 2011 head->read_user_buf = buffer;
2016 head->read_user_buf_avail = buffer_len; 2012 head->read_user_buf_avail = buffer_len;
2013 idx = tomoyo_read_lock();
2017 if (tomoyo_flush(head)) 2014 if (tomoyo_flush(head))
2018 /* Call the policy handler. */ 2015 /* Call the policy handler. */
2019 do { 2016 do {
@@ -2021,6 +2018,7 @@ int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2021 head->read(head); 2018 head->read(head);
2022 } while (tomoyo_flush(head) && 2019 } while (tomoyo_flush(head) &&
2023 tomoyo_has_more_namespace(head)); 2020 tomoyo_has_more_namespace(head));
2021 tomoyo_read_unlock(idx);
2024 len = head->read_user_buf - buffer; 2022 len = head->read_user_buf - buffer;
2025 mutex_unlock(&head->io_sem); 2023 mutex_unlock(&head->io_sem);
2026 return len; 2024 return len;
@@ -2071,8 +2069,6 @@ static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2071 * @buffer_len: Size of @buffer. 2069 * @buffer_len: Size of @buffer.
2072 * 2070 *
2073 * Returns @buffer_len on success, negative value otherwise. 2071 * Returns @buffer_len on success, negative value otherwise.
2074 *
2075 * Caller holds tomoyo_read_lock().
2076 */ 2072 */
2077int tomoyo_write_control(struct tomoyo_io_buffer *head, 2073int tomoyo_write_control(struct tomoyo_io_buffer *head,
2078 const char __user *buffer, const int buffer_len) 2074 const char __user *buffer, const int buffer_len)
@@ -2080,12 +2076,14 @@ int tomoyo_write_control(struct tomoyo_io_buffer *head,
2080 int error = buffer_len; 2076 int error = buffer_len;
2081 size_t avail_len = buffer_len; 2077 size_t avail_len = buffer_len;
2082 char *cp0 = head->write_buf; 2078 char *cp0 = head->write_buf;
2079 int idx;
2083 if (!head->write) 2080 if (!head->write)
2084 return -ENOSYS; 2081 return -ENOSYS;
2085 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2082 if (!access_ok(VERIFY_READ, buffer, buffer_len))
2086 return -EFAULT; 2083 return -EFAULT;
2087 if (mutex_lock_interruptible(&head->io_sem)) 2084 if (mutex_lock_interruptible(&head->io_sem))
2088 return -EINTR; 2085 return -EINTR;
2086 idx = tomoyo_read_lock();
2089 /* Read a line and dispatch it to the policy handler. */ 2087 /* Read a line and dispatch it to the policy handler. */
2090 while (avail_len > 0) { 2088 while (avail_len > 0) {
2091 char c; 2089 char c;
@@ -2148,6 +2146,7 @@ int tomoyo_write_control(struct tomoyo_io_buffer *head,
2148 } 2146 }
2149 } 2147 }
2150out: 2148out:
2149 tomoyo_read_unlock(idx);
2151 mutex_unlock(&head->io_sem); 2150 mutex_unlock(&head->io_sem);
2152 return error; 2151 return error;
2153} 2152}
@@ -2157,30 +2156,18 @@ out:
2157 * 2156 *
2158 * @head: Pointer to "struct tomoyo_io_buffer". 2157 * @head: Pointer to "struct tomoyo_io_buffer".
2159 * 2158 *
2160 * Releases memory and returns 0. 2159 * Returns 0.
2161 *
2162 * Caller looses tomoyo_read_lock().
2163 */ 2160 */
2164int tomoyo_close_control(struct tomoyo_io_buffer *head) 2161int tomoyo_close_control(struct tomoyo_io_buffer *head)
2165{ 2162{
2166 const bool is_write = !!head->write_buf;
2167
2168 /* 2163 /*
2169 * If the file is /sys/kernel/security/tomoyo/query , decrement the 2164 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2170 * observer counter. 2165 * observer counter.
2171 */ 2166 */
2172 if (head->type == TOMOYO_QUERY) 2167 if (head->type == TOMOYO_QUERY &&
2173 atomic_dec(&tomoyo_query_observers); 2168 atomic_dec_and_test(&tomoyo_query_observers))
2174 else if (head->type != TOMOYO_AUDIT) 2169 wake_up_all(&tomoyo_answer_wait);
2175 tomoyo_read_unlock(head->reader_idx); 2170 tomoyo_notify_gc(head, false);
2176 /* Release memory used for policy I/O. */
2177 kfree(head->read_buf);
2178 head->read_buf = NULL;
2179 kfree(head->write_buf);
2180 head->write_buf = NULL;
2181 kfree(head);
2182 if (is_write)
2183 tomoyo_run_gc();
2184 return 0; 2171 return 0;
2185} 2172}
2186 2173