Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 553992 - dev-vcs/git: Use symlinks instead of hardlinks.
Summary: dev-vcs/git: Use symlinks instead of hardlinks.
Status: RESOLVED WONTFIX
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: The Gentoo Linux Hardened Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-05 15:25 UTC by Piotr Karbowski (RETIRED)
Modified: 2015-07-08 00:25 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
ln -> false patch (foo.patch,641 bytes, patch)
2015-07-05 15:25 UTC, Piotr Karbowski (RETIRED)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Karbowski (RETIRED) gentoo-dev 2015-07-05 15:25:37 UTC
Created attachment 406210 [details, diff]
ln -> false patch

Since Grsecurity's RBAC fails hard when subject is a symlink I'd like to request switching from default hardlinks to symlinks with dev-vcs/git.

Git's Makefile have logic that first tries to hardlink, then symlink and if it also fails, copy git binary.

Right now, if RBAC's policy have /usr/bin/git subject and git is updated, git is no longer accessable as RBAC tracks only single path+inode pair, resulting in not 'seeing' git anymore until policy recreation (reload).

I don't think that this change would have any impact on users, since even the Makefile has the logic to symlink binaries, if failed to hardlink.

Patch attached, simple string replace for the `ln` alone to `false`.
Comment 1 Mike Gilbert gentoo-dev 2015-07-05 16:06:55 UTC
Sounds like a limitation of grsecurity, or it is somehow mis-configured.

Why can't that be fixed instead of adding workarounds to any package that uses hard links?
Comment 2 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-05 16:21:30 UTC
Hello,

For reference: https://forums.grsecurity.net/viewtopic.php?p=15181&sid=d387ff32fe0e55f83a3843905f65cc32#p15181

It's indeed limitation of grsecurity but does not seems like it will be addressed at all. Since Gentoo officially supports Grsecurity I thought such workaround would be acceptable.
Comment 3 Mike Gilbert gentoo-dev 2015-07-05 23:59:57 UTC
I guess I'm a bit confused as to what symlinks solve here. Symlinks have to point to a hard link eventually. The only difference is that there is a single hard link instead of dozens.

