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

Hide a file in folder by filtering lookup. #8

Open
Arbaks opened this issue Jan 19, 2019 · 4 comments
Open

Hide a file in folder by filtering lookup. #8

Arbaks opened this issue Jan 19, 2019 · 4 comments

Comments

@Arbaks
Copy link

Arbaks commented Jan 19, 2019

Здравствуйте, Слава. Мы два студента, пытающиеся выполнить лабораторную по драйверам в Маке. Поскольку в сети, к сожалению, почти нет информации по программированию в ядре для Мака, то ваш проект стал очень полезным подспорьем. Тем не менее, перед нами встала проблема, которую мы не можем решить.
Мы нигде не можем найти информацию о том, как сформировать новый vnode для того, чтобы скрыть какой-то конкретный файл.
Идея кардинально проста. Хукаем lookup, вытаскиваем из vnod'a имя, проверяем его. Если имя не то, то просто выдаем обратно тот же самый vnode, а вот как модифицировать vnode, чтобы в результате, например, того же ls'а на месте файла ничего не появлялось - непонятно.
Простите за такой банальный вопрос и, надеюсь, вы найдете время, чтобы нам помочь. Спасибо.

@slavaim
Copy link
Owner

slavaim commented Jan 20, 2019

Чтобы скрыть файл надо убрать его описание из данных возвращенных следующими операциями
vnop_reddir_desc (вызывается VNOP_READDIR)
vnop_reddir_desc (VNOP_READDIR)
vnop_getattrlistbulk_desc (VNOP_GETATTRLISTBULK)
эти функции возвращают массив с описанием данных для файлов в директории.

Фильтруя только lookup убрать vnode из списка файлов в директории не всегда возможно. Lookup запрашивает vnode от файловой системы и обычно помещает его в кеш если это не запрещено (создают vnode вызовом vnode_create если он уже не существует - это задача файловой системы следить за тем какие vnode уже созданы и не создавать новых для этого имени а возвратить созданный). Убрать его фильтруя lookup можно только если импленетация vnop_readdir* в файловой системе вызывает lookup (это не делают обычно) или если приложение после readdir вызывает например stat() (но показать в спсике файлов его все равно смогут, например Midnight Commander покажет его красным как недоступный). Тем не менее вам надо запретить открывать vnode и я вам рекомендую вместо перехвата lookup который несколько затруднен из-за кеша vnode (нужно нетривиальную логику сделать для его обхода) в дополнение к перехвату тех трех функций что я описал добавить в свой фильтр KAUTH callback для KAUTH_SCOPE_VNODE вызовом kauth_listen_scope и в этом callback запрещать доступ к vnode который вы скрываете чтобы даже имея имя нельзя было открыть его несмотря на то что в списке директории он не показывается благодаря фильтрации readdir функции которую вы добавите.

Если вам интересно как в lookup в фильтрах создают vnode вам надо посмотреть сюда https://github.com/slavaim/MacOSX-VFS-Isolation-Filter/blob/master/FileSystem-Isolation/VifCoveringVnode.cpp#L202 . Но этот путь как я указал требует обхода кеша vnode иначе иногда ваш хук не будет вызываться так как vnode был помещен в кеш до того как стартовал ваш фильтр. Это можно обойти но это уже слишком много для лабораторной. Вам достаточно KAUTH колбека.

Ну и конечно вам надо в lookup скорее возвращать ошибку EPERM например убрав предварительно референс с возвращенного vnode - vnode_put(*ap->a_vpp) и поставив ее в ноль *ap->a_vpp = NULLVP; . Но того же и даже лучше вы добьетесь вернув ошибку в KAUTH callback , дереференсить vnode при этом не надо.

@Arbaks
Copy link
Author

Arbaks commented Jan 20, 2019

Спасибо большое за помощь. Можно небольшое уточнение?
То есть, например, если мы можем поместить скрываемый файл в отдельную папку и вернуть результатом этих трех вышеописанных функций для этой папки - NULL, то результатом ls в ней будет пустая папка, так?
И можно еще одно уточнение: если мы считаем, что информации об этих файлах в кэше нет, то куда должна подаваться информация на выход о них в лукапе?

@slavaim
Copy link
Owner

slavaim commented Jan 20, 2019

NULL возвращать не надо. Даже у пустой директории возвращаются две записи
'.'
'..'
которые вначале массива возвращенного. Чтобы лучше понять посмотрите код файловой системы FAT, там простой код в отличие от HFS, - функция msdosfs_vnop_read в https://opensource.apple.com/source/msdosfs/msdosfs-229.200.3/msdosfs.kextproj/msdosfs.kmodproj/msdosfs_vnops.c

Про lookup я не понял вопрос. Lookup возвращает vnode . Возвращать его или вместо него ошибку - зависит от того что вы хотите. Если вернули vnode то он есть для системы и надо тогда запрещать в KAUTH callback доступ иначе файл будет доступен по полному имени несмотря даже на отсуствие его в списке readdir. Этим будет запрещен доступ к файлу для всех юзермод приложений и большей части кернел мод кода. Как я сказал - вам lookup вобще не нужен, достаточно в KAUTH callback вернуть ошибку и тем самым запретить возврат vnode . Если уж вам очень хочется в lookup все сделать то надо возвращать не vnode а NULL в ap->a_vpp и ошибку из lookup.

@slavaim
Copy link
Owner

slavaim commented Jan 20, 2019

Если у вас задача иметь доступ к файлу но не показывать его в списке файлов директории то вам вобще не надо ничего делать с lookup - она вернет vnode любому у кого есть имя файла.

Если надо фильтровать доступ к этому "секретному" файлу по какому то признаку то фильтруйте в KAUTH callback - делать это в lookup можно но неудобно.

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

2 participants