Roland Mainz
2013-09-18 00:47:28 UTC
Hi!
----
Attached (as "astksh20130913_pathcanon_more_flags_sizereduction001.diff.txt")
is a small patch which adds a few more flags to /dev/file/flags@ and
reduces the size somewhat...
* Notes:
- |O_@(NOLINKS|NOFOLLOW)| were added per CERN's request to have a way
to avoid link stunts (for example for permission escalation) in system
scripts. Just doing it with [[ ]] flags doesn't work because there is
still a timing gap between test and |open()| which can be exploited by
an user... and the students seem to have a lot of free time to
try&&try&&try... forever... grrr...
- I added |O_SEARCH| to have a way to open a directory fd without
having the read permission (usefull for cd(1))
- |O_EXEC| was added mostly for completeness and as counterpart for
|O_SEARCH|. No real usage yet (but it's usefull at least for kernel
debugging) ...
- |O_*SYNC| variants for syncronous read/write/etc. should be complete
now (|O_DSYNC|, |O_RSYNC|, |OSYNC|)
- Code size has been reduced from 43616 to 40584 bytes for pathcanon.o
-- snip --
1116829 41 -rw-r--r-- 1 test001 users 40584 Sep 18 02:25
./build_pathcanon_moreflags/arch/sol11.i386-64/src/lib/libast/pathcanon.o
1093235 44 -rw-r--r-- 1 test001 users 43616 Sep 14 00:33
./build_i386_64bit_debug_normal/arch/sol11.i386-64/src/lib/libast/pathcanon.o
-- snip --
Glenn: Is the patch OK for you ?
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
-------------- next part --------------
diff -r -u original/src/lib/libast/path/pathcanon.c build_xattr/src/lib/libast/path/pathcanon.c
--- src/lib/libast/path/pathcanon.c 2013-09-13 21:01:05.000000000 +0200
+++ src/lib/libast/path/pathcanon.c 2013-09-18 02:34:21.257331790 +0200
@@ -65,6 +65,134 @@
#include <ast_api.h>
+struct openflagmap
+{
+ const char name[15];
+ const char namelen;
+ int flag;
+};
+
+static const
+struct openflagmap ofmap[]=
+{
+ {
+ "async", 5,
+#ifdef O_ASYNC
+ O_ASYNC
+#else
+ 0
+#endif
+ },
+ {
+ "direct", 6,
+#ifdef O_DIRECT
+ O_DIRECT
+#else
+ 0
+#endif
+ },
+ {
+ "directory", 9,
+#ifdef O_DIRECTORY
+ O_DIRECTORY
+#else
+ 0
+#endif
+ },
+ {
+ "dsync", 5,
+#ifdef O_DSYNC
+ O_DSYNC
+#else
+ 0
+#endif
+ },
+ {
+ "exec", 4,
+#ifdef O_EXEC
+ O_EXEC
+#else
+ 0
+#endif
+ },
+ {
+ "nolinks", 7,
+#ifdef O_NOLINKS
+ O_NOLINKS
+#else
+ 0
+#endif
+ },
+ {
+ "nonblock", 8,
+#ifdef O_NONBLOCK
+ O_NONBLOCK
+#else
+ 0
+#endif
+ },
+ {
+ "nofollow", 8,
+#ifdef O_NOFOLLOW
+ O_NOFOLLOW
+#else
+ 0
+#endif
+ },
+ {
+ "rsync", 5,
+#ifdef O_RSYNC
+ O_RSYNC
+#else
+ 0
+#endif
+ },
+ {
+ "search", 6,
+#ifdef O_SEARCH
+ O_SEARCH
+#else
+ 0
+#endif
+ },
+ {
+ "sync", 4,
+#ifdef O_SYNC
+ O_SYNC
+#else
+ 0
+#endif
+ },
+ {
+ "xattr", 5,
+#ifdef O_XATTR
+ O_XATTR
+#else
+ 0
+#endif
+ },
+ { "", 0, 0 }
+};
+
+static
+const struct openflagmap *pathdev_str2openflag(const char *s)
+{
+ register size_t sz;
+ const struct openflagmap *o;
+
+ for (o=ofmap ; o->namelen != 0 ; o++)
+ {
+ sz = o->namelen;
+ if (!strncmp(s, o->name, sz) &&
+ ((s[sz] == '@') || (s[sz] == ',')))
+ {
+ return (o);
+ }
+ }
+ return (NULL);
+}
+
+
char*
pathcanon_20100601(char* path, size_t size, int flags)
{
@@ -249,76 +377,26 @@
NEXT(s, 4);
if (s[0] == 'f' && s[1] == 'l' && s[2] == 'a' && s[3] == 'g' && s[4] == 's' && s[5] == '@')
{
+ const struct openflagmap *ofm;
+
s += 6;
for (;;)
{
- if (s[0] == 'a' && s[1] == 's' && s[2] == 'y' && s[3] == 'n' && s[4] == 'c' && (s[5] == ',' || s[5] == '@'))
- {
-#ifdef O_ASYNC
- s += 5;
- dev->oflags |= O_ASYNC;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 'd' && s[1] == 'i' && s[2] == 'r' && s[3] == 'e' && s[4] == 'c' && s[5] == 't')
+ /* Be nice and eat leading ',' */
+ while(*s==',')
+ s++;
+
+ if (ofm = pathdev_str2openflag(s))
{
- if (s[6] == ',' || s[6] == '@')
+ /* Is this flag supported on this platform ? */
+ if (ofm->flag == 0)
{
-#ifdef O_DIRECT
- s += 6;
- dev->oflags |= O_DIRECT;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[6] == 'o' && s[7] == 'r' && s[8] == 'y' && (s[9] == ',' || s[9] == '@'))
- {
-#ifdef O_DIRECTORY
- s += 9;
- dev->oflags |= O_DIRECTORY;
-#else
errno = ENXIO;
return 0;
-#endif
- }
- else
- {
- errno = EINVAL;
- return 0;
}
- }
- else if (s[0] == 'n' && s[1] == 'o' && s[2] == 'n' && s[3] == 'b' && s[4] == 'l' && s[5] == 'o' && s[6] == 'c' && s[7] == 'k' && (s[8] == ',' || s[8] == '@'))
- {
-#ifdef O_NONBLOCK
- s += 8;
- dev->oflags |= O_NONBLOCK;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 's' && s[1] == 'y' && s[2] == 'n' && s[3] == 'c' && (s[4] == ',' || s[4] == '@'))
- {
-#ifdef O_SYNC
- s += 4;
- dev->oflags |= O_SYNC;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 'x' && s[1] == 'a' && s[2] == 't' && s[3] == 't' && s[4] == 'r' && (s[5] == ',' || s[5] == '@'))
- {
-#ifdef O_XATTR
- s += 5;
- dev->oflags |= O_XATTR;
-#else
- errno = ENXIO;
- return 0;
-#endif
+
+ dev->oflags |= ofm->flag;
+ s += ofm->namelen;
}
else if (*s != '@')
{
@@ -766,5 +844,5 @@
dots = 4;
break;
}
- return 0;
+ /*NOTREACHED*/
}
Only in build_xattr/src/lib/libast/path: pathcanon.c.orig
----
Attached (as "astksh20130913_pathcanon_more_flags_sizereduction001.diff.txt")
is a small patch which adds a few more flags to /dev/file/flags@ and
reduces the size somewhat...
* Notes:
- |O_@(NOLINKS|NOFOLLOW)| were added per CERN's request to have a way
to avoid link stunts (for example for permission escalation) in system
scripts. Just doing it with [[ ]] flags doesn't work because there is
still a timing gap between test and |open()| which can be exploited by
an user... and the students seem to have a lot of free time to
try&&try&&try... forever... grrr...
- I added |O_SEARCH| to have a way to open a directory fd without
having the read permission (usefull for cd(1))
- |O_EXEC| was added mostly for completeness and as counterpart for
|O_SEARCH|. No real usage yet (but it's usefull at least for kernel
debugging) ...
- |O_*SYNC| variants for syncronous read/write/etc. should be complete
now (|O_DSYNC|, |O_RSYNC|, |OSYNC|)
- Code size has been reduced from 43616 to 40584 bytes for pathcanon.o
-- snip --
1116829 41 -rw-r--r-- 1 test001 users 40584 Sep 18 02:25
./build_pathcanon_moreflags/arch/sol11.i386-64/src/lib/libast/pathcanon.o
1093235 44 -rw-r--r-- 1 test001 users 43616 Sep 14 00:33
./build_i386_64bit_debug_normal/arch/sol11.i386-64/src/lib/libast/pathcanon.o
-- snip --
Glenn: Is the patch OK for you ?
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
-------------- next part --------------
diff -r -u original/src/lib/libast/path/pathcanon.c build_xattr/src/lib/libast/path/pathcanon.c
--- src/lib/libast/path/pathcanon.c 2013-09-13 21:01:05.000000000 +0200
+++ src/lib/libast/path/pathcanon.c 2013-09-18 02:34:21.257331790 +0200
@@ -65,6 +65,134 @@
#include <ast_api.h>
+struct openflagmap
+{
+ const char name[15];
+ const char namelen;
+ int flag;
+};
+
+static const
+struct openflagmap ofmap[]=
+{
+ {
+ "async", 5,
+#ifdef O_ASYNC
+ O_ASYNC
+#else
+ 0
+#endif
+ },
+ {
+ "direct", 6,
+#ifdef O_DIRECT
+ O_DIRECT
+#else
+ 0
+#endif
+ },
+ {
+ "directory", 9,
+#ifdef O_DIRECTORY
+ O_DIRECTORY
+#else
+ 0
+#endif
+ },
+ {
+ "dsync", 5,
+#ifdef O_DSYNC
+ O_DSYNC
+#else
+ 0
+#endif
+ },
+ {
+ "exec", 4,
+#ifdef O_EXEC
+ O_EXEC
+#else
+ 0
+#endif
+ },
+ {
+ "nolinks", 7,
+#ifdef O_NOLINKS
+ O_NOLINKS
+#else
+ 0
+#endif
+ },
+ {
+ "nonblock", 8,
+#ifdef O_NONBLOCK
+ O_NONBLOCK
+#else
+ 0
+#endif
+ },
+ {
+ "nofollow", 8,
+#ifdef O_NOFOLLOW
+ O_NOFOLLOW
+#else
+ 0
+#endif
+ },
+ {
+ "rsync", 5,
+#ifdef O_RSYNC
+ O_RSYNC
+#else
+ 0
+#endif
+ },
+ {
+ "search", 6,
+#ifdef O_SEARCH
+ O_SEARCH
+#else
+ 0
+#endif
+ },
+ {
+ "sync", 4,
+#ifdef O_SYNC
+ O_SYNC
+#else
+ 0
+#endif
+ },
+ {
+ "xattr", 5,
+#ifdef O_XATTR
+ O_XATTR
+#else
+ 0
+#endif
+ },
+ { "", 0, 0 }
+};
+
+static
+const struct openflagmap *pathdev_str2openflag(const char *s)
+{
+ register size_t sz;
+ const struct openflagmap *o;
+
+ for (o=ofmap ; o->namelen != 0 ; o++)
+ {
+ sz = o->namelen;
+ if (!strncmp(s, o->name, sz) &&
+ ((s[sz] == '@') || (s[sz] == ',')))
+ {
+ return (o);
+ }
+ }
+ return (NULL);
+}
+
+
char*
pathcanon_20100601(char* path, size_t size, int flags)
{
@@ -249,76 +377,26 @@
NEXT(s, 4);
if (s[0] == 'f' && s[1] == 'l' && s[2] == 'a' && s[3] == 'g' && s[4] == 's' && s[5] == '@')
{
+ const struct openflagmap *ofm;
+
s += 6;
for (;;)
{
- if (s[0] == 'a' && s[1] == 's' && s[2] == 'y' && s[3] == 'n' && s[4] == 'c' && (s[5] == ',' || s[5] == '@'))
- {
-#ifdef O_ASYNC
- s += 5;
- dev->oflags |= O_ASYNC;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 'd' && s[1] == 'i' && s[2] == 'r' && s[3] == 'e' && s[4] == 'c' && s[5] == 't')
+ /* Be nice and eat leading ',' */
+ while(*s==',')
+ s++;
+
+ if (ofm = pathdev_str2openflag(s))
{
- if (s[6] == ',' || s[6] == '@')
+ /* Is this flag supported on this platform ? */
+ if (ofm->flag == 0)
{
-#ifdef O_DIRECT
- s += 6;
- dev->oflags |= O_DIRECT;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[6] == 'o' && s[7] == 'r' && s[8] == 'y' && (s[9] == ',' || s[9] == '@'))
- {
-#ifdef O_DIRECTORY
- s += 9;
- dev->oflags |= O_DIRECTORY;
-#else
errno = ENXIO;
return 0;
-#endif
- }
- else
- {
- errno = EINVAL;
- return 0;
}
- }
- else if (s[0] == 'n' && s[1] == 'o' && s[2] == 'n' && s[3] == 'b' && s[4] == 'l' && s[5] == 'o' && s[6] == 'c' && s[7] == 'k' && (s[8] == ',' || s[8] == '@'))
- {
-#ifdef O_NONBLOCK
- s += 8;
- dev->oflags |= O_NONBLOCK;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 's' && s[1] == 'y' && s[2] == 'n' && s[3] == 'c' && (s[4] == ',' || s[4] == '@'))
- {
-#ifdef O_SYNC
- s += 4;
- dev->oflags |= O_SYNC;
-#else
- errno = ENXIO;
- return 0;
-#endif
- }
- else if (s[0] == 'x' && s[1] == 'a' && s[2] == 't' && s[3] == 't' && s[4] == 'r' && (s[5] == ',' || s[5] == '@'))
- {
-#ifdef O_XATTR
- s += 5;
- dev->oflags |= O_XATTR;
-#else
- errno = ENXIO;
- return 0;
-#endif
+
+ dev->oflags |= ofm->flag;
+ s += ofm->namelen;
}
else if (*s != '@')
{
@@ -766,5 +844,5 @@
dots = 4;
break;
}
- return 0;
+ /*NOTREACHED*/
}
Only in build_xattr/src/lib/libast/path: pathcanon.c.orig