Tak, można należeć do kilku grup, sprawdza wszystkie sprawdzając uprawnienia - tj. jeżeli plik ma jako właściciela grupę C, a ty jesteś w grupie A (podstawowej), B oraz C, to ciebie obowiązują uprawnienia grupy C.
Czyli tak jak sądziłem, w anglojęzycznej części internetu również twierdzą to co ty @Ktos.
Przez ten czas, kiedy nie pisałem próbowałem zlokalizować część jądra - kod - żeby upewnić się co do tych grup i chyba mi się udało.
Nie jestem pewien tego co napisze poniżej, niekoniecznie musi to być prawda, mogłem przeoczyć jakiś opis,szczegół albo coś źle zrozumieć.
https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/security/keys/permission.c#L30
Znajdujemy tu funkcję odpowiedzialna za sprawdzenie uprawnień.
///Check to see whether permission is granted to use a key in the desired way,but permit the security modules to override.
int key_task_permission(const key_ref_t key_ref, const struct cred *cred,unsigned perm)
Podaje się jej jako argumenty kolejno :
- Referencje do klucza - niestety nie wiem co ten klucz przechowuje, został on zdefiniowany w ten sposób.
typedef struct __key_reference_with_attributes *key_ref_t;
w pliku https://github.com/torvalds/linux/blob/07b75260ebc2c789724c594d7eaf0194fa47b3be/include/linux/key.h#L111
Można o nim w tym pliku przeczytać:
key reference with possession attribute handling
NOTE! key_ref_t is a typedef'd pointer to a type that is not actuallydefined.
- Drugim argumentem jest struktura zawierająca poświadczenia
- Trzecim argumentem jest liczba całkowita, zawiera ona uprawnienia do sprawdzenia.
Jeżeli chodzi o ciało funkcji interesuje nas linijka:
ret = groups_search(cred->group_info, key->gid);
Ciało funkcji znajduje się w pliku https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/kernel/groups.c#L133
Kiedy funkcja
int groups_search(const struct group_info *group_info, kgid_t grp)
zwróci prawdę przechodzimy do dalszej części weryfikacji uprawnień poprzez skok goto use_these_perms;
Z tego co się zorientowałem i udało mi się zrozumieć to właśnie ta funkcja sprawdza listę grup do których należy użytkownik.
Wkleję tu jej kod:
```c
/* a simple bsearch */
int groups_search(const struct group_info *group_info, kgid_t grp)
{
unsigned int left, right;
if (!group_info)
return 0;
left = 0;
right = group_info->ngroups;
while (left < right) {
unsigned int mid = (left+right)/2;
if (gid_gt(grp, GROUP_AT(group_info, mid)))
left = mid + 1;
else if (gid_lt(grp, GROUP_AT(group_info, mid)))
right = mid;
else
return 1;
}
return 0;
}
==========
Czy powinno się używać instrukcji goto i to w kodzie jądra - użycie jej w nadmiernych ilościach powoduje zaciemnienie kodu.
Proszę również żeby ktoś wyjaśnił co znaczą te dwa zapisy - zwyczajnie ich nie rozumiem, nie umiem ich nawet odczytać:
(@mlyszczek - wybacz że ci zawracam głowę ale pisałeś że zajmujesz/zajmowałeś się niskopoziomowymi rzeczami.)
a) https://github.com/torvalds/linux/blob/c05c2ec96bb8b7310da1055c7b9d786a3ec6dc0c/include/linux/cred.h#L92
#define GROUP_AT(gi, i) \
((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
Zadaje sobie sprawę że tu chodzi o makro (funkcyjne?? - bo wywołuje się je jak funkcję) ale nie wiem co oznacza ten zapis.
b)https://github.com/torvalds/linux/blob/07b75260ebc2c789724c594d7eaf0194fa47b3be/include/linux/key.h#L119
static inline struct key *key_ref_to_ptr(const key_ref_t key_ref)
{
return (struct key *) ((unsigned long) key_ref & ~1UL);
}
Funkcja ta oczywiście zwraca wskaźnik a przyjmuje referencje a w komentarzu powyżej znajdujemy informacje
* the three functions are used to assemble and disassemble references
Jednak również tutaj nie rozumiem zapisu - patrz ciało funkcji.