diff options
Diffstat (limited to 'coreutils/ls.c')
-rw-r--r-- | coreutils/ls.c | 94 |
1 files changed, 81 insertions, 13 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 4a4956611..6245361e9 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -62,6 +62,11 @@ enum { | |||
62 | #include <termios.h> | 62 | #include <termios.h> |
63 | #include <sys/ioctl.h> | 63 | #include <sys/ioctl.h> |
64 | #include "busybox.h" | 64 | #include "busybox.h" |
65 | #ifdef CONFIG_SELINUX | ||
66 | #include <fs_secure.h> | ||
67 | #include <flask_util.h> | ||
68 | #include <ss.h> | ||
69 | #endif | ||
65 | 70 | ||
66 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | 71 | #ifdef CONFIG_FEATURE_LS_TIMESTAMPS |
67 | #include <time.h> | 72 | #include <time.h> |
@@ -89,14 +94,15 @@ enum { | |||
89 | #define LIST_NLINKS (1U<<3) | 94 | #define LIST_NLINKS (1U<<3) |
90 | #define LIST_ID_NAME (1U<<4) | 95 | #define LIST_ID_NAME (1U<<4) |
91 | #define LIST_ID_NUMERIC (1U<<5) | 96 | #define LIST_ID_NUMERIC (1U<<5) |
92 | #define LIST_SIZE (1U<<6) | 97 | #define LIST_CONTEXT (1U<<6) |
93 | #define LIST_DEV (1U<<7) | 98 | #define LIST_SIZE (1U<<7) |
94 | #define LIST_DATE_TIME (1U<<8) | 99 | #define LIST_DEV (1U<<8) |
95 | #define LIST_FULLTIME (1U<<9) | 100 | #define LIST_DATE_TIME (1U<<9) |
96 | #define LIST_FILENAME (1U<<10) | 101 | #define LIST_FULLTIME (1U<<10) |
97 | #define LIST_SYMLINK (1U<<11) | 102 | #define LIST_FILENAME (1U<<11) |
98 | #define LIST_FILETYPE (1U<<12) | 103 | #define LIST_SYMLINK (1U<<12) |
99 | #define LIST_EXEC (1U<<13) | 104 | #define LIST_FILETYPE (1U<<13) |
105 | #define LIST_EXEC (1U<<14) | ||
100 | 106 | ||
101 | #define LIST_MASK ((LIST_EXEC << 1) - 1) | 107 | #define LIST_MASK ((LIST_EXEC << 1) - 1) |
102 | 108 | ||
@@ -179,6 +185,9 @@ struct dnode { /* the basic node */ | |||
179 | char *name; /* the dir entry name */ | 185 | char *name; /* the dir entry name */ |
180 | char *fullname; /* the dir entry name */ | 186 | char *fullname; /* the dir entry name */ |
181 | struct stat dstat; /* the file stat info */ | 187 | struct stat dstat; /* the file stat info */ |
188 | #ifdef CONFIG_SELINUX | ||
189 | security_id_t sid; | ||
190 | #endif | ||
182 | struct dnode *next; /* point at the next node */ | 191 | struct dnode *next; /* point at the next node */ |
183 | }; | 192 | }; |
184 | typedef struct dnode dnode_t; | 193 | typedef struct dnode dnode_t; |
@@ -189,6 +198,10 @@ static int list_single(struct dnode *); | |||
189 | 198 | ||
190 | static unsigned int all_fmt; | 199 | static unsigned int all_fmt; |
191 | 200 | ||
201 | #ifdef CONFIG_SELINUX | ||
202 | static int is_flask_enabled_flag; | ||
203 | #endif | ||
204 | |||
192 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 205 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
193 | static unsigned short terminal_width = TERMINAL_WIDTH; | 206 | static unsigned short terminal_width = TERMINAL_WIDTH; |
194 | static unsigned short tabstops = COLUMN_GAP; | 207 | static unsigned short tabstops = COLUMN_GAP; |
@@ -203,26 +216,49 @@ static struct dnode *my_stat(char *fullname, char *name) | |||
203 | { | 216 | { |
204 | struct stat dstat; | 217 | struct stat dstat; |
205 | struct dnode *cur; | 218 | struct dnode *cur; |
219 | #ifdef CONFIG_SELINUX | ||
220 | security_id_t sid; | ||
221 | #endif | ||
222 | int rc; | ||
206 | 223 | ||
207 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS | 224 | #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS |
208 | if (all_fmt & FOLLOW_LINKS) { | 225 | if (all_fmt & FOLLOW_LINKS) { |
209 | if (stat(fullname, &dstat)) { | 226 | #ifdef CONFIG_SELINUX |
227 | if(is_flask_enabled_flag) | ||
228 | rc = stat_secure(fullname, &dstat, &sid); | ||
229 | else | ||
230 | #endif | ||
231 | rc = stat(fullname, &dstat); | ||
232 | if(rc) | ||
233 | { | ||
210 | bb_perror_msg("%s", fullname); | 234 | bb_perror_msg("%s", fullname); |
211 | status = EXIT_FAILURE; | 235 | status = EXIT_FAILURE; |
212 | return 0; | 236 | return 0; |
213 | } | 237 | } |
214 | } else | 238 | } else |
215 | #endif | 239 | #endif |
216 | if (lstat(fullname, &dstat)) { | 240 | { |
217 | bb_perror_msg("%s", fullname); | 241 | #ifdef CONFIG_SELINUX |
218 | status = EXIT_FAILURE; | 242 | if(is_flask_enabled_flag) |
219 | return 0; | 243 | rc = lstat_secure(fullname, &dstat, &sid); |
244 | else | ||
245 | #endif | ||
246 | rc = lstat(fullname, &dstat); | ||
247 | if(rc) | ||
248 | { | ||
249 | bb_perror_msg("%s", fullname); | ||
250 | status = EXIT_FAILURE; | ||
251 | return 0; | ||
252 | } | ||
220 | } | 253 | } |
221 | 254 | ||
222 | cur = (struct dnode *) xmalloc(sizeof(struct dnode)); | 255 | cur = (struct dnode *) xmalloc(sizeof(struct dnode)); |
223 | cur->fullname = fullname; | 256 | cur->fullname = fullname; |
224 | cur->name = name; | 257 | cur->name = name; |
225 | cur->dstat = dstat; | 258 | cur->dstat = dstat; |
259 | #ifdef CONFIG_SELINUX | ||
260 | cur->sid = sid; | ||
261 | #endif | ||
226 | return cur; | 262 | return cur; |
227 | } | 263 | } |
228 | 264 | ||
@@ -451,6 +487,9 @@ static void showfiles(struct dnode **dn, int nfiles) | |||
451 | /* find the longest file name- use that as the column width */ | 487 | /* find the longest file name- use that as the column width */ |
452 | for (i = 0; i < nfiles; i++) { | 488 | for (i = 0; i < nfiles; i++) { |
453 | int len = strlen(dn[i]->name) + | 489 | int len = strlen(dn[i]->name) + |
490 | #ifdef CONFIG_SELINUX | ||
491 | ((all_fmt & LIST_CONTEXT) ? 33 : 0) + | ||
492 | #endif | ||
454 | ((all_fmt & LIST_INO) ? 8 : 0) + | 493 | ((all_fmt & LIST_INO) ? 8 : 0) + |
455 | ((all_fmt & LIST_BLOCKS) ? 5 : 0); | 494 | ((all_fmt & LIST_BLOCKS) ? 5 : 0); |
456 | if (column_width < len) | 495 | if (column_width < len) |
@@ -695,6 +734,21 @@ static int list_single(struct dnode *dn) | |||
695 | column += 13; | 734 | column += 13; |
696 | break; | 735 | break; |
697 | #endif | 736 | #endif |
737 | #ifdef CONFIG_SELINUX | ||
738 | case LIST_CONTEXT: | ||
739 | { | ||
740 | char context[64]; | ||
741 | int len = sizeof(context); | ||
742 | if(security_sid_to_context(dn->sid, context, &len)) | ||
743 | { | ||
744 | strcpy(context, "unknown"); | ||
745 | len = 7; | ||
746 | } | ||
747 | printf("%-32s ", context); | ||
748 | column += MAX(33, len); | ||
749 | } | ||
750 | break; | ||
751 | #endif | ||
698 | case LIST_FILENAME: | 752 | case LIST_FILENAME: |
699 | #ifdef CONFIG_FEATURE_LS_COLOR | 753 | #ifdef CONFIG_FEATURE_LS_COLOR |
700 | errno = 0; | 754 | errno = 0; |
@@ -774,6 +828,9 @@ static const char ls_opts[] = "1AaCdgilnsx" | |||
774 | "h" | 828 | "h" |
775 | #endif | 829 | #endif |
776 | "k" | 830 | "k" |
831 | #ifdef CONFIG_SELINUX | ||
832 | "K" | ||
833 | #endif | ||
777 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 834 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
778 | "T:w:" | 835 | "T:w:" |
779 | #endif | 836 | #endif |
@@ -834,7 +891,12 @@ static const unsigned opt_flags[] = { | |||
834 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 891 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
835 | LS_DISP_HR, /* h */ | 892 | LS_DISP_HR, /* h */ |
836 | #endif | 893 | #endif |
894 | #ifndef CONFIG_SELINUX | ||
837 | 0, /* k - ingored */ | 895 | 0, /* k - ingored */ |
896 | #else | ||
897 | LIST_CONTEXT, /* k */ | ||
898 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ | ||
899 | #endif | ||
838 | }; | 900 | }; |
839 | 901 | ||
840 | 902 | ||
@@ -849,6 +911,9 @@ extern int ls_main(int argc, char **argv) | |||
849 | int opt; | 911 | int opt; |
850 | int oi, ac; | 912 | int oi, ac; |
851 | char **av; | 913 | char **av; |
914 | #ifdef CONFIG_SELINUX | ||
915 | is_flask_enabled_flag = is_flask_enabled(); | ||
916 | #endif | ||
852 | 917 | ||
853 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 918 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
854 | struct winsize win = { 0, 0, 0, 0 }; | 919 | struct winsize win = { 0, 0, 0, 0 }; |
@@ -911,6 +976,9 @@ extern int ls_main(int argc, char **argv) | |||
911 | if (flags & TIME_MASK_TRIGGER) { | 976 | if (flags & TIME_MASK_TRIGGER) { |
912 | all_fmt &= ~TIME_MASK; | 977 | all_fmt &= ~TIME_MASK; |
913 | } | 978 | } |
979 | if (flags & LIST_CONTEXT) { | ||
980 | all_fmt |= STYLE_SINGLE; | ||
981 | } | ||
914 | #ifdef CONFIG_FEATURE_HUMAN_READABLE | 982 | #ifdef CONFIG_FEATURE_HUMAN_READABLE |
915 | if (opt == 'l') { | 983 | if (opt == 'l') { |
916 | all_fmt &= ~LS_DISP_HR; | 984 | all_fmt &= ~LS_DISP_HR; |