aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Makefile3
-rw-r--r--security/integrity/ima/ima.h3
-rw-r--r--security/integrity/ima/ima_iint.c79
-rw-r--r--security/integrity/ima/ima_main.c184
-rw-r--r--security/keys/keyctl.c12
-rw-r--r--security/min_addr.c2
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/selinux/netlabel.c2
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--security/tomoyo/file.c1
10 files changed, 132 insertions, 158 deletions
diff --git a/security/Makefile b/security/Makefile
index bb44e350c618..da20a193c8dd 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,7 +8,8 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9 9
10# always enable default capabilities 10# always enable default capabilities
11obj-y += commoncap.o min_addr.o 11obj-y += commoncap.o
12obj-$(CONFIG_MMU) += min_addr.o
12 13
13# Object file lists 14# Object file lists
14obj-$(CONFIG_SECURITY) += security.o capability.o 15obj-$(CONFIG_SECURITY) += security.o capability.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 165eb5397ea5..c41afe6639a0 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -97,7 +97,6 @@ static inline unsigned long ima_hash_key(u8 *digest)
97 97
98/* iint cache flags */ 98/* iint cache flags */
99#define IMA_MEASURED 1 99#define IMA_MEASURED 1
100#define IMA_IINT_DUMP_STACK 512
101 100
102/* integrity data associated with an inode */ 101/* integrity data associated with an inode */
103struct ima_iint_cache { 102struct ima_iint_cache {
@@ -128,8 +127,6 @@ void ima_template_show(struct seq_file *m, void *e,
128 */ 127 */
129struct ima_iint_cache *ima_iint_insert(struct inode *inode); 128struct ima_iint_cache *ima_iint_insert(struct inode *inode);
130struct ima_iint_cache *ima_iint_find_get(struct inode *inode); 129struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
131struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
132void ima_iint_delete(struct inode *inode);
133void iint_free(struct kref *kref); 130void iint_free(struct kref *kref);
134void iint_rcu_free(struct rcu_head *rcu); 131void iint_rcu_free(struct rcu_head *rcu);
135 132
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index a4e2b1dac943..fa592ff1ac1c 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -19,8 +19,6 @@
19#include <linux/radix-tree.h> 19#include <linux/radix-tree.h>
20#include "ima.h" 20#include "ima.h"
21 21
22#define ima_iint_delete ima_inode_free
23
24RADIX_TREE(ima_iint_store, GFP_ATOMIC); 22RADIX_TREE(ima_iint_store, GFP_ATOMIC);
25DEFINE_SPINLOCK(ima_iint_lock); 23DEFINE_SPINLOCK(ima_iint_lock);
26 24
@@ -45,22 +43,21 @@ out:
45 return iint; 43 return iint;
46} 44}
47 45
48/* Allocate memory for the iint associated with the inode 46/**
49 * from the iint_cache slab, initialize the iint, and 47 * ima_inode_alloc - allocate an iint associated with an inode
50 * insert it into the radix tree. 48 * @inode: pointer to the inode
51 *
52 * On success return a pointer to the iint; on failure return NULL.
53 */ 49 */
54struct ima_iint_cache *ima_iint_insert(struct inode *inode) 50int ima_inode_alloc(struct inode *inode)
55{ 51{
56 struct ima_iint_cache *iint = NULL; 52 struct ima_iint_cache *iint = NULL;
57 int rc = 0; 53 int rc = 0;
58 54
59 if (!ima_initialized) 55 if (!ima_initialized)
60 return iint; 56 return 0;
57
61 iint = kmem_cache_alloc(iint_cache, GFP_NOFS); 58 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
62 if (!iint) 59 if (!iint)
63 return iint; 60 return -ENOMEM;
64 61
65 rc = radix_tree_preload(GFP_NOFS); 62 rc = radix_tree_preload(GFP_NOFS);
66 if (rc < 0) 63 if (rc < 0)
@@ -70,65 +67,13 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
70 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); 67 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
71 spin_unlock(&ima_iint_lock); 68 spin_unlock(&ima_iint_lock);
72out: 69out:
73 if (rc < 0) { 70 if (rc < 0)
74 kmem_cache_free(iint_cache, iint); 71 kmem_cache_free(iint_cache, iint);
75 if (rc == -EEXIST) {
76 spin_lock(&ima_iint_lock);
77 iint = radix_tree_lookup(&ima_iint_store,
78 (unsigned long)inode);
79 spin_unlock(&ima_iint_lock);
80 } else
81 iint = NULL;
82 }
83 radix_tree_preload_end();
84 return iint;
85}
86
87/**
88 * ima_inode_alloc - allocate an iint associated with an inode
89 * @inode: pointer to the inode
90 *
91 * Return 0 on success, 1 on failure.
92 */
93int ima_inode_alloc(struct inode *inode)
94{
95 struct ima_iint_cache *iint;
96
97 if (!ima_initialized)
98 return 0;
99
100 iint = ima_iint_insert(inode);
101 if (!iint)
102 return 1;
103 return 0;
104}
105
106/* ima_iint_find_insert_get - get the iint associated with an inode
107 *
108 * Most insertions are done at inode_alloc, except those allocated
109 * before late_initcall. When the iint does not exist, allocate it,
110 * initialize and insert it, and increment the iint refcount.
111 *
112 * (Can't initialize at security_initcall before any inodes are
113 * allocated, got to wait at least until proc_init.)
114 *
115 * Return the iint.
116 */
117struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
118{
119 struct ima_iint_cache *iint = NULL;
120 72
121 iint = ima_iint_find_get(inode); 73 radix_tree_preload_end();
122 if (iint)
123 return iint;
124
125 iint = ima_iint_insert(inode);
126 if (iint)
127 kref_get(&iint->refcount);
128 74
129 return iint; 75 return rc;
130} 76}
131EXPORT_SYMBOL_GPL(ima_iint_find_insert_get);
132 77
133/* iint_free - called when the iint refcount goes to zero */ 78/* iint_free - called when the iint refcount goes to zero */
134void iint_free(struct kref *kref) 79void iint_free(struct kref *kref)
@@ -164,12 +109,12 @@ void iint_rcu_free(struct rcu_head *rcu_head)
164} 109}
165 110
166/** 111/**
167 * ima_iint_delete - called on integrity_inode_free 112 * ima_inode_free - called on security_inode_free
168 * @inode: pointer to the inode 113 * @inode: pointer to the inode
169 * 114 *
170 * Free the integrity information(iint) associated with an inode. 115 * Free the integrity information(iint) associated with an inode.
171 */ 116 */
172void ima_iint_delete(struct inode *inode) 117void ima_inode_free(struct inode *inode)
173{ 118{
174 struct ima_iint_cache *iint; 119 struct ima_iint_cache *iint;
175 120
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index b85e61bcf246..a89f44d5e030 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -13,8 +13,8 @@
13 * License. 13 * License.
14 * 14 *
15 * File: ima_main.c 15 * File: ima_main.c
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_path_check. 17 * and ima_path_check.
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/file.h> 20#include <linux/file.h>
@@ -35,6 +35,100 @@ static int __init hash_setup(char *str)
35} 35}
36__setup("ima_hash=", hash_setup); 36__setup("ima_hash=", hash_setup);
37 37
38struct ima_imbalance {
39 struct hlist_node node;
40 unsigned long fsmagic;
41};
42
43/*
44 * ima_limit_imbalance - emit one imbalance message per filesystem type
45 *
46 * Maintain list of filesystem types that do not measure files properly.
47 * Return false if unknown, true if known.
48 */
49static bool ima_limit_imbalance(struct file *file)
50{
51 static DEFINE_SPINLOCK(ima_imbalance_lock);
52 static HLIST_HEAD(ima_imbalance_list);
53
54 struct super_block *sb = file->f_dentry->d_sb;
55 struct ima_imbalance *entry;
56 struct hlist_node *node;
57 bool found = false;
58
59 rcu_read_lock();
60 hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) {
61 if (entry->fsmagic == sb->s_magic) {
62 found = true;
63 break;
64 }
65 }
66 rcu_read_unlock();
67 if (found)
68 goto out;
69
70 entry = kmalloc(sizeof(*entry), GFP_NOFS);
71 if (!entry)
72 goto out;
73 entry->fsmagic = sb->s_magic;
74 spin_lock(&ima_imbalance_lock);
75 /*
76 * we could have raced and something else might have added this fs
77 * to the list, but we don't really care
78 */
79 hlist_add_head_rcu(&entry->node, &ima_imbalance_list);
80 spin_unlock(&ima_imbalance_lock);
81 printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n",
82 entry->fsmagic);
83out:
84 return found;
85}
86
87/*
88 * Update the counts given an fmode_t
89 */
90static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
91{
92 BUG_ON(!mutex_is_locked(&iint->mutex));
93
94 iint->opencount++;
95 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
96 iint->readcount++;
97 if (mode & FMODE_WRITE)
98 iint->writecount++;
99}
100
101/*
102 * Decrement ima counts
103 */
104static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
105 struct file *file)
106{
107 mode_t mode = file->f_mode;
108 BUG_ON(!mutex_is_locked(&iint->mutex));
109
110 iint->opencount--;
111 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
112 iint->readcount--;
113 if (mode & FMODE_WRITE) {
114 iint->writecount--;
115 if (iint->writecount == 0) {
116 if (iint->version != inode->i_version)
117 iint->flags &= ~IMA_MEASURED;
118 }
119 }
120
121 if (((iint->opencount < 0) ||
122 (iint->readcount < 0) ||
123 (iint->writecount < 0)) &&
124 !ima_limit_imbalance(file)) {
125 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
126 __FUNCTION__, iint->readcount, iint->writecount,
127 iint->opencount);
128 dump_stack();
129 }
130}
131
38/** 132/**
39 * ima_file_free - called on __fput() 133 * ima_file_free - called on __fput()
40 * @file: pointer to file structure being freed 134 * @file: pointer to file structure being freed
@@ -54,29 +148,7 @@ void ima_file_free(struct file *file)
54 return; 148 return;
55 149
56 mutex_lock(&iint->mutex); 150 mutex_lock(&iint->mutex);
57 if (iint->opencount <= 0) { 151 ima_dec_counts(iint, inode, file);
58 printk(KERN_INFO
59 "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n",
60 __FUNCTION__, file->f_dentry->d_name.name,
61 iint->readcount, iint->writecount,
62 iint->opencount, atomic_long_read(&file->f_count));
63 if (!(iint->flags & IMA_IINT_DUMP_STACK)) {
64 dump_stack();
65 iint->flags |= IMA_IINT_DUMP_STACK;
66 }
67 }
68 iint->opencount--;
69
70 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
71 iint->readcount--;
72
73 if (file->f_mode & FMODE_WRITE) {
74 iint->writecount--;
75 if (iint->writecount == 0) {
76 if (iint->version != inode->i_version)
77 iint->flags &= ~IMA_MEASURED;
78 }
79 }
80 mutex_unlock(&iint->mutex); 152 mutex_unlock(&iint->mutex);
81 kref_put(&iint->refcount, iint_free); 153 kref_put(&iint->refcount, iint_free);
82} 154}
@@ -116,8 +188,7 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
116{ 188{
117 int rc = 0; 189 int rc = 0;
118 190
119 iint->opencount++; 191 ima_inc_counts(iint, file->f_mode);
120 iint->readcount++;
121 192
122 rc = ima_collect_measurement(iint, file); 193 rc = ima_collect_measurement(iint, file);
123 if (!rc) 194 if (!rc)
@@ -125,15 +196,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
125 return rc; 196 return rc;
126} 197}
127 198
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0))
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++;
135}
136
137/** 199/**
138 * ima_path_check - based on policy, collect/store measurement. 200 * ima_path_check - based on policy, collect/store measurement.
139 * @path: contains a pointer to the path to be measured 201 * @path: contains a pointer to the path to be measured
@@ -152,7 +214,7 @@ static void ima_update_counts(struct ima_iint_cache *iint, int mask)
152 * Always return 0 and audit dentry_open failures. 214 * Always return 0 and audit dentry_open failures.
153 * (Return code will be based upon measurement appraisal.) 215 * (Return code will be based upon measurement appraisal.)
154 */ 216 */
155int ima_path_check(struct path *path, int mask, int update_counts) 217int ima_path_check(struct path *path, int mask)
156{ 218{
157 struct inode *inode = path->dentry->d_inode; 219 struct inode *inode = path->dentry->d_inode;
158 struct ima_iint_cache *iint; 220 struct ima_iint_cache *iint;
@@ -161,13 +223,11 @@ int ima_path_check(struct path *path, int mask, int update_counts)
161 223
162 if (!ima_initialized || !S_ISREG(inode->i_mode)) 224 if (!ima_initialized || !S_ISREG(inode->i_mode))
163 return 0; 225 return 0;
164 iint = ima_iint_find_insert_get(inode); 226 iint = ima_iint_find_get(inode);
165 if (!iint) 227 if (!iint)
166 return 0; 228 return 0;
167 229
168 mutex_lock(&iint->mutex); 230 mutex_lock(&iint->mutex);
169 if (update_counts)
170 ima_update_counts(iint, mask);
171 231
172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); 232 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
173 if (rc < 0) 233 if (rc < 0)
@@ -219,7 +279,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
219 279
220 if (!ima_initialized || !S_ISREG(inode->i_mode)) 280 if (!ima_initialized || !S_ISREG(inode->i_mode))
221 return 0; 281 return 0;
222 iint = ima_iint_find_insert_get(inode); 282 iint = ima_iint_find_get(inode);
223 if (!iint) 283 if (!iint)
224 return -ENOMEM; 284 return -ENOMEM;
225 285
@@ -238,39 +298,6 @@ out:
238} 298}
239 299
240/* 300/*
241 * ima_counts_put - decrement file counts
242 *
243 * File counts are incremented in ima_path_check. On file open
244 * error, such as ETXTBSY, decrement the counts to prevent
245 * unnecessary imbalance messages.
246 */
247void ima_counts_put(struct path *path, int mask)
248{
249 struct inode *inode = path->dentry->d_inode;
250 struct ima_iint_cache *iint;
251
252 /* The inode may already have been freed, freeing the iint
253 * with it. Verify the inode is not NULL before dereferencing
254 * it.
255 */
256 if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
257 return;
258 iint = ima_iint_find_insert_get(inode);
259 if (!iint)
260 return;
261
262 mutex_lock(&iint->mutex);
263 iint->opencount--;
264 if ((mask & MAY_WRITE) || (mask == 0))
265 iint->writecount--;
266 else if (mask & (MAY_READ | MAY_EXEC))
267 iint->readcount--;
268 mutex_unlock(&iint->mutex);
269
270 kref_put(&iint->refcount, iint_free);
271}
272
273/*
274 * ima_counts_get - increment file counts 301 * ima_counts_get - increment file counts
275 * 302 *
276 * - for IPC shm and shmat file. 303 * - for IPC shm and shmat file.
@@ -286,16 +313,11 @@ void ima_counts_get(struct file *file)
286 313
287 if (!ima_initialized || !S_ISREG(inode->i_mode)) 314 if (!ima_initialized || !S_ISREG(inode->i_mode))
288 return; 315 return;
289 iint = ima_iint_find_insert_get(inode); 316 iint = ima_iint_find_get(inode);
290 if (!iint) 317 if (!iint)
291 return; 318 return;
292 mutex_lock(&iint->mutex); 319 mutex_lock(&iint->mutex);
293 iint->opencount++; 320 ima_inc_counts(iint, file->f_mode);
294 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
295 iint->readcount++;
296
297 if (file->f_mode & FMODE_WRITE)
298 iint->writecount++;
299 mutex_unlock(&iint->mutex); 321 mutex_unlock(&iint->mutex);
300 322
301 kref_put(&iint->refcount, iint_free); 323 kref_put(&iint->refcount, iint_free);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 06ec722897be..e9c2e7c584d9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1194,7 +1194,7 @@ long keyctl_get_security(key_serial_t keyid,
1194 * have the authorisation token handy */ 1194 * have the authorisation token handy */
1195 instkey = key_get_instantiation_authkey(keyid); 1195 instkey = key_get_instantiation_authkey(keyid);
1196 if (IS_ERR(instkey)) 1196 if (IS_ERR(instkey))
1197 return PTR_ERR(key_ref); 1197 return PTR_ERR(instkey);
1198 key_put(instkey); 1198 key_put(instkey);
1199 1199
1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0); 1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0);
@@ -1236,6 +1236,7 @@ long keyctl_get_security(key_serial_t keyid,
1236 */ 1236 */
1237long keyctl_session_to_parent(void) 1237long keyctl_session_to_parent(void)
1238{ 1238{
1239#ifdef TIF_NOTIFY_RESUME
1239 struct task_struct *me, *parent; 1240 struct task_struct *me, *parent;
1240 const struct cred *mycred, *pcred; 1241 const struct cred *mycred, *pcred;
1241 struct cred *cred, *oldcred; 1242 struct cred *cred, *oldcred;
@@ -1326,6 +1327,15 @@ not_permitted:
1326error_keyring: 1327error_keyring:
1327 key_ref_put(keyring_r); 1328 key_ref_put(keyring_r);
1328 return ret; 1329 return ret;
1330
1331#else /* !TIF_NOTIFY_RESUME */
1332 /*
1333 * To be removed when TIF_NOTIFY_RESUME has been implemented on
1334 * m68k/xtensa
1335 */
1336#warning TIF_NOTIFY_RESUME not implemented
1337 return -EOPNOTSUPP;
1338#endif /* !TIF_NOTIFY_RESUME */
1329} 1339}
1330 1340
1331/*****************************************************************************/ 1341/*****************************************************************************/
diff --git a/security/min_addr.c b/security/min_addr.c
index fc43c9d37084..e86f297522bf 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -43,7 +43,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
43 return ret; 43 return ret;
44} 44}
45 45
46int __init init_mmap_min_addr(void) 46static int __init init_mmap_min_addr(void)
47{ 47{
48 update_mmap_min_addr(); 48 update_mmap_min_addr();
49 49
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7a374c2eb043..9a2ee845e9d4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2365,7 +2365,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2365 initrlim = init_task.signal->rlim + i; 2365 initrlim = init_task.signal->rlim + i;
2366 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); 2366 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2367 } 2367 }
2368 update_rlimit_cpu(rlim->rlim_cur); 2368 update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
2369 } 2369 }
2370} 2370}
2371 2371
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index e68823741ad5..2534400317c5 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -204,7 +204,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
204 * 204 *
205 * Description 205 * Description
206 * Call the NetLabel mechanism to set the label of a packet using @sid. 206 * Call the NetLabel mechanism to set the label of a packet using @sid.
207 * Returns zero on auccess, negative values on failure. 207 * Returns zero on success, negative values on failure.
208 * 208 *
209 */ 209 */
210int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, 210int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 9ec24169ccd7..3b42b154d87c 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -806,7 +806,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
806 goto out; 806 goto out;
807 } 807 }
808 808
809 /* type/domain unchaned */ 809 /* type/domain unchanged */
810 if (old_context->type == new_context->type) { 810 if (old_context->type == new_context->type) {
811 rc = 0; 811 rc = 0;
812 goto out; 812 goto out;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 075392c052b4..cfcb096ee97a 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -12,7 +12,6 @@
12#include "common.h" 12#include "common.h"
13#include "tomoyo.h" 13#include "tomoyo.h"
14#include "realpath.h" 14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16 15
17/* 16/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding 17 * tomoyo_globally_readable_file_entry is a structure which is used for holding