diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/fs/udf/unicode.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/fs/udf/unicode.c')
-rw-r--r-- | kernel/fs/udf/unicode.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/kernel/fs/udf/unicode.c b/kernel/fs/udf/unicode.c index b84fee372..e788a05aa 100644 --- a/kernel/fs/udf/unicode.c +++ b/kernel/fs/udf/unicode.c @@ -68,21 +68,16 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) /* * udf_build_ustr_exact */ -static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) +static void udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) { - if ((!dest) || (!ptr) || (!exactsize)) - return -1; - memset(dest, 0, sizeof(struct ustr)); dest->u_cmpID = ptr[0]; dest->u_len = exactsize - 1; memcpy(dest->u_name, ptr + 1, exactsize - 1); - - return 0; } /* - * udf_ocu_to_utf8 + * udf_CS0toUTF8 * * PURPOSE * Convert OSTA Compressed Unicode to the UTF-8 equivalent. @@ -94,7 +89,7 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) * both of type "struct ustr *" * * POST-CONDITIONS - * <return> Zero on success. + * <return> >= 0 on success. * * HISTORY * November 12, 1997 - Andrew E. Mileski @@ -117,7 +112,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) memset(utf_o, 0, sizeof(struct ustr)); pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name); - return 0; + return -EINVAL; } ocu = ocu_i->u_name; @@ -133,11 +128,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) if (c < 0x80U) utf_o->u_name[utf_o->u_len++] = (uint8_t)c; else if (c < 0x800U) { + if (utf_o->u_len > (UDF_NAME_LEN - 4)) + break; utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6)); utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f)); } else { + if (utf_o->u_len > (UDF_NAME_LEN - 5)) + break; utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12)); utf_o->u_name[utf_o->u_len++] = @@ -154,7 +153,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) /* * - * udf_utf8_to_ocu + * udf_UTF8toCS0 * * PURPOSE * Convert UTF-8 to the OSTA Compressed Unicode equivalent. @@ -178,17 +177,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) { unsigned c, i, max_val, utf_char; - int utf_cnt, u_len; + int utf_cnt, u_len, u_ch; memset(ocu, 0, sizeof(dstring) * length); ocu[0] = 8; max_val = 0xffU; + u_ch = 1; try_again: u_len = 0U; utf_char = 0U; utf_cnt = 0U; for (i = 0U; i < utf->u_len; i++) { + /* Name didn't fit? */ + if (u_len + 1 + u_ch >= length) + return 0; + c = (uint8_t)utf->u_name[i]; /* Complete a multi-byte UTF-8 character */ @@ -230,6 +234,7 @@ try_again: if (max_val == 0xffU) { max_val = 0xffffU; ocu[0] = (uint8_t)0x10U; + u_ch = 2; goto try_again; } goto error_out; @@ -270,7 +275,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, memset(utf_o, 0, sizeof(struct ustr)); pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name); - return 0; + return -EINVAL; } ocu = ocu_i->u_name; @@ -282,7 +287,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, c = (c << 8) | ocu[i++]; len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - utf_o->u_len); + UDF_NAME_LEN - 2 - utf_o->u_len); /* Valid character? */ if (len >= 0) utf_o->u_len += len; @@ -300,15 +305,19 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int len; unsigned i, max_val; uint16_t uni_char; - int u_len; + int u_len, u_ch; memset(ocu, 0, sizeof(dstring) * length); ocu[0] = 8; max_val = 0xffU; + u_ch = 1; try_again: u_len = 0U; for (i = 0U; i < uni->u_len; i++) { + /* Name didn't fit? */ + if (u_len + 1 + u_ch >= length) + return 0; len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); if (!len) continue; @@ -321,6 +330,7 @@ try_again: if (uni_char > max_val) { max_val = 0xffffU; ocu[0] = (uint8_t)0x10U; + u_ch = 2; goto try_again; } @@ -338,43 +348,51 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, uint8_t *dname, int dlen) { struct ustr *filename, *unifilename; - int len = 0; + int ret; + + if (!slen) + return -EIO; filename = kmalloc(sizeof(struct ustr), GFP_NOFS); if (!filename) - return 0; + return -ENOMEM; unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); - if (!unifilename) + if (!unifilename) { + ret = -ENOMEM; goto out1; + } - if (udf_build_ustr_exact(unifilename, sname, slen)) - goto out2; - + udf_build_ustr_exact(unifilename, sname, slen); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { - if (!udf_CS0toUTF8(filename, unifilename)) { + ret = udf_CS0toUTF8(filename, unifilename); + if (ret < 0) { udf_debug("Failed in udf_get_filename: sname = %s\n", sname); goto out2; } } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { - if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, - unifilename)) { + ret = udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, + unifilename); + if (ret < 0) { udf_debug("Failed in udf_get_filename: sname = %s\n", sname); goto out2; } } else - goto out2; + BUG(); - len = udf_translate_to_linux(dname, dlen, + ret = udf_translate_to_linux(dname, dlen, filename->u_name, filename->u_len, unifilename->u_name, unifilename->u_len); + /* Zero length filename isn't valid... */ + if (ret == 0) + ret = -EINVAL; out2: kfree(unifilename); out1: kfree(filename); - return len; + return ret; } int udf_put_filename(struct super_block *sb, const uint8_t *sname, |