Bug 2036277
| Summary: | autofs accesses memory outside of allocation | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Frank Sorenson <fsorenso> | ||||
| Component: | autofs | Assignee: | Ian Kent <ikent> | ||||
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Kun Wang <kunwan> | ||||
| Severity: | unspecified | Docs Contact: | |||||
| Priority: | unspecified | ||||||
| Version: | 8.4 | CC: | xzhou | ||||
| Target Milestone: | rc | Keywords: | Regression, Triaged | ||||
| Target Release: | --- | Flags: | pm-rhel:
mirror+
|
||||
| Hardware: | Unspecified | ||||||
| OS: | Unspecified | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | autofs-5.1.4-82.el8 | Doc Type: | If docs needed, set a value | ||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2022-02-18 04:03:42 UTC | Type: | Bug | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Attachments: |
|
||||||
The loop in cache_get_offset_parent() looks like this:
update_offset_entry: parse(sun): updated multi-mount offset /exports -> -nosuid 127.0.0.1:/exports
cache_get_offset_parent called with key: '/net/127.0.0.1/exports' (22 bytes)
while(*tail) parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a5 (s)
top of loop parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a5 (s)
while (*tail != '/') {
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a4 (ts)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a3 (rts)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a2 (orts)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a1 (ports)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf95a0 (xports)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf959f (exports)
tail--; parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf959e (/exports)
} parent: 0xaaf9590 (/net/127.0.0.1/exports); tail: 0xaaf959e (/exports)
*tail = 0; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959e ()
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959d (1)
if (tail == parent) break *FALSE* parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959d (1)
cache_lookup_distinct("/net/127.0.0.1") returns (nil)
} parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959d (1)
while(*tail) parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959d (1)
top of loop parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959d (1)
while (*tail != '/') {
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959c (.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959b (0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf959a (.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9599 (0.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9598 (.0.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9597 (7.0.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9596 (27.0.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9595 (127.0.0.1)
tail--; parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9594 (/127.0.0.1)
} parent: 0xaaf9590 (/net/127.0.0.1); tail: 0xaaf9594 (/127.0.0.1)
*tail = 0; parent: 0xaaf9590 (/net); tail: 0xaaf9594 ()
tail--; parent: 0xaaf9590 (/net); tail: 0xaaf9593 (t)
if (tail == parent) break *FALSE* parent: 0xaaf9590 (/net); tail: 0xaaf9593 (t)
cache_lookup_distinct("/net") returns (nil)
} parent: 0xaaf9590 (/net); tail: 0xaaf9593 (t)
while(*tail) parent: 0xaaf9590 (/net); tail: 0xaaf9593 (t)
top of loop parent: 0xaaf9590 (/net); tail: 0xaaf9593 (t)
while (*tail != '/') {
tail--; parent: 0xaaf9590 (/net); tail: 0xaaf9592 (et)
tail--; parent: 0xaaf9590 (/net); tail: 0xaaf9591 (net)
tail--; parent: 0xaaf9590 (/net); tail: 0xaaf9590 (/net)
} parent: 0xaaf9590 (/net); tail: 0xaaf9590 (/net)
*tail = 0; parent: 0xaaf9590 (); tail: 0xaaf9590 ()
tail--; parent: 0xaaf9590 (); tail: 0xaaf958f (ÿ)
if (tail == parent) break *FALSE* parent: 0xaaf9590 (); tail: 0xaaf958f (ÿ)
cache_lookup_distinct("") returns (nil)
} parent: 0xaaf9590 (); tail: 0xaaf958f (ÿ)
while(*tail) parent: 0xaaf9590 (); tail: 0xaaf958f (ÿ)
BOOM!
Created attachment 1848358 [details]
patch
|
Description of problem: When searching the cache, autofs reads into memory just prior to allocated memory. cache_get_offset_parent() duplicates the key, then crawls backward from the end of the allocated string, searching for the string in the cache, but walks off the beginning of the allocated string. Version-Release number of selected component (if applicable): autofs-5.1.4-77.el8.x86_64 How reproducible: easy Steps to Reproduce: # mkdir -p /exports # exportfs '*:/exports' /etc/auto.master: /net -hosts --nosuid # valgrind --trace-children=yes /usr/sbin/automount -f --dont-check-daemon 2>&1 | tee /var/tmp/valgrind.out # ls -al /net/127.0.0.1 Actual results: ==812777== Invalid read of size 1 ==812777== at 0x12C538: cache_get_offset_parent (cache.c:676) ==812777== by 0x130452: tree_mapent_add_node (mounts.c:1587) ==812777== by 0xA24B35F: parse_mount (parse_sun.c:1548) ==812777== by 0xB0BC35D: do_parse_mount (lookup_hosts.c:188) ==812777== by 0xB0BC35D: lookup_mount (lookup_hosts.c:425) ==812777== by 0x127E90: do_lookup_mount (lookup.c:831) ==812777== by 0x128BA0: lookup_nss_mount (lookup.c:1216) ==812777== by 0x118DF4: do_mount_indirect (indirect.c:750) ==812777== by 0x4E4A2DD: start_thread (pthread_create.c:486) ==812777== by 0x6823132: clone (clone.S:95) ==812777== Address 0x959b9ef is 1 bytes before a block of size 23 alloc'd ==812777== at 0x4C32135: malloc (vg_replace_malloc.c:381) ==812777== by 0x67B04AD: strdup (strdup.c:42) ==812777== by 0x12C52E: cache_get_offset_parent (cache.c:673) ==812777== by 0x130452: tree_mapent_add_node (mounts.c:1587) ==812777== by 0xA24B35F: parse_mount (parse_sun.c:1548) ==812777== by 0xB0BC35D: do_parse_mount (lookup_hosts.c:188) ==812777== by 0xB0BC35D: lookup_mount (lookup_hosts.c:425) ==812777== by 0x127E90: do_lookup_mount (lookup.c:831) ==812777== by 0x128BA0: lookup_nss_mount (lookup.c:1216) ==812777== by 0x118DF4: do_mount_indirect (indirect.c:750) ==812777== by 0x4E4A2DD: start_thread (pthread_create.c:486) ==812777== by 0x6823132: clone (clone.S:95) Expected results: no attempts to access memory outside allocations Additional info: the condition in this loop reads the value at tail, which may not be a valid address: 675 676 while (*tail) { 677 while (*tail != '/') 678 tail--; 679 680 *tail = 0;