Implemented symlink unrolling before locking.
Showing
3 changed files
with
81 additions
and
3 deletions
... | @@ -84,6 +84,7 @@ typedef void *(*mu_retrieve_fp) __P((void *)); | ... | @@ -84,6 +84,7 @@ typedef void *(*mu_retrieve_fp) __P((void *)); |
84 | extern void mu_register_retriever __P((list_t *pflist, mu_retrieve_fp fun)); | 84 | extern void mu_register_retriever __P((list_t *pflist, mu_retrieve_fp fun)); |
85 | extern void * mu_retrieve __P((list_t flist, void *data)); | 85 | extern void * mu_retrieve __P((list_t flist, void *data)); |
86 | 86 | ||
87 | extern int mu_unroll_symlink __P((char *out, size_t outsz, const char *in)); | ||
87 | 88 | ||
88 | #ifdef __cplusplus | 89 | #ifdef __cplusplus |
89 | } | 90 | } | ... | ... |
... | @@ -100,21 +100,26 @@ int locker_set_default_flags(int flags) | ... | @@ -100,21 +100,26 @@ int locker_set_default_flags(int flags) |
100 | } | 100 | } |
101 | 101 | ||
102 | int | 102 | int |
103 | locker_create (locker_t *plocker, const char *filename, int flags) | 103 | locker_create (locker_t *plocker, const char *filename_, int flags) |
104 | { | 104 | { |
105 | locker_t l; | 105 | locker_t l; |
106 | char filename[_POSIX_PATH_MAX]; | ||
107 | int err = 0; | ||
106 | 108 | ||
107 | if (plocker == NULL) | 109 | if (plocker == NULL) |
108 | return MU_ERR_OUT_PTR_NULL; | 110 | return MU_ERR_OUT_PTR_NULL; |
109 | 111 | ||
110 | if (filename == NULL) | 112 | if (filename_ == NULL) |
111 | return EINVAL; | 113 | return EINVAL; |
112 | 114 | ||
115 | if((err = mu_unroll_symlink(filename, sizeof(filename), filename_))) | ||
116 | return err; | ||
117 | |||
113 | l = calloc (1, sizeof (*l)); | 118 | l = calloc (1, sizeof (*l)); |
119 | |||
114 | if (l == NULL) | 120 | if (l == NULL) |
115 | return ENOMEM; | 121 | return ENOMEM; |
116 | 122 | ||
117 | /* Should make l->file be the result of following the symlinks. */ | ||
118 | l->file = strdup(filename); | 123 | l->file = strdup(filename); |
119 | 124 | ||
120 | if (l->file == NULL) | 125 | if (l->file == NULL) | ... | ... |
... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | #include <limits.h> | ||
24 | #include <netdb.h> | 25 | #include <netdb.h> |
25 | #include <pwd.h> | 26 | #include <pwd.h> |
26 | #include <signal.h> | 27 | #include <signal.h> |
... | @@ -776,3 +777,74 @@ int mu_spawnvp (const char* prog, const char* const av_[], int* stat) | ... | @@ -776,3 +777,74 @@ int mu_spawnvp (const char* prog, const char* const av_[], int* stat) |
776 | return err; | 777 | return err; |
777 | } | 778 | } |
778 | 779 | ||
780 | |||
781 | /* The result of readlink() may be a path relative to that link, | ||
782 | * qualify it if necessary. | ||
783 | */ | ||
784 | static void | ||
785 | mu_qualify_link (const char *path, const char *link, char *qualified) | ||
786 | { | ||
787 | const char *lb = NULL; | ||
788 | size_t len; | ||
789 | |||
790 | /* link is full path */ | ||
791 | if (*link == '/') | ||
792 | { | ||
793 | mu_cpystr (qualified, link, _POSIX_PATH_MAX); | ||
794 | return; | ||
795 | } | ||
796 | |||
797 | if ((lb = strrchr (path, '/')) == NULL) | ||
798 | { | ||
799 | /* no path in link */ | ||
800 | mu_cpystr (qualified, link, _POSIX_PATH_MAX); | ||
801 | return; | ||
802 | } | ||
803 | |||
804 | len = lb - path + 1; | ||
805 | memcpy (qualified, path, len); | ||
806 | mu_cpystr (qualified + len, link, _POSIX_PATH_MAX - len); | ||
807 | } | ||
808 | |||
809 | #ifndef _POSIX_SYMLOOP_MAX | ||
810 | # define _POSIX_SYMLOOP_MAX 255 | ||
811 | #endif | ||
812 | |||
813 | int | ||
814 | mu_unroll_symlink (char *out, size_t outsz, const char *in) | ||
815 | { | ||
816 | char path[_POSIX_PATH_MAX]; | ||
817 | int symloops = 0; | ||
818 | |||
819 | while (symloops++ < _POSIX_SYMLOOP_MAX) | ||
820 | { | ||
821 | struct stat s; | ||
822 | char link[_POSIX_PATH_MAX]; | ||
823 | char qualified[_POSIX_PATH_MAX]; | ||
824 | int len; | ||
825 | |||
826 | if (lstat (in, &s) == -1) | ||
827 | return errno; | ||
828 | |||
829 | if (!S_ISLNK (s.st_mode)) | ||
830 | { | ||
831 | mu_cpystr (path, in, sizeof (path)); | ||
832 | break; | ||
833 | } | ||
834 | |||
835 | if ((len = readlink (in, link, sizeof (link))) == -1) | ||
836 | return errno; | ||
837 | |||
838 | link[(len >= sizeof (link)) ? (sizeof (link) - 1) : len] = '\0'; | ||
839 | |||
840 | mu_qualify_link (in, link, qualified); | ||
841 | |||
842 | mu_cpystr (path, qualified, sizeof (path)); | ||
843 | |||
844 | in = path; | ||
845 | } | ||
846 | |||
847 | mu_cpystr (out, path, outsz); | ||
848 | |||
849 | return 0; | ||
850 | } | ... | ... |
-
Please register or sign in to post a comment