How is it that grsecurity is able to deal with replacing one hard link but not many?
Comment 4 Anthony Basile gentoo-dev 2015-07-06 01:33:31 UTC
(In reply to Piotr Karbowski from comment #2)
> Hello,
> 
> For reference:
> https://forums.grsecurity.net/viewtopic.
> php?p=15181&sid=d387ff32fe0e55f83a3843905f65cc32#p15181
> 
> It's indeed limitation of grsecurity but does not seems like it will be
> addressed at all. Since Gentoo officially supports Grsecurity I thought such
> workaround would be acceptable.

This is not really not how rbac should be used.  Sorry but I can't recommend this patch for git.
Comment 5 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-06 14:57:41 UTC
(In reply to Anthony Basile from comment #4)
> (In reply to Piotr Karbowski from comment #2)
> > Hello,
> > 
> > For reference:
> > https://forums.grsecurity.net/viewtopic.
> > php?p=15181&sid=d387ff32fe0e55f83a3843905f65cc32#p15181
> > 
> > It's indeed limitation of grsecurity but does not seems like it will be
> > addressed at all. Since Gentoo officially supports Grsecurity I thought such
> > workaround would be acceptable.
> 
> This is not really not how rbac should be used.  Sorry but I can't recommend
> this patch for git.

Not how rbac should be used? Care to elaborate?

The default subject have no access to network, so I create a subject for /usr/bin/git with the network access, however after any git upgrade (namely, merge from portage temp to rootfs) because of the hardlink magic rbac no longer sees /usr/bin/git at all, until policy recreation done by reloading.

With symlink that is resolved in VFS it will work.
Comment 6 Mike Gilbert gentoo-dev 2015-07-06 15:45:44 UTC
If I understand this correctly, any binary that has an RBAC policy applied to it could be affected by this behavior -- it would occur any time the inode for an existing file changes. it's not an issue that affects only git.

Perhaps a more appropriate solution would be some post-merge hook to reload the RBAC policy. This would really be a package manager (portage) feature, and not something to be implemented in individual ebuilds.
Comment 7 Anthony Basile gentoo-dev 2015-07-06 22:13:37 UTC
(In reply to Piotr Karbowski from comment #5)
> (In reply to Anthony Basile from comment #4)
> > (In reply to Piotr Karbowski from comment #2)
> > > Hello,
> > > 
> > > For reference:
> > > https://forums.grsecurity.net/viewtopic.
> > > php?p=15181&sid=d387ff32fe0e55f83a3843905f65cc32#p15181
> > > 
> > > It's indeed limitation of grsecurity but does not seems like it will be
> > > addressed at all. Since Gentoo officially supports Grsecurity I thought such
> > > workaround would be acceptable.
> > 
> > This is not really not how rbac should be used.  Sorry but I can't recommend
> > this patch for git.
> 
> Not how rbac should be used? Care to elaborate?

you use rbac on a mostly static system like a server that just does one thing.  you run rbac learning for about a week, distill the rules, examine them and then remove the ones that shouldn't be there.  you then enforce.  if you're doing stuff like updating or developing with git or otherwise, you've got a system which is way too dynamic for rbac and its going to get you into trouble.

specifically here you're hitting the issue with hard links.  upstream isn't going to budge on that for good reasons.

> 
> The default subject have no access to network, so I create a subject for
> /usr/bin/git with the network access, however after any git upgrade (namely,
> merge from portage temp to rootfs) because of the hardlink magic rbac no
> longer sees /usr/bin/git at all, until policy recreation done by reloading.

don't use rbac here.

> 
> With symlink that is resolved in VFS it will work.
Comment 8 Anthony Basile gentoo-dev 2015-07-06 22:17:23 UTC
(In reply to Mike Gilbert from comment #6)
> If I understand this correctly, any binary that has an RBAC policy applied
> to it could be affected by this behavior -- it would occur any time the
> inode for an existing file changes. it's not an issue that affects only git.
> 
> Perhaps a more appropriate solution would be some post-merge hook to reload
> the RBAC policy. This would really be a package manager (portage) feature,
> and not something to be implemented in individual ebuilds.

i don't see much of a point to this.  if you've ever used rbac, it can severely limit your system and you want that for the kind of security it provides.  when i ran rbac servers, i would update every 6 months or so. I just turn off rbac and tweaked the rules.
Comment 9 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-07 17:53:16 UTC
(In reply to Anthony Basile from comment #7)
> (In reply to Piotr Karbowski from comment #5)
> > (In reply to Anthony Basile from comment #4)
> > > (In reply to Piotr Karbowski from comment #2)
> > > > Hello,
> > > > 
> > > > For reference:
> > > > https://forums.grsecurity.net/viewtopic.
> > > > php?p=15181&sid=d387ff32fe0e55f83a3843905f65cc32#p15181
> > > > 
> > > > It's indeed limitation of grsecurity but does not seems like it will be
> > > > addressed at all. Since Gentoo officially supports Grsecurity I thought such
> > > > workaround would be acceptable.
> > > 
> > > This is not really not how rbac should be used.  Sorry but I can't recommend
> > > this patch for git.
> > 
> > Not how rbac should be used? Care to elaborate?
> 
> you use rbac on a mostly static system like a server that just does one
> thing.  you run rbac learning for about a week, distill the rules, examine
> them and then remove the ones that shouldn't be there.  you then enforce. 
> if you're doing stuff like updating or developing with git or otherwise,
> you've got a system which is way too dynamic for rbac and its going to get
> you into trouble.

You use rbac on systems where you want additional security. There's no such thing like static or dynamic system. Also, upgrading system in admin role is noting unusual, as this is what special admin role are for. The host that I face this issues is a server, headless. It does act like git server, where you push changes over ssh to there, which requires git on the remote end, which is broken after upgrade. This is nothing too dynamic here. 

Such arguments is like closing a bug report about heavy degradated performance with libsandbox(iirc) with argument like 'thinclient w/ 1GHz amd64 is too slow for gentoo' which also happend on this very bugzilla to me.

> specifically here you're hitting the issue with hard links.  upstream isn't
> going to budge on that for good reasons.

I never got answer to why it won't be fixed, so about what reason are you talking sir?

> > 
> > The default subject have no access to network, so I create a subject for
> > /usr/bin/git with the network access, however after any git upgrade (namely,
> > merge from portage temp to rootfs) because of the hardlink magic rbac no
> > longer sees /usr/bin/git at all, until policy recreation done by reloading.
> 
> don't use rbac here.

Something I would never expect to get from Gentoo Hardened crew.

Whatsoever, I can accept WON'T FIX, I can accept that effort to address this issue on is too great when compared to result and possible users that actually happens to hit this issue, but the overall resoning here is so wrong.

For the future reference and anyone who happen to google here, I will just write a post_src_install function for portage's bashrc that will break all files that have more than one hardlink. That should be package-indepandent solution without much effort.
Comment 10 Jason Zaman gentoo-dev 2015-07-07 19:40:59 UTC
(In reply to Piotr Karbowski from comment #9)
> (In reply to Anthony Basile from comment #7)
> > (In reply to Piotr Karbowski from comment #5)
> > > The default subject have no access to network, so I create a subject for
> > > /usr/bin/git with the network access, however after any git upgrade (namely,
> > > merge from portage temp to rootfs) because of the hardlink magic rbac no
> > > longer sees /usr/bin/git at all, until policy recreation done by reloading.
> > 
> > don't use rbac here.
> 
> Something I would never expect to get from Gentoo Hardened crew.
> 
> Whatsoever, I can accept WON'T FIX, I can accept that effort to address this
> issue on is too great when compared to result and possible users that
> actually happens to hit this issue, but the overall resoning here is so
> wrong.

SELinux, SMACK, AppArmor would all work for this. Hardlinks are a pretty standard part of Unix, if rbac doesnt support it that sounds more like a failing of rbac than a problem with hardlinks thats why its not being recommended.

Incidentally, is it a gitolite server? Wouldnt you have a policy on the main gitolite command than on git itself? I have gitolite on my server that is running SELinux and the policies are for gitolite and git-daemon not on git itself.
ie: /usr/bin/gl-auth-command instead of /usr/bin/git.
Comment 11 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-07 19:59:07 UTC
(In reply to Jason Zaman from comment #10)
> Incidentally, is it a gitolite server? Wouldnt you have a policy on the main
> gitolite command than on git itself? I have gitolite on my server that is
> running SELinux and the policies are for gitolite and git-daemon not on git
> itself.
> ie: /usr/bin/gl-auth-command instead of /usr/bin/git.

This affect both subjects as well as objects, as the default subject (/) have "/ h" i need to specify what can be executed, thus I need a rule with '/usr/bin/git x' to allow any subject actually use it. Right now with the merge of hardlinks I simply can't exec object /usr/bin/git, and I do need `git` binary when i check on the hooks on actually what is pushed.

Anyway, /etc/portage/bashrc:
post_src_install() {
    local hardlink sufix
    while read hardlink; do
        einfo "Breaking hardlink ${hardlink} ..."
        sufix="${RANDOM}"
        cp -a "${hardlink}" "${hardlink}._tmp_${sufix}" && mv -f "${hardlink}._tmp_${sufix}" "${hardlink}"
    done < <(find "$D" -type f -links +1)
}

Did the trick.
Comment 12 Mike Gilbert gentoo-dev 2015-07-07 20:56:14 UTC
Out of curiosity, I would really like a better explanation of why having multiple hard links to the same file breaks grsecurity rbac. The explanations thus far have been very short on details.

Applying any fix without fully understanding the problem is short-sighted.
Comment 13 Anthony Basile gentoo-dev 2015-07-07 21:43:59 UTC
(In reply to Mike Gilbert from comment #12)
> Out of curiosity, I would really like a better explanation of why having
> multiple hard links to the same file breaks grsecurity rbac. The
> explanations thus far have been very short on details.
> 
> Applying any fix without fully understanding the problem is short-sighted.

First, let's keep in mind that this is not exclusively a git issue.  So if you read the forum post in comment #2, you see that piotr has this issue with perl as well.  So for that reason alone, this bug is WONTIX because it really doesn't deal with the bigger issue.

Brad pretty much says it in his second post: rbac only allows a 1:1 mapping between objects and filenames so you can't replace objects with hardlinks.  I like this feature of rbac precisely because it doesn't allow what piotr wants.
Comment 14 Mike Gilbert gentoo-dev 2015-07-07 22:04:09 UTC
(In reply to Anthony Basile from comment #13)
> I like this feature of rbac precisely because it doesn't allow what piotr
> wants.

That just seems weird. The point of the policy would be to limit who can use the git command with network access. It seems like it shouldn't break in a strange way just because the git command has been replaced with a new version.

It is especially strange given that it reportedly works how Piotr wants if you install 113 copies of the same binary, rather than 113 links to the same binary.

As someone who doesn't use an RBAC at all, this really does not seem like a feature, but rather a limitation that nobody cares to address.
Comment 15 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-07 22:06:21 UTC
(In reply to Anthony Basile from comment #13)
> Brad pretty much says it in his second post: rbac only allows a 1:1 mapping
> between objects and filenames so you can't replace objects with hardlinks. 
> I like this feature of rbac precisely because it doesn't allow what piotr
> wants.

Its not a feature, but a limitation, and please stop making it sound like I do something special here or I want to make it do something special that RBAC is not meant to. RBAC's limitation is that it presume that inode have only one path and gets confused when you have more paths pointing to single inode. Meaning if I have such, totally sane RBAC rules:

role users g {
    subject / {
        / h
        $basic_env
        /usr/bin/git x

        -CAP_ALL
        bind disabled
        connect disabled
    }

    subject /usr/bin/git {
        connect 0.0.0.0/0 stream dgram ip
    }
}

And then I re-emerge git, I can no longer execute /usr/bin/git, as it acts like '/usr/bin/git x' was never added there, until I force policy recreation in-kernel, with gradm -R and providing RBAC password.

This is simple usecase, regular, nothing special, NOTHING. Every single rbac policy looks the same way like the one I posted here. Meaning with RBAC enabled I can't really switch to admin role and do system upgrade unless I hack around the hardlink issues.

-- Piotr.
Comment 16 Anthony Basile gentoo-dev 2015-07-07 22:37:49 UTC
(In reply to Mike Gilbert from comment #14)
> (In reply to Anthony Basile from comment #13)
> > I like this feature of rbac precisely because it doesn't allow what piotr
> > wants.
> 
> That just seems weird. The point of the policy would be to limit who can use
> the git command with network access. It seems like it shouldn't break in a
> strange way just because the git command has been replaced with a new
> version.

I *want* execution to be forbidden if the git exe is replaced *while* rbac is enforced.  I'm not sure what I'm not communicating here, but let me put it this way.  When I ran my rbac servers, emerge was totally forbidden and the modification of anything in /bin /sbin /usr/bin /usr/sbin was not allowed while rbac was enforced.  The only way I could update my system was to turn off rbac, emerge -uvNDq @world, and then turn it back on again (with possibly some tweaks to the rules if things had changed.)  I did this about once every 4-6 months.

> And then I re-emerge git, I can no longer execute /usr/bin/git, as it acts
> like '/usr/bin/git x' was never added there, until I force policy recreation
> in-kernel, with gradm -R and providing RBAC password.

Or, git is replaced by some malicious executable and then you'll be glad rbac works this way.  The operative point here is *until I force policy recreation*.  That's what I like about it.  When rbac was turned on, you gave permission to that particular git executable to run (or be an object) and not some future version that you haven't sanctioned by reloading the policy in the kernel.  And not only git, but *all* executables on the system.

I think I have a very different model of "best practices" with rbac than you do.  The mere fact that you can emerge while rbac is enforced suggests a use of rbac that I would not recommend.




> Its not a feature, but a limitation, and please stop making it sound like I
> do something special here or I want to make it do something special that
> RBAC is not meant to.

While I can understand your frustration with my position, I don't appreciate the tone.  It might behoove you to try to take the time to understand why I hold the opinion I do.  Alternatively, nothing is to stop you from convincing upstream.  You don't have to bother me.
Comment 17 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-07 22:50:58 UTC
(In reply to Anthony Basile from comment #16)
> (In reply to Mike Gilbert from comment #14)
> > (In reply to Anthony Basile from comment #13)
> > > I like this feature of rbac precisely because it doesn't allow what piotr
> > > wants.
> > 
> > That just seems weird. The point of the policy would be to limit who can use
> > the git command with network access. It seems like it shouldn't break in a
> > strange way just because the git command has been replaced with a new
> > version.
> 
> I *want* execution to be forbidden if the git exe is replaced *while* rbac
> is enforced.  I'm not sure what I'm not communicating here, but let me put
> it this way.  When I ran my rbac servers, emerge was totally forbidden and
> the modification of anything in /bin /sbin /usr/bin /usr/sbin was not
> allowed while rbac was enforced.  The only way I could update my system was
> to turn off rbac, emerge -uvNDq @world, and then turn it back on again (with
> possibly some tweaks to the rules if things had changed.)  I did this about
> once every 4-6 months.

The thing is, the access denied on replaced subjects happens only if the binary was hardlink and was replaced by another hardlink, thus it coudn't be considerd as a feature, because if I can replace binary, and do 'cp /tmp/evilBinary /usr/bin/git' you won't loose access to the (new) git.
 
> > And then I re-emerge git, I can no longer execute /usr/bin/git, as it acts
> > like '/usr/bin/git x' was never added there, until I force policy recreation
> > in-kernel, with gradm -R and providing RBAC password.
> 
> Or, git is replaced by some malicious executable and then you'll be glad
> rbac works this way.  The operative point here is *until I force policy
> recreation*.  That's what I like about it.  When rbac was turned on, you
> gave permission to that particular git executable to run (or be an object)
> and not some future version that you haven't sanctioned by reloading the
> policy in the kernel.  And not only git, but *all* executables on the system.
> 
> I think I have a very different model of "best practices" with rbac than you
> do.  The mere fact that you can emerge while rbac is enforced suggests a use
> of rbac that I would not recommend.

As per official Grsecurity Role Based Access Control, there's a special role, called admin, that can do admin things, with full access to system. I can't emerge with RBAC enabled, unless I switch to admin role, that require password, just like disabling RBAC require password. from usablity-point-of view there's no diffrent if you do

gradm -D # to disable rbac. needs password.
emerge --sync
emerge --NuDa @world
gradm -E

or if you do

gradm -a admin # needs password
emerge --sync
emerge -NuDa @world
gradm --unauth

The only diff here is that the first one take RBAC off for whole system, and the second one limits the 'god mode' to the current shell, meaning you can work like without RBAC, but everything outside this very shell is still restricted.

> > Its not a feature, but a limitation, and please stop making it sound like I
> > do something special here or I want to make it do something special that
> > RBAC is not meant to.
> 
> While I can understand your frustration with my position, I don't appreciate
> the tone.  It might behoove you to try to take the time to understand why I
> hold the opinion I do.  Alternatively, nothing is to stop you from
> convincing upstream.  You don't have to bother me.
Comment 18 Mike Gilbert gentoo-dev 2015-07-07 23:11:29 UTC
(In reply to Piotr Karbowski from comment #17)

Thanks, that last comment was quite helpful in my understanding.

To restate: You shouldn't need to completely disable RBAC to run emerge and install new software. Rather, you should just need to change your role to an admin role. That makes a lot more sense to me than shutting off the entire thing. It also seems a lot more "secure".

It also sounds like there is some code in RBAC that automatically detects changes to files with only one link on the filesystem. This code fails when multiple links are involved. That's not a security feature, but a bug/limitation.
Comment 19 Anthony Basile gentoo-dev 2015-07-07 23:48:58 UTC
(In reply to Piotr Karbowski from comment #17)

> gradm -a admin # needs password
> emerge --sync
> emerge -NuDa @world
> gradm --unauth
> 

One sec, you didn't do `gradm -R`  Does the hardlink issue go away if you do that before `gradm -u`?
Comment 20 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-07 23:55:41 UTC
Indeed. If I run gradm -R before unauthing, the policy is loaded in kernel, which force to resolve the in-policy paths of objects into inodes, so it does indeed fixes it, until next replace of multiple-link-inode-path. This is almost like expected behavior, but instead of picking up new inode for an specified, single object, it does do it for all of them, like starting from scretch.
Comment 21 Anthony Basile gentoo-dev 2015-07-08 00:11:41 UTC
(In reply to Piotr Karbowski from comment #20)
> Indeed. If I run gradm -R before unauthing, the policy is loaded in kernel,
> which force to resolve the in-policy paths of objects into inodes, so it
> does indeed fixes it, until next replace of multiple-link-inode-path. This
> is almost like expected behavior, but instead of picking up new inode for an
> specified, single object, it does do it for all of them, like starting from
> scretch.

I'm confused.  If you ran `gradm -R` after each time your emerged, would you ever hit this problem?  I'm having difficulties understanding your last sentence.  Perhaps some code that would demonstrate.
Comment 22 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-08 00:19:48 UTC
(In reply to Anthony Basile from comment #21)
> (In reply to Piotr Karbowski from comment #20)
> > Indeed. If I run gradm -R before unauthing, the policy is loaded in kernel,
> > which force to resolve the in-policy paths of objects into inodes, so it
> > does indeed fixes it, until next replace of multiple-link-inode-path. This
> > is almost like expected behavior, but instead of picking up new inode for an
> > specified, single object, it does do it for all of them, like starting from
> > scretch.
> 
> I'm confused.  If you ran `gradm -R` after each time your emerged, would you
> ever hit this problem?  I'm having difficulties understanding your last
> sentence.  Perhaps some code that would demonstrate.

Kind of. Race condition prone and hardly scriptable because reload requires password. Even reloading every package would leave you with a time slot when the objects aren't accessable because in the nut shell, the problem is that the path of in-kernel policy does not match what's really on filesystem because the code to pick up new inode does not runs when there are multiple links, it seems.

Less troubesome is code to break hardlinks into independent inodes, even if git now uses over 200 MB, it still does not leave me with borked system.
Comment 23 Piotr Karbowski (RETIRED) gentoo-dev 2015-07-08 00:25:05 UTC
To make it a bit less confusing.

Once policy is created in-kernel, the kernel tracks the changes (which fails a bit, when there are multiple hardlinks). Upon enabling RBAC as well as when reloading, there's a policy (re)creation in kernel, which probe all the objects to track later, thus if there as any change on filesystem that in-kernel tracker did not saw, it does not matter anymore as the new inode-to-object-path mapping has been created.