Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition in multi-threaded use of archive_write_disk_header() on posix based systems #1876

Open
xypiie opened this issue May 24, 2023 · 9 comments

Comments

@xypiie
Copy link

xypiie commented May 24, 2023

Summary

the umask() call inside archive_write_disk_posix.c changes the umask of the whole process for a very short period of time and race condition with other thread can lead to permanent umask 0 setting:
_archive_write_disk_header(): umask(a->user_umask = umask(0));

process has umask of 027
thread1 enters _archive_write_disk_header()
thread1: prev_umask = umask(0) -> returns 027
thread1: whole process has now umask of 0
thread2 enters _archive_write_disk_header()
thread2: prev_umask = umask(0) -> returns 0
thread1: umask(prev_umask) sets to 027
thread2: umask (prev_umask) sets to 0
whole process remains at umask of 0

Effects (vulnerability)

Such race condition could lead to implicit directory creation with permissions 777 without sticky bit, which means any low privileged user on this system can delete and rename files inside those directories.
This is a serious vulnerability on a multi-user system and admins might not even be aware of it. They probably need to scan their full rootfs for such directories to mitigate.

Proposals

Short term: Adding info to README

Adding information to README to make users aware to mutex this call:
#1875

Potential solution for Linux (>= 4.7)

since linux kernel 4.7 rc1, the umask can be read from /proc fs without modifying it
see: torvalds/linux@3e42979

Example:
getumask.c

@xypiie
Copy link
Author

xypiie commented May 30, 2023

CVE-2023-30571 has been assigned to this

@ljavorsk
Copy link
Contributor

Hi, is there any update on the issue?

@ljavorsk
Copy link
Contributor

ljavorsk commented Jul 4, 2023

@xypiie Could you please share more detail about your example? What it does do, what is expected behavior and what is current (faulty) behavior?
Thank you so much

@kientzle
Copy link
Contributor

kientzle commented Jul 4, 2023

This issue arises if you are using multiple threads, each using libarchive to restore archive entries to disk. Note that libarchive has never officially supported this mode of use, primarily because libarchive relies on C library services that are not safe for multi-threaded use. Also note that umask() is not the only non-thread-safe function that libarchive relies on; fixing this issue would not be sufficient to support using libarchive from multiple threads simultaneously.

@theta682
Copy link
Contributor

theta682 commented Jul 4, 2023

This issue arises if you are using multiple threads, each using libarchive to restore archive entries to disk. Note that libarchive has never officially supported this mode of use, primarily because libarchive relies on C library services that are not safe for multi-threaded use. Also note that umask() is not the only non-thread-safe function that libarchive relies on; fixing this issue would not be sufficient to support using libarchive from multiple threads simultaneously.

#1875 proposes to make a statement in the README file. I agree that it must be documented properly.

@xypiie
Copy link
Author

xypiie commented Jul 4, 2023

This issue arises if you are using multiple threads, each using libarchive to restore archive entries to disk. Note that libarchive has never officially supported this mode of use, primarily because libarchive relies on C library services that are not safe for multi-threaded use. Also note that umask() is not the only non-thread-safe function that libarchive relies on; fixing this issue would not be sufficient to support using libarchive from multiple threads simultaneously.

In the README, it's stated: "The library is generally thread safe depending on the platform..." and adds some limits / constraints to it, like mentioning the usage of chdir(), which could cause problems.
From my point of view it's important to add information about the usage of the umask() calls as well, as this could even cause security issues. That's why I raised #1875 and from my point of view, merging it would close the case as then the users are informed and can take care about mutexing this call on their own. Further possibility and efforts to provide a fix inside libarchive code it is up to libarchive team to decide.

@kientzle
Copy link
Contributor

kientzle commented Jul 9, 2023

Yeah, we should certainly clarify the documentation:

  • The archive_read and archive_write core APIs are in fact generally thread safe, depending on how you implement the callbacks.
  • The archive_read_disk and archive_write_disk APIs are not generally thread safe. Writing a thread-safe version of these APIs would be an interesting project, if anyone wanted to take on that challenge. (Hint: openat() and related *at() APIs are probably essential components for implementing this on POSIX.)

halstead pushed a commit to yoctoproject/poky that referenced this issue Jul 30, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: 9b5b850d6a6982bb8ff14dcfbb6769b293638293)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
halstead pushed a commit to openembedded/openembedded-core that referenced this issue Jul 30, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
halstead pushed a commit to openembedded/openembedded-core that referenced this issue Aug 7, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
halstead pushed a commit to yoctoproject/poky that referenced this issue Aug 7, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: d5e7971e12cdc8748be91b4e6408b42fa86b2f15)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
jpuhlman pushed a commit to MontaVista-OpenSourceTechnology/poky that referenced this issue Aug 9, 2023
Source: poky
MR: 126575, 127628
Type: Security Fix
Disposition: Merged from poky
ChangeID: cd329fc
Description:

This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: d5e7971e12cdc8748be91b4e6408b42fa86b2f15)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
Signed-off-by: Jeremy A. Puhlman <[email protected]>
halstead pushed a commit to openembedded/openembedded-core that referenced this issue Aug 15, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
halstead pushed a commit to yoctoproject/poky that referenced this issue Aug 15, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: ffa8f92aa6f8405d8fea117af2f212ba190de393)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
halstead pushed a commit to openembedded/openembedded-core that referenced this issue Aug 16, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
halstead pushed a commit to yoctoproject/poky that referenced this issue Aug 16, 2023
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: 9374e680ae2376589a9bfe4565dfcf4dc9791aa8)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
jpuhlman pushed a commit to MontaVista-OpenSourceTechnology/poky that referenced this issue Aug 23, 2023
Source: poky
MR: 127621, 126578
Type: Security Fix
Disposition: Merged from poky
ChangeID: 0de5f6a27a794c915a2ef2483901ab915056d961
Description:

This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: 9374e680ae2376589a9bfe4565dfcf4dc9791aa8)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Steve Sakoman <[email protected]>
Signed-off-by: Jeremy A. Puhlman <[email protected]>
@arabesc
Copy link

arabesc commented Feb 5, 2024

This issue arises if you are using multiple threads, each using libarchive to restore archive entries to disk.

The issue does not require the use of libarchive from multiple threads. The problem is not in the libarchive itself, but in the thread-unsafe use of the system function umask that changes process global state. So, any code that uses umask from multiple threads without synchronization is unsafe, including the libarchive *disk* functions.

The archive_read_disk and archive_write_disk APIs are not generally thread safe.

It would be good to add in the README that the archive_*_disk_*() functions are API specific and that other APIs such as archive_write_new are safe. This will save time on investigating what it's all for and where it's used.

@arabesc
Copy link

arabesc commented Feb 5, 2024

I think a better solution than mutexing umask calls would be to ask a client to provide the mask value via a callback. There will be no umask calls in libarchive, no calls - no problem.

daregit pushed a commit to daregit/yocto-combined that referenced this issue May 22, 2024
This issue was reported and discusses under [1] which is linked in NVD CVE report.
It was already documented that some parts or libarchive are thread safe and some not.
[2] was now merged to document that also reported function is not thread safe.
So this CVE *now* reports thread race condition for non-thread-safe function.
And as such the CVE report is now invalid.

The issue is still not closed for 2 reasons:
* better document what is and what is not thread safe
* request to public if someone could make these functions thread safe
This should however not invalidate above statment about ignoring this CVE.

[1] libarchive/libarchive#1876
[2] libarchive/libarchive#1875

(From OE-Core rev: 9b5b850d6a6982bb8ff14dcfbb6769b293638293)

Signed-off-by: Peter Marko <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants