Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

paste(1): capsicumise the utility #1443

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
Loading
from
Open

paste(1): capsicumise the utility #1443

wants to merge 6 commits into from

Conversation

kfv
Copy link
Contributor

@kfv kfv commented Sep 30, 2024

This PR applies Capsicum security enhancements to the paste utility as part of my initial contribution with Capsicumisation. The user experience and POSIX compliance have been preserved, with adjustments made to improve the code’s structure and error handling.

My goal is to gain a deeper understanding of Capsicum by starting with simpler utilities before progressing to more complex codebases and libraries, so any corrections, suggestions, or feedback on the approach are highly appreciated, as I am eager to refine my work and contribute more broadly to the project.

usr.bin/paste/paste.c Show resolved Hide resolved
usr.bin/paste/paste.c Show resolved Hide resolved
@bsdimp bsdimp added the changes-required Cannot land as is, change requested of submitter label Oct 4, 2024
@kfv kfv marked this pull request as draft October 5, 2024 11:32
@kfv kfv marked this pull request as ready for review October 8, 2024 22:24
@kfv kfv requested a review from bsdjhb October 8, 2024 22:25
@kfv
Copy link
Contributor Author

kfv commented Nov 1, 2024

Cc: @oshogbo

Copy link
Member

@markjdb markjdb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mostly looks ok to me, just some nitpicking.

I'm a bit wary about pre-opening all of the files at once. In general that's a bad idea since it might cause the utility to open more file descriptors than is allowed (small RLIMIT_NOFILE limits are not uncommon), but for paste that's probably ok...

I would also drop the sysexits change, as we generally don't add new uses of them.

usr.bin/paste/paste.c Outdated Show resolved Hide resolved

cap_rights_init(&rights, CAP_READ);
STAILQ_FOREACH(lp, &lh, entries) {
if (lp->fp && cap_rights_limit(fileno(lp->fp), &rights) < 0 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest calling cap_rights_limit() right after each fopen() call, rather than having a separate loop. It's easier to reason about that way (open+rights limiting happens in one go), and it's simpler.

Also, I don't think you need the lp->fp null check.

Also, I believe you can use caph_rights_limit() and avoid the ENOSYS check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest calling cap_rights_limit() right after each fopen() call, rather than having a separate loop. It's easier to reason about that way (open+rights limiting happens in one go), and it's simpler.

You're absolutely right, it's totally valid. Done.

Also, I don't think you need the lp->fp null check.

True.

Also, I believe you can use caph_rights_limit() and avoid the ENOSYS check.

True, but since it's concise enough for this small use case, I kept it as is. Let me know if you think it needs to be changed.

@oshogbo oshogbo self-assigned this Dec 2, 2024
kfv added 4 commits December 9, 2024 22:05
…d linked-list

Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
@kfv
Copy link
Contributor Author

kfv commented Dec 9, 2024

I would also drop the sysexits change, as we generally don't add new uses of them.

@markjdb: The termination status macros are from the standard C library (defined in <stdlib.h> as per C23 7.24p4 or the older C99 7.20p3,) not from <sysexit.h>.

@markjdb
Copy link
Member

markjdb commented Dec 9, 2024

I would also drop the sysexits change, as we generally don't add new uses of them.

@markjdb: The termination status macros are from the standard C library (defined in <stdlib.h> as per C23 7.24p4 or the older C99 7.20p3,) not from <sysexit.h>.

Yes, apologies - I forgot about this distinction when reading several PRs back-to-back. Please ignore my comments relating to sysexits.

Signed-off-by: Faraz Vahedi <kfv@kfv.io>
@kfv
Copy link
Contributor Author

kfv commented Dec 9, 2024

No worries, mate. Thanks!

rval = sequential(argv);
else
rval = parallel(argv);
for (filecnt = 0; *argv; ++argv, ++filecnt) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered using fileargs?
man.freebsd.org/cgi/man.cgi?query=cap_fileargs&sektion=3&manpath=freebsd+14.1-release+and+ports
Opening files up front has some advantages, it's faster.
I wonder why you decided to open files upfront and not use fileargs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely! I didn't know that, Mariusz. Thanks a lot, I'll take care of it.

STAILQ_INSERT_TAIL(&lh, lp, entries);
}

if (cap_enter() < 0 && errno != ENOSYS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use caph_enter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to use the raw Capsicum API instead of caph because it felt more concise and appropriate for the small-scale use cases in such a utility. Additionally, I thought having another direct example of capsicumisation with only raw API calls might be beneficial as a reference, considering further complexities observed here. While it does add some verbosity to the code, I don't see it causing any other significant issues. That said, if you still believe using Capsicum helpers would be better for this context, I’m happy to reconsider and follow your guidance.

failed = errno;
}

if (cap_rights_limit(fileno(lp->fp),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe caph_rights_limit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, but for the same reasons mentioned earlier, I felt it might be better to stick with the raw API. I’ve reviewed the helpers you’ve written, and they’re indeed excellent—adding no overhead or unnecessary abstraction. However, I thought it might still be worthwhile to use the raw API directly here. If you believe otherwise, I’m happy to adapt based on your recommendation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to use a raw API, capsicum helpers make it simpler.
Ideally when we make capsicum mandatory in FreeBSD it will also make code cleanup much simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. OK, I can take care of it as well, rog.


for (opencnt = cnt; opencnt;) {
for (output = 0, lp = head; lp; lp = lp->next) {
for (opencnt = filecnt; opencnt;) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In opencnt can we do a logical expression?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean using opencnt > 0? That’s certainly a valid approach and it’s a good idea if you want to make the code more self-explanatory. It avoids relying on implicit truthiness, which can sometimes be less clear. Personally, I prefer to keep the code brief and concise where possible, which is why I didn’t use that form. However, if you think it would be helpful for clarity, I’d be open to considering the change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I prefer to have a boolean expression in conditions it makes it easier to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger that, I'll take care of it.

usr.bin/paste/paste.c Show resolved Hide resolved
Copy link

github-actions bot commented Jun 3, 2025

Thank you for taking the time to contribute to FreeBSD!
There is an issue that needs to be fixed:

  • Missing Signed-off-by lines5ecc60f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changes-required Cannot land as is, change requested of submitter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.