1 Star 0 Fork 49

小小鸟儿/samba

forked from src-openEuler/samba 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
backport-0005-CVE-2021-44142.patch 5.25 KB
一键复制 编辑 原始数据 按行查看 历史
From 0e2b3fb982d1f53d111e10d9197ed2ec2e13712c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Thu, 13 Jan 2022 17:03:02 +0100
Subject: [PATCH 07/99] CVE-2021-44142: libadouble: harden parsing code
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
selftest/knownfail.d/samba.unittests.adouble | 3 -
source3/lib/adouble.c | 115 ++++++++++++++++---
2 files changed, 101 insertions(+), 17 deletions(-)
delete mode 100644 selftest/knownfail.d/samba.unittests.adouble
diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble
deleted file mode 100644
index 8b0314f2fae..00000000000
--- a/selftest/knownfail.d/samba.unittests.adouble
+++ /dev/null
@@ -1,3 +0,0 @@
-^samba.unittests.adouble.parse_abouble_finderinfo2\(none\)
-^samba.unittests.adouble.parse_abouble_finderinfo3\(none\)
-^samba.unittests.adouble.parse_abouble_date2\(none\)
diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index 6cbe8a5aeda..37fb686f17b 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -269,6 +269,95 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off)
return ad->ad_eid[eid].ade_off = off;
}
+/*
+ * All entries besides FinderInfo and resource fork must fit into the
+ * buffer. FinderInfo is special as it may be larger then the default 32 bytes
+ * if it contains marshalled xattrs, which we will fixup that in
+ * ad_convert(). The first 32 bytes however must also be part of the buffer.
+ *
+ * The resource fork is never accessed directly by the ad_data buf.
+ */
+static bool ad_entry_check_size(uint32_t eid,
+ size_t bufsize,
+ uint32_t off,
+ uint32_t got_len)
+{
+ struct {
+ off_t expected_len;
+ bool fixed_size;
+ bool minimum_size;
+ } ad_checks[] = {
+ [ADEID_DFORK] = {-1, false, false}, /* not applicable */
+ [ADEID_RFORK] = {-1, false, false}, /* no limit */
+ [ADEID_NAME] = {ADEDLEN_NAME, false, false},
+ [ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false},
+ [ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false},
+ [ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false},
+ [ADEID_FILEI] = {ADEDLEN_FILEI, true, false},
+ [ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false},
+ [ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true},
+ [ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false},
+ [ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false},
+ [ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false},
+ [ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false},
+ [ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false},
+ [ADEID_DID] = {ADEDLEN_DID, true, false},
+ [ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false},
+ [ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false},
+ [ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false},
+ [ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false},
+ };
+
+ if (eid >= ADEID_MAX) {
+ return false;
+ }
+ if (got_len == 0) {
+ /* Entry present, but empty, allow */
+ return true;
+ }
+ if (ad_checks[eid].expected_len == 0) {
+ /*
+ * Shouldn't happen: implicitly initialized to zero because
+ * explicit initializer missing.
+ */
+ return false;
+ }
+ if (ad_checks[eid].expected_len == -1) {
+ /* Unused or no limit */
+ return true;
+ }
+ if (ad_checks[eid].fixed_size) {
+ if (ad_checks[eid].expected_len != got_len) {
+ /* Wrong size fo fixed size entry. */
+ return false;
+ }
+ } else {
+ if (ad_checks[eid].minimum_size) {
+ if (got_len < ad_checks[eid].expected_len) {
+ /*
+ * Too small for variable sized entry with
+ * minimum size.
+ */
+ return false;
+ }
+ } else {
+ if (got_len > ad_checks[eid].expected_len) {
+ /* Too big for variable sized entry. */
+ return false;
+ }
+ }
+ }
+ if (off + got_len < off) {
+ /* wrap around */
+ return false;
+ }
+ if (off + got_len > bufsize) {
+ /* overflow */
+ return false;
+ }
+ return true;
+}
+
/**
* Return a pointer to an AppleDouble entry
*
@@ -276,8 +365,15 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off)
**/
char *ad_get_entry(const struct adouble *ad, int eid)
{
+ size_t bufsize = talloc_get_size(ad->ad_data);
off_t off = ad_getentryoff(ad, eid);
size_t len = ad_getentrylen(ad, eid);
+ bool valid;
+
+ valid = ad_entry_check_size(eid, bufsize, off, len);
+ if (!valid) {
+ return NULL;
+ }
if (off == 0 || len == 0) {
return NULL;
@@ -914,20 +1010,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
return false;
}
- /*
- * All entries besides FinderInfo and resource fork
- * must fit into the buffer. FinderInfo is special as
- * it may be larger then the default 32 bytes (if it
- * contains marshalled xattrs), but we will fixup that
- * in ad_convert(). And the resource fork is never
- * accessed directly by the ad_data buf (also see
- * comment above) anyway.
- */
- if ((eid != ADEID_RFORK) &&
- (eid != ADEID_FINDERI) &&
- ((off + len) > bufsize)) {
- DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n",
- eid, off, len));
+ ok = ad_entry_check_size(eid, bufsize, off, len);
+ if (!ok) {
+ DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] "
+ "off [%"PRIu32"] len [%"PRIu32"]\n",
+ eid, bufsize, off, len);
return false;
}
--
2.25.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/little-little-bird/samba.git
git@gitee.com:little-little-bird/samba.git
little-little-bird
samba
samba
master

搜索帮助