From nobody Mon Sep 28 08:07:25 2026 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D60B453A3B for ; Mon, 24 Aug 2026 15:43:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787586227; cv=none; b=sGYI4FuqzMpYU7hJ3BQBcE/RaMKebwjMGpHYuVUNc3KNE0HmDTLmBy7rnpAOw5f+DLSHt7cWJ8wJx9nnLiTQcLoy4WUxxfDqrFOUlIutOE7KT+QaxFItwkIImWZ+6sTRRSXhGLjGkXzlpWkkQvNvXdoNKL/0W59J7t/MJKZcQ/0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787586227; c=relaxed/simple; bh=Mm82Cm+9fidaHZqiCV7dmTYVZ4KocuKX5WP0HtEMwBo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=HoJov2ZJQsRbAkBrvQuZWoS5menF1h7BWHM7FCFWnbx0m9ztC1/YgVSO4h9eFnuGnxsjzQ6Wvw7uL8o5oBFxMXTGQZb7mzO/xtWgrzw7v6yMkn+P//lwbxIgvkgim6lc/4USUlXU3H77b6K1IwUFWzEbtyUZ1p/L/qdHfuA5t54= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr; spf=pass smtp.mailfrom=snu.ac.kr; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b=VaCTccZM; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b="VaCTccZM" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-84eb992a881so2655753b3a.2 for ; Mon, 24 Aug 2026 08:43:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=snu.ac.kr; s=google; t=1787586220; x=1788191020; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=V46JzfDzhl+D94yGdlzJmpD/3wlHVTDt9SXujyPiV/Q=; b=VaCTccZMyXOg1tSRuwfiSYAwNun/3/JvZ1uNqizWTJx9whohDjSwCb1t/aITRKP3L9 JgTygVE0EAMwLGOv/LGBTgd4+bCfpWCODmdG8W3UDaR0NFVgNgfG4X/SymQzhSMbXwk8 lCCHaByMLrfjO8b/ZVRGh7COWvlxya05syPIQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787586220; x=1788191020; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=V46JzfDzhl+D94yGdlzJmpD/3wlHVTDt9SXujyPiV/Q=; b=Ruf8bJcX7ldKbBQhtSXqwtk+ss24Clr3ZWD5jGmfC7oVomkOtsPwjhxr1p/8+31y81 OfEOG0EnPVvisqImvqzA0Cj0IpAquKQBxBAwr6B6y1x7/BCZstsW64dawEttTIEckJDI M79nh5sM5RpKBgHzO3j3K34r5COy9pqLClO6CMvEV4bWY7CqonWs/KOfEg8E8KWczqBq fNsGogSYeylaZngTbAT0HesSLNnemLZpvId/3rI+iJ5hEIo3y63vKNmOzWR/7CPesRqj O3g3eVx1DC9rLHDPkvYnijNq0830SLG+PYutbfdTjjLJRhRTL/m97rDbvhRc98Rvvczr 0akQ== X-Forwarded-Encrypted: i=1; AHgh+RotXhdh8DFKpG5S0dAwFNO5omkSUYdFizsKulGENzPy6zHB8PwYwSLKVJwJB8TUFHQgVSgSkkLIdLP5sTo=@vger.kernel.org X-Gm-Message-State: AFuF++l7vEPQqYS36kv41Xioi9ThcQOmVCTzpkBvUY5uGzKfjDBUIMzv im3z2RId0mUrlvw4H7LoZdiylD4yjsSV/Kj1tHOKOgN4KrjJfhy1Uc9HJJhCaAwgdM4= X-Gm-Gg: AR+sD13hd0HeGpXieRoIjVVnFGJKI5PUbLS67oB5Xxl+UaS/H5KsW2Iw33j6mFGsg5e cjnxmNVNGwm925BXtQsRyv12LEYPLD456qSBIaxYoTdcMBCFHkppQNVBBkfKscDcrgfybkWlSKV OR/YytjWWh36CN9uzETFCknYdHhLC7CwgdzKreKTCT8ifYrOg88rbjWDw2nn/51HCObeDka0wsQ to0dPIRYf4Gc/kw7M4YK9v4O5lqqQTe+oniElkZHJze2RPa2cUAUyQ6pMDdlk3MfkaI7BOoCgvK 319FeyCq/gDyzTQDn5c6CpeJ49KpK5Li6PYS43behOzDgkjFDdQfjXjRRPxkvI2dBnwr6nLZzN4 n/YFIgJ+V1R61vO6Val2lJuYr/5O3F/qzg3d6nRkaxbqUnu6mFHr8p3hjyaZLNEv7l85CgCIa5J nXa6GF5mrxWzTDv6s18PSE1FW1yp7Yx6OXcfqTx8j/Cv5t0hxDIi5xVeJqEU4FgGPDspoGKJ1Hk DEe8dehij9Tf54MakFt5LRDLkKQ/9PPVY5GCwnBXnxiMdDUJwkTXhaKY8MyH0s3klQptI6Caj1G N5xNk/QOeqnJ0GxPhOVl+7tuL58BzfIX4rSKSOHlGSVWHvdje69bpA== X-Received: by 2002:a05:6a00:1821:b0:84e:4d6:78fe with SMTP id d2e1a72fcca58-851f972a7f7mr44618198b3a.3.1787586219812; Mon, 24 Aug 2026 08:43:39 -0700 (PDT) Received: from leesin ([147.46.121.37]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8520f14abb3sm2137739b3a.45.2026.08.24.08.43.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2026 08:43:39 -0700 (PDT) From: Jaeyoung Chung To: dwmw2@infradead.org, linux-mtd@lists.infradead.org, richard@nod.at Cc: kees@kernel.org, linux-kernel@vger.kernel.org, eulgyukim@snu.ac.kr, jjy600901@snu.ac.kr Subject: [BUG] kernel BUG in jffs2_sum_write_sumnode Date: Tue, 25 Aug 2026 00:43:33 +0900 Message-ID: <20260824154335.2340665-1-jjy600901@snu.ac.kr> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hello, We found a "kernel BUG in jffs2_sum_write_sumnode" on Linux v7.2. The issue was found by our own race fuzzer. We have not analyzed the root c= ause, so we do not have a proposed fix to offer. To reproduce the race reliably, we applied the delay patch below to the kernel and ran the C reproducer as root inside an x86_64 QEMU guest. The crash log we observed, the delay patch and the reproducer are all included below. The following kernel config options are required to reproduce the issue: CONFIG_JFFS2_FS=3Dy CONFIG_JFFS2_SUMMARY=3Dy CONFIG_MTD=3Dy CONFIG_MTD_MTDRAM=3Dy CONFIG_MTD_BLOCK=3Dy CONFIG_MTDRAM_TOTAL_SIZE=3D128 CONFIG_MTDRAM_ERASE_SIZE=3D4 CONFIG_KASAN=3Dy We hope this report is useful. Please let us know if any further information would help. Reported-by: Eulgyu Kim Reported-by: Jaeyoung Chung Kernel delay patch: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 1b833bbffcf5..7517c66c86e9 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include "nodelist.h" #include "compr.h" @@ -603,6 +605,9 @@ static int jffs2_garbage_collect_pristine(struct jffs2_= sb_info *c, ref_offset(raw)); =20 alloclen =3D rawlen =3D ref_totlen(c, c->gcblock, raw); + if (c->summary && c->nextblock && !c->summary->sum_num) { + mdelay(10); + } =20 /* Ask for a small amount of space (or the totlen if smaller) because we don't want to force wastage of the end of a block if splitting would diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 3fb9f9807b66..7785bde6b795 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include "nodelist.h" @@ -84,6 +86,10 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_= t minsize, minsize =3D PAD(minsize); =20 jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize); + if (c->summary && c->nextblock && !c->summary->sum_num && + strncmp(current->comm, "syzrepro1", 9) =3D=3D 0) { + mdelay(80); + } mutex_lock(&c->alloc_sem); =20 jffs2_dbg(1, "%s(): alloc sem got\n", __func__); diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 06e494797724..b7ac51a0cc95 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "nodelist.h" #include "summary.h" @@ -207,6 +208,9 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) } /* update collected summary information for the current nextblock */ jffs2_sum_move_collected(c, s); + if (!c->summary->sum_num || !c->summary->sum_list_head) { + mdelay(10); + } jffs2_dbg(1, "%s(): new nextblock =3D 0x%08x\n", __func__, jeb->offset); c->nextblock =3D jeb; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D C reproducer: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #define SYSCHK(x) ({ long __r =3D (long)(x); if (__r =3D=3D -1L) { perror(#= x); exit(1); } __r; }) #define SECT 4096u #define NBLK 32u #define FLASH (SECT * NBLK) #define GATE_FREE 160u #define OTHER_FREE 128u #define MNTPOINT "/syzrepro_mnt" #define MTDBLK "/dev/mtdblock0" static volatile int g_mounted, g_stop; static unsigned g_wseq; static unsigned int crc_tab[256]; static void crc_init(void) { unsigned int i, k, c; for (i =3D 0; i < 256; i++) { for (c =3D i, k =3D 0; k < 8; k++) c =3D (c & 1) ? ((c >> 1) ^ 0xEDB88320u) : (c >> 1); crc_tab[i] =3D c; } } static unsigned int jcrc32(unsigned int crc, const void *p, size_t n) { const unsigned char *b =3D p; while (n--) crc =3D crc_tab[(crc ^ *b++) & 0xff] ^ (crc >> 8); return crc; } static int img_read(unsigned char *img) { int fd =3D open(MTDBLK, O_RDONLY); ssize_t r; if (fd < 0) return -1; ioctl(fd, BLKFLSBUF, 0); r =3D pread(fd, img, FLASH, 0); close(fd); return r =3D=3D (ssize_t)FLASH ? 0 : -1; } static int img_write(const unsigned char *img) { int fd =3D open(MTDBLK, O_RDWR); ssize_t w; if (fd < 0) return -1; w =3D pwrite(fd, img, FLASH, 0); fsync(fd); ioctl(fd, BLKFLSBUF, 0); close(fd); sync(); return w =3D=3D (ssize_t)FLASH ? 0 : -1; } static int build_fs(unsigned char *img, unsigned char *data) { char name[256], path[600]; unsigned i; int made =3D 0; memset(img, 0xff, FLASH); if (img_write(img) || mount("mtd0", MNTPOINT, "jffs2", 0, NULL)) return -1; for (i =3D 0; i < 48; i++) { int fd; ssize_t w; memset(name, 'a' + (i % 26), 200); name[200] =3D 0; snprintf(path, sizeof(path), MNTPOINT "/%s%02u", name, i); fd =3D open(path, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd < 0) break; w =3D write(fd, data, 4096); if (w =3D=3D 4096) w =3D write(fd, data + 4096, 4096); fsync(fd); close(fd); if (w !=3D 4096) break; made++; } sync(); umount2(MNTPOINT, MNT_DETACH); return made > 0 ? 0 : -1; } /* * Wipe one eraseblock down to a single length-12 node so that, once mounte= d, * jffs2_sum_write_sumnode() is entered with nothing to write. */ static int scribble(unsigned char *img) { unsigned b, k, tail[NBLK], junk =3D NBLK, best =3D 0, bestt =3D 0; unsigned char *p; unsigned int hdr; for (b =3D 0; b < NBLK; b++) { for (k =3D 0; k < SECT && img[b * SECT + SECT - 1 - k] =3D=3D 0xff; k++) ; tail[b] =3D k; if (k > bestt) { bestt =3D k; best =3D b; } if (k >=3D SECT - 16 && junk =3D=3D NBLK) junk =3D b; } if (junk =3D=3D NBLK) junk =3D best; for (b =3D 0; b < NBLK; b++) if (b !=3D junk && tail[b] > OTHER_FREE) memset(img + b * SECT + SECT - tail[b], 0, tail[b] - OTHER_FREE); p =3D img + junk * SECT; memset(p, 0, SECT); p[0] =3D 0x85; p[1] =3D 0x19; p[2] =3D 0x03; p[3] =3D 0x20; p[4] =3D 12; hdr =3D jcrc32(0, p, 8); p[8] =3D hdr; p[9] =3D hdr >> 8; p[10] =3D hdr >> 16; p[11] =3D hdr >> 24; memset(p + SECT - GATE_FREE, 0xff, GATE_FREE); return img_write(img) ? -1 : (int)junk; } static void *writer(void *arg) { int idx =3D (int)(long)arg; unsigned char *buf =3D malloc(8192); char nm[16], path[128]; snprintf(nm, sizeof(nm), "syzrepro%d", idx); prctl(PR_SET_NAME, nm, 0, 0, 0); memset(buf, 0x5a, 8192); while (!g_stop) { int fd; if (!g_mounted) { usleep(2000); continue; } snprintf(path, sizeof(path), MNTPOINT "/w%d_%u", idx, (g_wseq++) & 31u); fd =3D open(path, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd < 0) { usleep(3000); continue; } write(fd, buf, 4096); write(fd, buf, 4096); fsync(fd); close(fd); usleep(1000); } free(buf); return NULL; } int main(void) { unsigned char *img =3D malloc(FLASH), *data =3D malloc(8192); pthread_t th; int i, it; prctl(PR_SET_NAME, "syzrepro0", 0, 0, 0); crc_init(); for (i =3D 0; i < 8192; i++) data[i] =3D (i >> 4) & 0x0f; mkdir(MNTPOINT, 0755); mknod(MTDBLK, S_IFBLK | 0600, makedev(31, 0)); umount2(MNTPOINT, MNT_DETACH); pthread_create(&th, NULL, writer, (void *)1L); for (it =3D 0; it < 25 && !g_stop; it++) { g_mounted =3D 0; umount2(MNTPOINT, MNT_DETACH); usleep(50000); if (build_fs(img, data) || img_read(img) || scribble(img) < 0 || mount("mtd0", MNTPOINT, "jffs2", 0, NULL)) { usleep(200000); continue; } usleep(1200000); g_mounted =3D 1; usleep(1200000); g_mounted =3D 0; usleep(50000); umount2(MNTPOINT, MNT_DETACH); usleep(50000); } g_stop =3D 1; pthread_join(th, NULL); umount2(MNTPOINT, MNT_DETACH); return 0; } =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Crash log: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D kernel BUG at fs/jffs2/summary.c:868! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 2 UID: 0 PID: 404 Comm: syzrepro1 Not tainted 7.2.0-dirty #3 PREEMPT=20 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1= .1 04/01/2014 RIP: 0010:jffs2_sum_write_sumnode+0x1bb6/0x1bc0 fs/jffs2/summary.c:868 Code: 14 89 d9 80 e1 07 80 c1 03 38 c1 7c 08 48 89 df e8 ef a1 61 ff 8b 33 = 48 c7 c7 e0 c7 31 87 48 c7 c2 fb a0 ff 87 e8 8a 17 94 fe <0f> 0b cc cc cc c= c cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90 RSP: 0018:ffff888109cd74a0 EFLAGS: 00010246 RAX: 0000000000000044 RBX: ffff888106c93a00 RCX: 5e7574cf0ce16600 RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff888109cd7360 RBP: ffff888109cd7588 R08: ffff888109cd7367 R09: 1ffff1102139ae6c R10: dffffc0000000000 R11: ffffed102139ae6d R12: ffff88810357dd84 R13: ffff88810bbc1aa0 R14: dffffc0000000000 R15: ffff88810bbc1990 FS: 000078a3c6f956c0(0000) GS:ffff888190840000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005bafe23d9b20 CR3: 0000000108312000 CR4: 00000000000006f0 Call Trace: jffs2_do_reserve_space+0x1c9/0xe50 fs/jffs2/nodemgmt.c:398 jffs2_reserve_space_gc+0x45/0xb0 fs/jffs2/nodemgmt.c:232 jffs2_garbage_collect_dirent+0x209/0x320 fs/jffs2/gc.c:882 jffs2_garbage_collect_live+0x42a/0x2970 fs/jffs2/gc.c:574 jffs2_garbage_collect_pass+0x141b/0x1af0 fs/jffs2/gc.c:466 jffs2_reserve_space+0x4e5/0xae0 fs/jffs2/nodemgmt.c:177 jffs2_do_create+0x52/0xbe0 fs/jffs2/write.c:454 jffs2_create+0x1b4/0x300 fs/jffs2/dir.c:205 lookup_open fs/namei.c:4508 [inline] open_last_lookups fs/namei.c:4608 [inline] path_openat+0xe3c/0x29b0 fs/namei.c:4860 do_file_open+0x19d/0x360 fs/namei.c:4892 do_sys_openat2+0x9a/0x100 fs/open.c:1368 do_sys_open fs/open.c:1374 [inline] __do_sys_openat fs/open.c:1390 [inline] __se_sys_openat fs/open.c:1385 [inline] __x64_sys_openat+0xf8/0x130 fs/open.c:1385 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf7/0x370 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x78a3c7091090 Code: 48 89 44 24 20 75 93 44 89 54 24 0c e8 a9 d7 f8 ff 44 8b 54 24 0c 89 = da 48 89 ee 41 89 c0 bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff f= f 77 38 44 89 c7 89 44 24 0c e8 fc d7 f8 ff 8b 44 RSP: 002b:000078a3c6f94d80 EFLAGS: 00000293 ORIG_RAX: 0000000000000101 RAX: ffffffffffffffda RBX: 0000000000000241 RCX: 000078a3c7091090 RDX: 0000000000000241 RSI: 000078a3c6f94e20 RDI: 00000000ffffff9c RBP: 000078a3c6f94e20 R08: 0000000000000000 R09: 0000000000000075 R10: 00000000000001a4 R11: 0000000000000293 R12: 000078a3c6f94e20 R13: 0000000000000001 R14: 00007ffe30446b90 R15: 000078a3c6795000 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D