[RFC V0] Exminating the use of HFSPLUS_ATTR_MAX_STRLEN c.f. non-English attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hin-Tak Leung <htl10@xxxxxxxxxxxxxxxxxxxxx>

This isn't a real patch but just an RFC of examination of all usages of
HFSPLUS_ATTR_MAX_STRLEN .

Actually it turns out to be rather simple - except for
one use calling hfsplus_asc2uni (which should stay the same) and
one use calling hfsplus_uni2asc (which was changed in the just submitted
patch), all the other uses are of the forms:

1. char buffer[size]

2. bound check: "if (input_length > size) return failure;"

The buffer size change is simple enough - conversion between on-disk and char
(in whichever direction) always needs to be in the worst, so any char buffer
with that size almost all needs to have a NLS_MAX_CHARSET_SIZE x . They also
all need to switch to dynamic allocation (not done here yet, just for
simplicity ATM), and also possibly need to do kzalloc(?or null terminated
on first use?) since some of them are involved in strcpy.
(unlike the case of file names, which goes around with a length and
used as is).

The bound checks are all wrong. since they are all of comparing
nls_length to unicode_length_limit . changing them to comparing
nls_length to (unicode_length_limit * NLS_MAX) is rather stupid and useless.

So really, we want a cheap function to calculate the unicode length
of a given nls string, and do that instead of calling strlen() as many of these
functions do; and distinguish the two lengths where it matters.

Also, we have two other complications - sometimes the nls length is added to
XATTR_TRUSTED_PREFIX_LEN,XATTR_SECURITY_PREFIX_LEN,XATTR_MAC_OSX_PREFIX_LEN .
Can we assume that XATTR_TRUSTED_PREFIX, XATTR_SECURITY_PREFIX and
XATTR_MAC_OSX_PREFIX will forever stay Engish (i.e. their ascii length
is the same as their unicode length)?

Also with the switch to dynamic allocation, many of the routines
which formerly does

return hfsplus_{get,set}xattr(dentry, xattr_name ...)

needs to be turned into:

   int res;
   ...
   res = hfsplus_{get,set}xattr(dentry, xattr_name ...)
   kfree(xattr_name);
   return res;

As outlined above, all the changes are relatively mundane and tedious,
other than that of calculating the unicode length of an nls string.
Writing a wrapper around hfsplus_asc2uni is one possibility,
except it either returns a len or -ENAMETOOLONG, so we possibly
should convert all the length-based bound check to tests
for failure of conversion to unicode of length of
say HFSPLUS_ATTR_MAX_STRLEN - XATTR_MAC_OSX_PREFIX, and just
test for -ENAMETOOLONG or other failure instead.

Signed-off-by: Hin-Tak Leung <htl10@xxxxxxxxxxxxxxxxxxxxx>
---
 fs/hfsplus/attributes.c     |  2 +-
 fs/hfsplus/xattr.c          |  8 ++++----
 fs/hfsplus/xattr_security.c | 12 ++++++------
 fs/hfsplus/xattr_trusted.c  |  8 ++++----
 fs/hfsplus/xattr_user.c     |  8 ++++----
 5 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/fs/hfsplus/attributes.c b/fs/hfsplus/attributes.c
index caf89a7..86422bf 100644
--- a/fs/hfsplus/attributes.c
+++ b/fs/hfsplus/attributes.c
@@ -55,7 +55,7 @@ int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key,
 	key->attr.cnid = cpu_to_be32(cnid);
 	if (name) {
 		len = strlen(name);
-		if (len > HFSPLUS_ATTR_MAX_STRLEN) {
+		if (len > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN) {
 			pr_err("invalid xattr name's length\n");
 			return -EINVAL;
 		}
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 3034ce6..04b8f5b 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -805,14 +805,14 @@ end_removexattr:
 static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name,
 					void *buffer, size_t size, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN +
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN +
 				XATTR_MAC_OSX_PREFIX_LEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	/*
@@ -828,14 +828,14 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name,
 static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
 		const void *buffer, size_t size, int flags, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN +
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN +
 				XATTR_MAC_OSX_PREFIX_LEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	/*
diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c
index 0072276..4dfa15e 100644
--- a/fs/hfsplus/xattr_security.c
+++ b/fs/hfsplus/xattr_security.c
@@ -14,13 +14,13 @@
 static int hfsplus_security_getxattr(struct dentry *dentry, const char *name,
 					void *buffer, size_t size, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_SECURITY_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_SECURITY_PREFIX);
@@ -32,13 +32,13 @@ static int hfsplus_security_getxattr(struct dentry *dentry, const char *name,
 static int hfsplus_security_setxattr(struct dentry *dentry, const char *name,
 		const void *buffer, size_t size, int flags, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_SECURITY_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_SECURITY_PREFIX);
@@ -62,7 +62,7 @@ static int hfsplus_initxattrs(struct inode *inode,
 				void *fs_info)
 {
 	const struct xattr *xattr;
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t xattr_name_len;
 	int err = 0;
 
@@ -73,7 +73,7 @@ static int hfsplus_initxattrs(struct inode *inode,
 			continue;
 
 		if (xattr_name_len + XATTR_SECURITY_PREFIX_LEN >
-				HFSPLUS_ATTR_MAX_STRLEN)
+				NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 			return -EOPNOTSUPP;
 
 		strcpy(xattr_name, XATTR_SECURITY_PREFIX);
diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c
index 426cee2..965593b 100644
--- a/fs/hfsplus/xattr_trusted.c
+++ b/fs/hfsplus/xattr_trusted.c
@@ -12,13 +12,13 @@
 static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name,
 					void *buffer, size_t size, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_TRUSTED_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_TRUSTED_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_TRUSTED_PREFIX);
@@ -30,13 +30,13 @@ static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name,
 static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name,
 		const void *buffer, size_t size, int flags, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_TRUSTED_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_TRUSTED_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_TRUSTED_PREFIX);
diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c
index e340165..8ead0640 100644
--- a/fs/hfsplus/xattr_user.c
+++ b/fs/hfsplus/xattr_user.c
@@ -12,13 +12,13 @@
 static int hfsplus_user_getxattr(struct dentry *dentry, const char *name,
 					void *buffer, size_t size, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_USER_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_USER_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_USER_PREFIX);
@@ -30,13 +30,13 @@ static int hfsplus_user_getxattr(struct dentry *dentry, const char *name,
 static int hfsplus_user_setxattr(struct dentry *dentry, const char *name,
 		const void *buffer, size_t size, int flags, int type)
 {
-	char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
+	char xattr_name[NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
 	size_t len = strlen(name);
 
 	if (!strcmp(name, ""))
 		return -EINVAL;
 
-	if (len + XATTR_USER_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
+	if (len + XATTR_USER_PREFIX_LEN > NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN)
 		return -EOPNOTSUPP;
 
 	strcpy(xattr_name, XATTR_USER_PREFIX);
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux