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

RFC: drop dependency on libapparmor and reimplement aa_change_exec in Go #1674

Closed
tklauser opened this issue Dec 11, 2017 · 1 comment
Closed

Comments

@tklauser
Copy link
Contributor

libapparmor is integrated in libcontainer using cgo but is only used to call a single function: aa_change_onexec in https://github.com/opencontainers/runc/blob/master/libcontainer/apparmor/apparmor.go#L35.

The dependency on libapparmor requires additional packages to be installed for runc/libcontainer to be built and run, which might cause confusion for some users (e.g see #1486).

Looking at aa_change_onexec in libapparmor it seems like is simple enough (writing a string to a file in /proc//attr/...) to be re-implemented locally in libcontainer in plain Go.

I have an untested PR ready locally which I can submit if people think this is a worthwhile thing to do. In the meantime I'll try to figure out how to test this properly (i.e. getting runc to run with an apparmor profile).

@tklauser
Copy link
Contributor Author

FWIW, here's the implementation from libapparmor (libraries/libapparmor/src/kernel.c):

static int setprocattr(pid_t tid, const char *attr, const char *buf, int len)
{
        int rc = -1;
        int fd, ret;
        char *ctl = NULL;

        if (!buf) {
                errno = EINVAL;
                goto out;
        }

        ctl = procattr_path(tid, attr);
        if (!ctl)
                goto out;

        fd = open(ctl, O_WRONLY);
        if (fd == -1) {
                goto out;
        }

        ret = write(fd, buf, len);
        if (ret != len) {
                int saved;
                if (ret != -1) {
                        errno = EPROTO;
                }
                saved = errno;
                (void)close(fd);
                errno = saved;
                goto out;
        }

        rc = 0;
        (void)close(fd);

out:
        if (ctl) {
                free(ctl);
        }
        return rc;
}

int aa_change_onexec(const char *profile)
{                                                                                                                                                                                    
        char *buf = NULL;                                                                                                                                                            
        int len;
        int rc;
                                                                                                                                                                                     
        if (!profile) {                                                                                                                                                              
                errno = EINVAL;                                                                                                                                                      
                return -1;                                                                                                                                                           
        }                                                                                                                                                                            
                                                                                                                                                                                     
        len = asprintf(&buf, "exec %s", profile);                                                                                                                                    
        if (len < 0)                                                                                                                                                                 
                return -1;                                                                                                                                                           
                                                                                                                                                                                     
        rc = setprocattr(aa_gettid(), "exec", buf, len);                                                                                                                             
        
        free(buf);
        return rc;                                                                                                                                                                   
}

kolyshkin pushed a commit to kolyshkin/runc that referenced this issue Sep 5, 2019
libapparmor is integrated in libcontainer using cgo but is only used to
call a single function: aa_change_onexec. It turns out this function is
simple enough (writing a string to a file in /proc/<n>/attr/...) to be
re-implemented locally in libcontainer in plain Go.

This allows to drop the dependency on libapparmor and the corresponding
cgo integration.

Fixes opencontainers#1674

Signed-off-by: Tobias Klauser <[email protected]>
(cherry picked from commit db093f6)
Signed-off-by: Kir Kolyshkin <[email protected]>

Conflicts:
- minor conflict in .travis.yml due to missing go get lines
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

1 participant