aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.de>2018-10-09 11:12:33 -0400
committerMimi Zohar <zohar@linux.ibm.com>2018-10-10 15:18:00 -0400
commita408e4a86b36bf98ad15b9ada531cf0e5118ac67 (patch)
tree7c801d1417656f68fd2c6ee70a01cf34ba389eb7
parent1e4c8dafbb6bf72fb5eca035b861e39c5896c2b7 (diff)
ima: open a new file instance if no read permissions
Open a new file instance as opposed to changing file->f_mode when the file is not readable. This is done to accomodate overlayfs stacked file operations change. The real struct file is hidden behind the overlays struct file. So, any file->f_mode manipulations are not reflected on the real struct file. Open the file again in read mode if original file cannot be read, read and calculate the hash. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Cc: stable@vger.kernel.org (linux-4.19) Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-rw-r--r--security/integrity/ima/ima_crypto.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 7e7e7e7c250a..d9e7728027c6 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -210,7 +210,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
210{ 210{
211 loff_t i_size, offset; 211 loff_t i_size, offset;
212 char *rbuf[2] = { NULL, }; 212 char *rbuf[2] = { NULL, };
213 int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0; 213 int rc, rbuf_len, active = 0, ahash_rc = 0;
214 struct ahash_request *req; 214 struct ahash_request *req;
215 struct scatterlist sg[1]; 215 struct scatterlist sg[1];
216 struct crypto_wait wait; 216 struct crypto_wait wait;
@@ -257,11 +257,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
257 &rbuf_size[1], 0); 257 &rbuf_size[1], 0);
258 } 258 }
259 259
260 if (!(file->f_mode & FMODE_READ)) {
261 file->f_mode |= FMODE_READ;
262 read = 1;
263 }
264
265 for (offset = 0; offset < i_size; offset += rbuf_len) { 260 for (offset = 0; offset < i_size; offset += rbuf_len) {
266 if (!rbuf[1] && offset) { 261 if (!rbuf[1] && offset) {
267 /* Not using two buffers, and it is not the first 262 /* Not using two buffers, and it is not the first
@@ -300,8 +295,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
300 /* wait for the last update request to complete */ 295 /* wait for the last update request to complete */
301 rc = ahash_wait(ahash_rc, &wait); 296 rc = ahash_wait(ahash_rc, &wait);
302out3: 297out3:
303 if (read)
304 file->f_mode &= ~FMODE_READ;
305 ima_free_pages(rbuf[0], rbuf_size[0]); 298 ima_free_pages(rbuf[0], rbuf_size[0]);
306 ima_free_pages(rbuf[1], rbuf_size[1]); 299 ima_free_pages(rbuf[1], rbuf_size[1]);
307out2: 300out2:
@@ -336,7 +329,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
336{ 329{
337 loff_t i_size, offset = 0; 330 loff_t i_size, offset = 0;
338 char *rbuf; 331 char *rbuf;
339 int rc, read = 0; 332 int rc;
340 SHASH_DESC_ON_STACK(shash, tfm); 333 SHASH_DESC_ON_STACK(shash, tfm);
341 334
342 shash->tfm = tfm; 335 shash->tfm = tfm;
@@ -357,11 +350,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
357 if (!rbuf) 350 if (!rbuf)
358 return -ENOMEM; 351 return -ENOMEM;
359 352
360 if (!(file->f_mode & FMODE_READ)) {
361 file->f_mode |= FMODE_READ;
362 read = 1;
363 }
364
365 while (offset < i_size) { 353 while (offset < i_size) {
366 int rbuf_len; 354 int rbuf_len;
367 355
@@ -378,8 +366,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
378 if (rc) 366 if (rc)
379 break; 367 break;
380 } 368 }
381 if (read)
382 file->f_mode &= ~FMODE_READ;
383 kfree(rbuf); 369 kfree(rbuf);
384out: 370out:
385 if (!rc) 371 if (!rc)
@@ -420,6 +406,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
420{ 406{
421 loff_t i_size; 407 loff_t i_size;
422 int rc; 408 int rc;
409 struct file *f = file;
410 bool new_file_instance = false, modified_flags = false;
423 411
424 /* 412 /*
425 * For consistency, fail file's opened with the O_DIRECT flag on 413 * For consistency, fail file's opened with the O_DIRECT flag on
@@ -431,15 +419,41 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
431 return -EINVAL; 419 return -EINVAL;
432 } 420 }
433 421
434 i_size = i_size_read(file_inode(file)); 422 /* Open a new file instance in O_RDONLY if we cannot read */
423 if (!(file->f_mode & FMODE_READ)) {
424 int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
425 O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
426 flags |= O_RDONLY;
427 f = dentry_open(&file->f_path, flags, file->f_cred);
428 if (IS_ERR(f)) {
429 /*
430 * Cannot open the file again, lets modify f_flags
431 * of original and continue
432 */
433 pr_info_ratelimited("Unable to reopen file for reading.\n");
434 f = file;
435 f->f_flags |= FMODE_READ;
436 modified_flags = true;
437 } else {
438 new_file_instance = true;
439 }
440 }
441
442 i_size = i_size_read(file_inode(f));
435 443
436 if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { 444 if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
437 rc = ima_calc_file_ahash(file, hash); 445 rc = ima_calc_file_ahash(f, hash);
438 if (!rc) 446 if (!rc)
439 return 0; 447 goto out;
440 } 448 }
441 449
442 return ima_calc_file_shash(file, hash); 450 rc = ima_calc_file_shash(f, hash);
451out:
452 if (new_file_instance)
453 fput(f);
454 else if (modified_flags)
455 f->f_flags &= ~FMODE_READ;
456 return rc;
443} 457}
444 458
445/* 459/*