(empty log message)
@@ -27,17 +27,17 @@ | ||
27 | 27 | |
28 | 28 | char *ccs_encode(const char *str); |
29 | 29 | char *ccs_encode2(const char *str, int str_len); |
30 | -char *ccs_realpath(struct path *path); | |
30 | +char *ccs_realpath(const struct path *path); | |
31 | 31 | const char *ccs_get_exe(void); |
32 | 32 | void ccs_fill_path_info(struct ccs_path_info *ptr); |
33 | 33 | |
34 | -static char *ccs_get_absolute_path(struct path *path, char * const buffer, | |
35 | - const int buflen); | |
34 | +static char *ccs_get_absolute_path(const struct path *path, | |
35 | + char * const buffer, const int buflen); | |
36 | 36 | static char *ccs_get_dentry_path(struct dentry *dentry, char * const buffer, |
37 | 37 | const int buflen); |
38 | 38 | static char *ccs_get_local_path(struct dentry *dentry, char * const buffer, |
39 | 39 | const int buflen); |
40 | -static char *ccs_get_socket_name(struct path *path, char * const buffer, | |
40 | +static char *ccs_get_socket_name(const struct path *path, char * const buffer, | |
41 | 41 | const int buflen); |
42 | 42 | static int ccs_const_part_length(const char *filename); |
43 | 43 |
@@ -213,8 +213,8 @@ | ||
213 | 213 | * |
214 | 214 | * If dentry is a directory, trailing '/' is appended. |
215 | 215 | */ |
216 | -static char *ccs_get_absolute_path(struct path *path, char * const buffer, | |
217 | - const int buflen) | |
216 | +static char *ccs_get_absolute_path(const struct path *path, | |
217 | + char * const buffer, const int buflen) | |
218 | 218 | { |
219 | 219 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) |
220 | 220 | char *pos = ERR_PTR(-ENOMEM); |
@@ -343,9 +343,20 @@ | ||
343 | 343 | static char *ccs_get_dentry_path(struct dentry *dentry, char * const buffer, |
344 | 344 | const int buflen) |
345 | 345 | { |
346 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) | |
346 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) | |
347 | 347 | char *pos = ERR_PTR(-ENOMEM); |
348 | 348 | if (buflen >= 256) { |
349 | + pos = dentry_path_raw(dentry, buffer, buflen - 1); | |
350 | + if (!IS_ERR(pos) && *pos == '/' && pos[1] && | |
351 | + d_is_dir(dentry)) { | |
352 | + buffer[buflen - 2] = '/'; | |
353 | + buffer[buflen - 1] = '\0'; | |
354 | + } | |
355 | + } | |
356 | + return pos; | |
357 | +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) | |
358 | + char *pos = ERR_PTR(-ENOMEM); | |
359 | + if (buflen >= 256) { | |
349 | 360 | /* rename_lock is locked/unlocked by dentry_path_raw(). */ |
350 | 361 | pos = dentry_path_raw(dentry, buffer, buflen - 1); |
351 | 362 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
@@ -478,7 +489,7 @@ | ||
478 | 489 | * |
479 | 490 | * Returns the buffer. |
480 | 491 | */ |
481 | -static char *ccs_get_socket_name(struct path *path, char * const buffer, | |
492 | +static char *ccs_get_socket_name(const struct path *path, char * const buffer, | |
482 | 493 | const int buflen) |
483 | 494 | { |
484 | 495 | struct inode *inode = path->dentry->d_inode; |
@@ -506,7 +517,7 @@ | ||
506 | 517 | * This function uses kzalloc(), so caller must kfree() if this function |
507 | 518 | * didn't return NULL. |
508 | 519 | */ |
509 | -char *ccs_realpath(struct path *path) | |
520 | +char *ccs_realpath(const struct path *path) | |
510 | 521 | { |
511 | 522 | char *buf = NULL; |
512 | 523 | char *name = NULL; |
@@ -717,30 +728,40 @@ | ||
717 | 728 | const char *ccs_get_exe(void) |
718 | 729 | { |
719 | 730 | struct mm_struct *mm = current->mm; |
720 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) | |
731 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) | |
721 | 732 | struct vm_area_struct *vma; |
722 | 733 | #endif |
723 | - const char *cp = NULL; | |
734 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) | |
735 | + struct path path; | |
736 | +#endif | |
737 | + struct file *exe_file = NULL; | |
738 | + const char *cp; | |
724 | 739 | if (!mm) |
725 | 740 | return NULL; |
726 | 741 | down_read(&mm->mmap_sem); |
727 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) | |
728 | - if (mm->exe_file) | |
729 | - cp = ccs_realpath(&mm->exe_file->f_path); | |
742 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) | |
743 | + /* Not using get_mm_exe_file() as it is not exported. */ | |
744 | + exe_file = mm->exe_file; | |
730 | 745 | #else |
731 | 746 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
732 | 747 | if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { |
733 | -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) | |
734 | - struct path path = { vma->vm_file->f_vfsmnt, | |
735 | - vma->vm_file->f_dentry }; | |
736 | - cp = ccs_realpath(&path); | |
737 | -#else | |
738 | - cp = ccs_realpath(&vma->vm_file->f_path); | |
739 | -#endif | |
748 | + exe_file = vma->vm_file; | |
740 | 749 | break; |
741 | 750 | } |
742 | 751 | } |
743 | 752 | #endif |
753 | + if (exe_file) | |
754 | + get_file(exe_file); | |
744 | 755 | up_read(&mm->mmap_sem); |
756 | + if (!exe_file) | |
757 | + return NULL; | |
758 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) | |
759 | + cp = ccs_realpath(&exe_file->f_path); | |
760 | +#else | |
761 | + path.mnt = exe_file->f_vfsmnt; | |
762 | + path.dentry = exe_file->f_dentry; | |
763 | + cp = ccs_realpath(&path); | |
764 | +#endif | |
765 | + fput(exe_file); | |
745 | 766 | return cp; |
746 | 767 | } |
@@ -1594,7 +1594,7 @@ | ||
1594 | 1594 | bool ccs_memory_ok(const void *ptr, const unsigned int size); |
1595 | 1595 | char *ccs_encode(const char *str); |
1596 | 1596 | char *ccs_encode2(const char *str, int str_len); |
1597 | -char *ccs_realpath(struct path *path); | |
1597 | +char *ccs_realpath(const struct path *path); | |
1598 | 1598 | const char *ccs_get_exe(void); |
1599 | 1599 | const struct ccs_path_info *ccs_get_name(const char *name); |
1600 | 1600 | int ccs_audit_log(struct ccs_request_info *r); |
@@ -2302,9 +2302,14 @@ | ||
2302 | 2302 | return 0; |
2303 | 2303 | #endif |
2304 | 2304 | #ifndef CONFIG_CCSECURITY_FILE_GETATTR |
2305 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) | |
2306 | + if (d_is_dir(dentry)) | |
2307 | + return 0; | |
2308 | +#else | |
2305 | 2309 | if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) |
2306 | 2310 | return 0; |
2307 | 2311 | #endif |
2312 | +#endif | |
2308 | 2313 | buf.name = NULL; |
2309 | 2314 | r.mode = CCS_CONFIG_DISABLED; |
2310 | 2315 | idx = ccs_read_lock(); |
@@ -2513,8 +2518,13 @@ | ||
2513 | 2518 | switch (operation) { |
2514 | 2519 | case CCS_TYPE_RENAME: |
2515 | 2520 | case CCS_TYPE_LINK: |
2521 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) | |
2522 | + if (!d_is_dir(dentry1)) | |
2523 | + break; | |
2524 | +#else | |
2516 | 2525 | if (!dentry1->d_inode || !S_ISDIR(dentry1->d_inode->i_mode)) |
2517 | 2526 | break; |
2527 | +#endif | |
2518 | 2528 | /* fall through */ |
2519 | 2529 | case CCS_TYPE_PIVOT_ROOT: |
2520 | 2530 | ccs_add_slash(&buf1); |
@@ -1030,9 +1030,29 @@ | ||
1030 | 1030 | |
1031 | 1031 | #endif |
1032 | 1032 | |
1033 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) | |
1034 | + | |
1033 | 1035 | /** |
1034 | 1036 | * ccs_inode_getattr - Check permission for stat(). |
1035 | 1037 | * |
1038 | + * @path: Pointer to "struct path". | |
1039 | + * | |
1040 | + * Returns 0 on success, negative value otherwise. | |
1041 | + */ | |
1042 | +static int ccs_inode_getattr(const struct path *path) | |
1043 | +{ | |
1044 | + int rc = ccs_getattr_permission(path->mnt, path->dentry); | |
1045 | + if (rc) | |
1046 | + return rc; | |
1047 | + while (!original_security_ops.inode_getattr); | |
1048 | + return original_security_ops.inode_getattr(path); | |
1049 | +} | |
1050 | + | |
1051 | +#else | |
1052 | + | |
1053 | +/** | |
1054 | + * ccs_inode_getattr - Check permission for stat(). | |
1055 | + * | |
1036 | 1056 | * @mnt: Pointer to "struct vfsmount". |
1037 | 1057 | * @dentry: Pointer to "struct dentry". |
1038 | 1058 | * |
@@ -1047,6 +1067,8 @@ | ||
1047 | 1067 | return original_security_ops.inode_getattr(mnt, dentry); |
1048 | 1068 | } |
1049 | 1069 | |
1070 | +#endif | |
1071 | + | |
1050 | 1072 | #if defined(CONFIG_SECURITY_PATH) |
1051 | 1073 | |
1052 | 1074 | #if defined(USE_UMODE_T) |